3v324v23 commited on
Commit
8216643
·
1 Parent(s): 34fdee6

Auto-deploy from GitHub

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. app.py +2 -226
  2. space/app.py +2 -226
  3. space/space/app.py +2 -226
  4. space/space/space/app.py +2 -226
  5. space/space/space/space/app.py +2 -226
  6. space/space/space/space/space/app.py +2 -226
  7. space/space/space/space/space/space/app.py +2 -226
  8. space/space/space/space/space/space/space/app.py +2 -226
  9. space/space/space/space/space/space/space/space/app.py +2 -226
  10. space/space/space/space/space/space/space/space/space/app.py +2 -226
  11. space/space/space/space/space/space/space/space/space/space/app.py +2 -226
  12. space/space/space/space/space/space/space/space/space/space/space/app.py +2 -226
  13. space/space/space/space/space/space/space/space/space/space/space/space/app.py +2 -226
  14. space/space/space/space/space/space/space/space/space/space/space/space/space/app.py +2 -226
  15. space/space/space/space/space/space/space/space/space/space/space/space/space/space/app.py +2 -226
  16. space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/app.py +2 -226
  17. space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/app.py +2 -226
  18. space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/app.py +2 -226
  19. space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/app.py +2 -226
  20. space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/app.py +2 -226
  21. space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/app.py +2 -226
  22. space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/app.py +2 -226
  23. space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/app.py +2 -226
  24. space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/app.py +2 -226
  25. space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/app.py +2 -226
  26. space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/app.py +2 -226
  27. space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/app.py +2 -226
  28. space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/app.py +2 -226
  29. space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/app.py +2 -226
  30. space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/app.py +2 -226
  31. space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/app.py +2 -226
  32. space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/app.py +2 -226
  33. space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/app.py +2 -226
  34. space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/jfk_text/104-10003-10041.md +47 -0
  35. space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/jfk_text/104-10004-10143 (C06932208).md +147 -0
  36. space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/jfk_text/104-10004-10143.md +68 -0
  37. space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/jfk_text/104-10004-10156.md +55 -0
  38. space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/jfk_text/104-10004-10213.md +206 -0
  39. space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/jfk_text/104-10005-10321.md +82 -0
  40. space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/jfk_text/104-10006-10247.md +145 -0
  41. space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/jfk_text/104-10007-10345.md +326 -0
  42. space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/jfk_text/104-10009-10021.md +192 -0
  43. space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/jfk_text/104-10009-10222.md +72 -0
  44. space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/jfk_text/104-10012-10022.md +102 -0
  45. space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/jfk_text/104-10012-10024.md +29 -0
  46. space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/jfk_text/104-10012-10035.md +208 -0
  47. space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/jfk_text/104-10012-10076.md +180 -0
  48. space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/jfk_text/104-10012-10078.md +199 -0
  49. space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/jfk_text/104-10012-10079.md +61 -0
  50. space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/jfk_text/104-10014-10051.md +56 -0
app.py CHANGED
@@ -6,8 +6,6 @@ from entity_recognition import extract_entities
6
  from wordcloud import WordCloud
7
  from summarization import summarizer
8
  from utils import list_files, process_file
9
- import pygraphviz as pgv
10
- import os
11
 
12
  # Initialize FastAPI
13
  app = FastAPI()
@@ -16,175 +14,6 @@ app = FastAPI()
16
  class TextRequest(BaseModel):
17
  text: str
18
 
19
- def wrap_label(label, max_length=15):
20
- """Improved label wrapping with hyphenation awareness"""
21
- if len(label) <= max_length:
22
- return label
23
-
24
- # Try to break at natural points
25
- break_chars = [" ", "-", "_", "/"]
26
- lines = []
27
- current = ""
28
-
29
- for char in label:
30
- if len(current) >= max_length and char in break_chars:
31
- lines.append(current.strip())
32
- current = char
33
- else:
34
- current += char
35
-
36
- if current:
37
- lines.append(current.strip())
38
-
39
- return "\\n".join(lines)
40
- def generate_high_res_mindmap(text):
41
- """Generate high-quality mind map with improved visibility"""
42
- try:
43
- # Verify we have entities to visualize
44
- entities = extract_entities(text)
45
- if not any(entities.values()):
46
- print("No entities found to generate mind map")
47
- return None
48
-
49
- # Create temporary directory
50
- temp_dir = "/tmp/mindmaps"
51
- os.makedirs(temp_dir, exist_ok=True)
52
- output_path = os.path.join(temp_dir, "mindmap.png")
53
-
54
- # Create graph with optimized settings
55
- G = pgv.AGraph(
56
- directed=True,
57
- rankdir="TB", # Top-to-bottom layout
58
- bgcolor="white",
59
- fontname="Arial", # More readable font
60
- splines="ortho", # Straight lines
61
- overlap="false",
62
- concentrate="true",
63
- ratio="compress",
64
- size="50,50", # Larger canvas
65
- dpi="1000", # Higher resolution
66
- pad="1.0",
67
- nodesep="1.2", # More space between nodes
68
- ranksep="1.5" # More vertical space
69
- )
70
-
71
- # Enhanced node styling for better visibility
72
- G.node_attr.update({
73
- "fontsize": "24", # Larger font
74
- "fontname": "Arial Bold",
75
- "shape": "box",
76
- "style": "rounded,filled",
77
- "fillcolor": "#E1F5FE",
78
- "color": "#0288D1",
79
- "height": "0.8",
80
- "width": "2.0",
81
- "penwidth": "2.0",
82
- "margin": "0.3,0.1" # Better text padding
83
- })
84
-
85
- # Enhanced edge styling
86
- G.edge_attr.update({
87
- "color": "#616161",
88
- "penwidth": "2.5",
89
- "arrowsize": "1.2",
90
- "fontname": "Arial",
91
- "fontsize": "20",
92
- "fontcolor": "#424242"
93
- })
94
-
95
- # Add central node with improved styling
96
- G.add_node("DOCUMENT",
97
- shape="doubleoctagon",
98
- fillcolor="#4FC3F7",
99
- fontsize="28",
100
- width="2.5",
101
- height="1.0",
102
- penwidth="3.0")
103
-
104
- # Add entities with better spacing
105
- max_categories = 5
106
- max_entities = 8
107
-
108
- for cat_idx, (category, values) in enumerate(entities.items()):
109
- if cat_idx >= max_categories:
110
- break
111
-
112
- # Main category node
113
- cat_node = f"CAT_{cat_idx}"
114
- G.add_node(cat_node,
115
- label=wrap_label(category, 18),
116
- shape="tab",
117
- fillcolor="#81D4FA",
118
- fontsize="22")
119
-
120
- G.add_edge("DOCUMENT", cat_node,
121
- label="contains",
122
- penwidth="3.0")
123
-
124
- # Add entities with grouping if needed
125
- if len(values) > max_entities:
126
- # Create subcategory groups
127
- for sub_idx, group in enumerate([values[i:i+max_entities]
128
- for i in range(0, len(values), max_entities)]):
129
- sub_node = f"SUB_{cat_idx}_{sub_idx}"
130
- G.add_node(sub_node,
131
- label=f"Group {sub_idx+1}",
132
- shape="folder",
133
- fillcolor="#B3E5FC")
134
- G.add_edge(cat_node, sub_node)
135
-
136
- for ent_idx, value in enumerate(group):
137
- ent_node = f"ENT_{cat_idx}_{sub_idx}_{ent_idx}"
138
- G.add_node(ent_node,
139
- label=wrap_label(value, 15),
140
- shape="note",
141
- fillcolor="#E1F5FE")
142
- G.add_edge(sub_node, ent_node)
143
- else:
144
- # Directly add entities
145
- for ent_idx, value in enumerate(values[:max_entities]):
146
- ent_node = f"ENT_{cat_idx}_{ent_idx}"
147
- G.add_node(ent_node,
148
- label=wrap_label(value, 15),
149
- shape="note",
150
- fillcolor="#E1F5FE")
151
- G.add_edge(cat_node, ent_node)
152
-
153
- # Generate output with multiple attempts
154
- for engine in ['dot', 'neato', 'sfdp']:
155
- try:
156
- G.draw(output_path,
157
- format="png",
158
- prog=engine,
159
- args=f"-Gdpi=300 -Gsize=50,50 -Goverlap=prism")
160
- print(f"Successfully generated with {engine}")
161
-
162
- # Verify the output
163
- if os.path.exists(output_path) and os.path.getsize(output_path) > 0:
164
- return output_path
165
-
166
- except Exception as e:
167
- print(f"Layout engine {engine} failed: {str(e)}")
168
- continue
169
-
170
- raise RuntimeError("All layout engines failed")
171
-
172
- except Exception as e:
173
- print(f"Mind map generation failed: {str(e)}")
174
- # Create error visualization
175
- try:
176
- import matplotlib.pyplot as plt
177
- plt.figure(figsize=(20, 10))
178
- plt.text(0.5, 0.5,
179
- f"Mind Map Generation Failed\n{str(e)}\n\nOriginal Text:\n{text[:200]}...",
180
- ha='center', va='center', wrap=True)
181
- plt.axis('off')
182
- error_path = os.path.join(temp_dir, "error_mindmap.png")
183
- plt.savefig(error_path, bbox_inches='tight', dpi=300)
184
- plt.close()
185
- return error_path
186
- except:
187
- return None
188
  @app.post("/summarize")
189
  def summarize_text(request: TextRequest):
190
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
@@ -223,16 +52,7 @@ def generate_word_cloud(request: TextRequest):
223
 
224
  # Gradio UI
225
  with gr.Blocks(theme=gr.themes.Soft(), css="""
226
- .mindmap-container img {
227
- max-height: none !important;
228
- min-width: 100% !important;
229
- object-fit: contain !important;
230
- background: white !important;
231
- border: 1px solid #e0e0e0 !important;
232
- border-radius: 8px !important;
233
- padding: 20px !important;
234
- }
235
- .gradio-container { max-width: 1400px !important; }
236
  """) as iface:
237
 
238
  gr.Markdown("# JFK Document Analysis Suite")
@@ -272,20 +92,7 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
272
  width=600
273
  )
274
 
275
- # Mind map section
276
- with gr.Row():
277
- mindmap_btn = gr.Button(
278
- "Generate Enhanced Mind Map",
279
- variant="primary"
280
- )
281
-
282
- with gr.Row():
283
- output_mindmap = gr.Image(
284
- label="High-Resolution Mind Map",
285
- elem_classes="mindmap-container",
286
- height=800,
287
- width=800
288
- )
289
 
290
  # Event handlers must be inside the Blocks context
291
  process_btn.click(
@@ -294,37 +101,6 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
294
  outputs=[full_doc_text, output_summary, output_entities, output_wordcloud]
295
  )
296
 
297
- def display_mindmap(text):
298
- try:
299
- img_path = generate_high_res_mindmap(text)
300
- if img_path and os.path.exists(img_path):
301
- return img_path
302
- return None
303
- except Exception as e:
304
- print(f"Display error: {e}")
305
- return None
306
-
307
- mindmap_btn.click(
308
- fn=display_mindmap,
309
- inputs=full_doc_text,
310
- outputs=output_mindmap,
311
- api_name="generate_mindmap",
312
- show_progress=True
313
- )
314
-
315
- # Add CSS for better image display
316
- css = """
317
- .mindmap-container img {
318
- max-width: 100% !important;
319
- height: auto !important;
320
- background: white !important;
321
- border: 2px solid #e0e0e0 !important;
322
- border-radius: 8px !important;
323
- padding: 10px !important;
324
- margin: 10px auto !important;
325
- display: block !important;
326
- }
327
- """
328
 
329
  if __name__ == "__main__":
330
  iface.launch(
 
6
  from wordcloud import WordCloud
7
  from summarization import summarizer
8
  from utils import list_files, process_file
 
 
9
 
10
  # Initialize FastAPI
11
  app = FastAPI()
 
14
  class TextRequest(BaseModel):
15
  text: str
16
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
  @app.post("/summarize")
18
  def summarize_text(request: TextRequest):
19
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
 
52
 
53
  # Gradio UI
54
  with gr.Blocks(theme=gr.themes.Soft(), css="""
55
+
 
 
 
 
 
 
 
 
 
56
  """) as iface:
57
 
58
  gr.Markdown("# JFK Document Analysis Suite")
 
92
  width=600
93
  )
94
 
95
+
 
 
 
 
 
 
 
 
 
 
 
 
 
96
 
97
  # Event handlers must be inside the Blocks context
98
  process_btn.click(
 
101
  outputs=[full_doc_text, output_summary, output_entities, output_wordcloud]
102
  )
103
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
104
 
105
  if __name__ == "__main__":
106
  iface.launch(
space/app.py CHANGED
@@ -6,8 +6,6 @@ from entity_recognition import extract_entities
6
  from wordcloud import WordCloud
7
  from summarization import summarizer
8
  from utils import list_files, process_file
9
- import pygraphviz as pgv
10
- import os
11
 
12
  # Initialize FastAPI
13
  app = FastAPI()
@@ -16,175 +14,6 @@ app = FastAPI()
16
  class TextRequest(BaseModel):
17
  text: str
18
 
19
- def wrap_label(label, max_length=15):
20
- """Improved label wrapping with hyphenation awareness"""
21
- if len(label) <= max_length:
22
- return label
23
-
24
- # Try to break at natural points
25
- break_chars = [" ", "-", "_", "/"]
26
- lines = []
27
- current = ""
28
-
29
- for char in label:
30
- if len(current) >= max_length and char in break_chars:
31
- lines.append(current.strip())
32
- current = char
33
- else:
34
- current += char
35
-
36
- if current:
37
- lines.append(current.strip())
38
-
39
- return "\\n".join(lines)
40
- def generate_high_res_mindmap(text):
41
- """Generate high-quality mind map with improved visibility"""
42
- try:
43
- # Verify we have entities to visualize
44
- entities = extract_entities(text)
45
- if not any(entities.values()):
46
- print("No entities found to generate mind map")
47
- return None
48
-
49
- # Create temporary directory
50
- temp_dir = "/tmp/mindmaps"
51
- os.makedirs(temp_dir, exist_ok=True)
52
- output_path = os.path.join(temp_dir, "mindmap.png")
53
-
54
- # Create graph with optimized settings
55
- G = pgv.AGraph(
56
- directed=True,
57
- rankdir="TB", # Top-to-bottom layout
58
- bgcolor="white",
59
- fontname="Arial", # More readable font
60
- splines="ortho", # Straight lines
61
- overlap="false",
62
- concentrate="true",
63
- ratio="compress",
64
- size="50,50", # Larger canvas
65
- dpi="1000", # Higher resolution
66
- pad="1.0",
67
- nodesep="1.2", # More space between nodes
68
- ranksep="1.5" # More vertical space
69
- )
70
-
71
- # Enhanced node styling for better visibility
72
- G.node_attr.update({
73
- "fontsize": "24", # Larger font
74
- "fontname": "Arial Bold",
75
- "shape": "box",
76
- "style": "rounded,filled",
77
- "fillcolor": "#E1F5FE",
78
- "color": "#0288D1",
79
- "height": "0.8",
80
- "width": "2.0",
81
- "penwidth": "2.0",
82
- "margin": "0.3,0.1" # Better text padding
83
- })
84
-
85
- # Enhanced edge styling
86
- G.edge_attr.update({
87
- "color": "#616161",
88
- "penwidth": "2.5",
89
- "arrowsize": "1.2",
90
- "fontname": "Arial",
91
- "fontsize": "20",
92
- "fontcolor": "#424242"
93
- })
94
-
95
- # Add central node with improved styling
96
- G.add_node("DOCUMENT",
97
- shape="doubleoctagon",
98
- fillcolor="#4FC3F7",
99
- fontsize="28",
100
- width="2.5",
101
- height="1.0",
102
- penwidth="3.0")
103
-
104
- # Add entities with better spacing
105
- max_categories = 5
106
- max_entities = 8
107
-
108
- for cat_idx, (category, values) in enumerate(entities.items()):
109
- if cat_idx >= max_categories:
110
- break
111
-
112
- # Main category node
113
- cat_node = f"CAT_{cat_idx}"
114
- G.add_node(cat_node,
115
- label=wrap_label(category, 18),
116
- shape="tab",
117
- fillcolor="#81D4FA",
118
- fontsize="22")
119
-
120
- G.add_edge("DOCUMENT", cat_node,
121
- label="contains",
122
- penwidth="3.0")
123
-
124
- # Add entities with grouping if needed
125
- if len(values) > max_entities:
126
- # Create subcategory groups
127
- for sub_idx, group in enumerate([values[i:i+max_entities]
128
- for i in range(0, len(values), max_entities)]):
129
- sub_node = f"SUB_{cat_idx}_{sub_idx}"
130
- G.add_node(sub_node,
131
- label=f"Group {sub_idx+1}",
132
- shape="folder",
133
- fillcolor="#B3E5FC")
134
- G.add_edge(cat_node, sub_node)
135
-
136
- for ent_idx, value in enumerate(group):
137
- ent_node = f"ENT_{cat_idx}_{sub_idx}_{ent_idx}"
138
- G.add_node(ent_node,
139
- label=wrap_label(value, 15),
140
- shape="note",
141
- fillcolor="#E1F5FE")
142
- G.add_edge(sub_node, ent_node)
143
- else:
144
- # Directly add entities
145
- for ent_idx, value in enumerate(values[:max_entities]):
146
- ent_node = f"ENT_{cat_idx}_{ent_idx}"
147
- G.add_node(ent_node,
148
- label=wrap_label(value, 15),
149
- shape="note",
150
- fillcolor="#E1F5FE")
151
- G.add_edge(cat_node, ent_node)
152
-
153
- # Generate output with multiple attempts
154
- for engine in ['dot', 'neato', 'sfdp']:
155
- try:
156
- G.draw(output_path,
157
- format="png",
158
- prog=engine,
159
- args=f"-Gdpi=300 -Gsize=50,50 -Goverlap=prism")
160
- print(f"Successfully generated with {engine}")
161
-
162
- # Verify the output
163
- if os.path.exists(output_path) and os.path.getsize(output_path) > 0:
164
- return output_path
165
-
166
- except Exception as e:
167
- print(f"Layout engine {engine} failed: {str(e)}")
168
- continue
169
-
170
- raise RuntimeError("All layout engines failed")
171
-
172
- except Exception as e:
173
- print(f"Mind map generation failed: {str(e)}")
174
- # Create error visualization
175
- try:
176
- import matplotlib.pyplot as plt
177
- plt.figure(figsize=(20, 10))
178
- plt.text(0.5, 0.5,
179
- f"Mind Map Generation Failed\n{str(e)}\n\nOriginal Text:\n{text[:200]}...",
180
- ha='center', va='center', wrap=True)
181
- plt.axis('off')
182
- error_path = os.path.join(temp_dir, "error_mindmap.png")
183
- plt.savefig(error_path, bbox_inches='tight', dpi=300)
184
- plt.close()
185
- return error_path
186
- except:
187
- return None
188
  @app.post("/summarize")
189
  def summarize_text(request: TextRequest):
190
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
@@ -223,16 +52,7 @@ def generate_word_cloud(request: TextRequest):
223
 
224
  # Gradio UI
225
  with gr.Blocks(theme=gr.themes.Soft(), css="""
226
- .mindmap-container img {
227
- max-height: none !important;
228
- min-width: 100% !important;
229
- object-fit: contain !important;
230
- background: white !important;
231
- border: 1px solid #e0e0e0 !important;
232
- border-radius: 8px !important;
233
- padding: 20px !important;
234
- }
235
- .gradio-container { max-width: 1400px !important; }
236
  """) as iface:
237
 
238
  gr.Markdown("# JFK Document Analysis Suite")
@@ -272,20 +92,7 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
272
  width=600
273
  )
274
 
275
- # Mind map section
276
- with gr.Row():
277
- mindmap_btn = gr.Button(
278
- "Generate Enhanced Mind Map",
279
- variant="primary"
280
- )
281
-
282
- with gr.Row():
283
- output_mindmap = gr.Image(
284
- label="High-Resolution Mind Map",
285
- elem_classes="mindmap-container",
286
- height=800,
287
- width=800
288
- )
289
 
290
  # Event handlers must be inside the Blocks context
291
  process_btn.click(
@@ -294,37 +101,6 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
294
  outputs=[full_doc_text, output_summary, output_entities, output_wordcloud]
295
  )
296
 
297
- def display_mindmap(text):
298
- try:
299
- img_path = generate_high_res_mindmap(text)
300
- if img_path and os.path.exists(img_path):
301
- return img_path
302
- return None
303
- except Exception as e:
304
- print(f"Display error: {e}")
305
- return None
306
-
307
- mindmap_btn.click(
308
- fn=display_mindmap,
309
- inputs=full_doc_text,
310
- outputs=output_mindmap,
311
- api_name="generate_mindmap",
312
- show_progress=True
313
- )
314
-
315
- # Add CSS for better image display
316
- css = """
317
- .mindmap-container img {
318
- max-width: 100% !important;
319
- height: auto !important;
320
- background: white !important;
321
- border: 2px solid #e0e0e0 !important;
322
- border-radius: 8px !important;
323
- padding: 10px !important;
324
- margin: 10px auto !important;
325
- display: block !important;
326
- }
327
- """
328
 
329
  if __name__ == "__main__":
330
  iface.launch(
 
6
  from wordcloud import WordCloud
7
  from summarization import summarizer
8
  from utils import list_files, process_file
 
 
9
 
10
  # Initialize FastAPI
11
  app = FastAPI()
 
14
  class TextRequest(BaseModel):
15
  text: str
16
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
  @app.post("/summarize")
18
  def summarize_text(request: TextRequest):
19
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
 
52
 
53
  # Gradio UI
54
  with gr.Blocks(theme=gr.themes.Soft(), css="""
55
+
 
 
 
 
 
 
 
 
 
56
  """) as iface:
57
 
58
  gr.Markdown("# JFK Document Analysis Suite")
 
92
  width=600
93
  )
94
 
95
+
 
 
 
 
 
 
 
 
 
 
 
 
 
96
 
97
  # Event handlers must be inside the Blocks context
98
  process_btn.click(
 
101
  outputs=[full_doc_text, output_summary, output_entities, output_wordcloud]
102
  )
103
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
104
 
105
  if __name__ == "__main__":
106
  iface.launch(
space/space/app.py CHANGED
@@ -6,8 +6,6 @@ from entity_recognition import extract_entities
6
  from wordcloud import WordCloud
7
  from summarization import summarizer
8
  from utils import list_files, process_file
9
- import pygraphviz as pgv
10
- import os
11
 
12
  # Initialize FastAPI
13
  app = FastAPI()
@@ -16,175 +14,6 @@ app = FastAPI()
16
  class TextRequest(BaseModel):
17
  text: str
18
 
19
- def wrap_label(label, max_length=15):
20
- """Improved label wrapping with hyphenation awareness"""
21
- if len(label) <= max_length:
22
- return label
23
-
24
- # Try to break at natural points
25
- break_chars = [" ", "-", "_", "/"]
26
- lines = []
27
- current = ""
28
-
29
- for char in label:
30
- if len(current) >= max_length and char in break_chars:
31
- lines.append(current.strip())
32
- current = char
33
- else:
34
- current += char
35
-
36
- if current:
37
- lines.append(current.strip())
38
-
39
- return "\\n".join(lines)
40
- def generate_high_res_mindmap(text):
41
- """Generate high-quality mind map with improved visibility"""
42
- try:
43
- # Verify we have entities to visualize
44
- entities = extract_entities(text)
45
- if not any(entities.values()):
46
- print("No entities found to generate mind map")
47
- return None
48
-
49
- # Create temporary directory
50
- temp_dir = "/tmp/mindmaps"
51
- os.makedirs(temp_dir, exist_ok=True)
52
- output_path = os.path.join(temp_dir, "mindmap.png")
53
-
54
- # Create graph with optimized settings
55
- G = pgv.AGraph(
56
- directed=True,
57
- rankdir="TB", # Top-to-bottom layout
58
- bgcolor="white",
59
- fontname="Arial", # More readable font
60
- splines="ortho", # Straight lines
61
- overlap="false",
62
- concentrate="true",
63
- ratio="compress",
64
- size="50,50", # Larger canvas
65
- dpi="1000", # Higher resolution
66
- pad="1.0",
67
- nodesep="1.2", # More space between nodes
68
- ranksep="1.5" # More vertical space
69
- )
70
-
71
- # Enhanced node styling for better visibility
72
- G.node_attr.update({
73
- "fontsize": "24", # Larger font
74
- "fontname": "Arial Bold",
75
- "shape": "box",
76
- "style": "rounded,filled",
77
- "fillcolor": "#E1F5FE",
78
- "color": "#0288D1",
79
- "height": "0.8",
80
- "width": "2.0",
81
- "penwidth": "2.0",
82
- "margin": "0.3,0.1" # Better text padding
83
- })
84
-
85
- # Enhanced edge styling
86
- G.edge_attr.update({
87
- "color": "#616161",
88
- "penwidth": "2.5",
89
- "arrowsize": "1.2",
90
- "fontname": "Arial",
91
- "fontsize": "20",
92
- "fontcolor": "#424242"
93
- })
94
-
95
- # Add central node with improved styling
96
- G.add_node("DOCUMENT",
97
- shape="doubleoctagon",
98
- fillcolor="#4FC3F7",
99
- fontsize="28",
100
- width="2.5",
101
- height="1.0",
102
- penwidth="3.0")
103
-
104
- # Add entities with better spacing
105
- max_categories = 5
106
- max_entities = 8
107
-
108
- for cat_idx, (category, values) in enumerate(entities.items()):
109
- if cat_idx >= max_categories:
110
- break
111
-
112
- # Main category node
113
- cat_node = f"CAT_{cat_idx}"
114
- G.add_node(cat_node,
115
- label=wrap_label(category, 18),
116
- shape="tab",
117
- fillcolor="#81D4FA",
118
- fontsize="22")
119
-
120
- G.add_edge("DOCUMENT", cat_node,
121
- label="contains",
122
- penwidth="3.0")
123
-
124
- # Add entities with grouping if needed
125
- if len(values) > max_entities:
126
- # Create subcategory groups
127
- for sub_idx, group in enumerate([values[i:i+max_entities]
128
- for i in range(0, len(values), max_entities)]):
129
- sub_node = f"SUB_{cat_idx}_{sub_idx}"
130
- G.add_node(sub_node,
131
- label=f"Group {sub_idx+1}",
132
- shape="folder",
133
- fillcolor="#B3E5FC")
134
- G.add_edge(cat_node, sub_node)
135
-
136
- for ent_idx, value in enumerate(group):
137
- ent_node = f"ENT_{cat_idx}_{sub_idx}_{ent_idx}"
138
- G.add_node(ent_node,
139
- label=wrap_label(value, 15),
140
- shape="note",
141
- fillcolor="#E1F5FE")
142
- G.add_edge(sub_node, ent_node)
143
- else:
144
- # Directly add entities
145
- for ent_idx, value in enumerate(values[:max_entities]):
146
- ent_node = f"ENT_{cat_idx}_{ent_idx}"
147
- G.add_node(ent_node,
148
- label=wrap_label(value, 15),
149
- shape="note",
150
- fillcolor="#E1F5FE")
151
- G.add_edge(cat_node, ent_node)
152
-
153
- # Generate output with multiple attempts
154
- for engine in ['dot', 'neato', 'sfdp']:
155
- try:
156
- G.draw(output_path,
157
- format="png",
158
- prog=engine,
159
- args=f"-Gdpi=300 -Gsize=50,50 -Goverlap=prism")
160
- print(f"Successfully generated with {engine}")
161
-
162
- # Verify the output
163
- if os.path.exists(output_path) and os.path.getsize(output_path) > 0:
164
- return output_path
165
-
166
- except Exception as e:
167
- print(f"Layout engine {engine} failed: {str(e)}")
168
- continue
169
-
170
- raise RuntimeError("All layout engines failed")
171
-
172
- except Exception as e:
173
- print(f"Mind map generation failed: {str(e)}")
174
- # Create error visualization
175
- try:
176
- import matplotlib.pyplot as plt
177
- plt.figure(figsize=(20, 10))
178
- plt.text(0.5, 0.5,
179
- f"Mind Map Generation Failed\n{str(e)}\n\nOriginal Text:\n{text[:200]}...",
180
- ha='center', va='center', wrap=True)
181
- plt.axis('off')
182
- error_path = os.path.join(temp_dir, "error_mindmap.png")
183
- plt.savefig(error_path, bbox_inches='tight', dpi=300)
184
- plt.close()
185
- return error_path
186
- except:
187
- return None
188
  @app.post("/summarize")
189
  def summarize_text(request: TextRequest):
190
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
@@ -223,16 +52,7 @@ def generate_word_cloud(request: TextRequest):
223
 
224
  # Gradio UI
225
  with gr.Blocks(theme=gr.themes.Soft(), css="""
226
- .mindmap-container img {
227
- max-height: none !important;
228
- min-width: 100% !important;
229
- object-fit: contain !important;
230
- background: white !important;
231
- border: 1px solid #e0e0e0 !important;
232
- border-radius: 8px !important;
233
- padding: 20px !important;
234
- }
235
- .gradio-container { max-width: 1400px !important; }
236
  """) as iface:
237
 
238
  gr.Markdown("# JFK Document Analysis Suite")
@@ -272,20 +92,7 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
272
  width=600
273
  )
274
 
275
- # Mind map section
276
- with gr.Row():
277
- mindmap_btn = gr.Button(
278
- "Generate Enhanced Mind Map",
279
- variant="primary"
280
- )
281
-
282
- with gr.Row():
283
- output_mindmap = gr.Image(
284
- label="High-Resolution Mind Map",
285
- elem_classes="mindmap-container",
286
- height=800,
287
- width=800
288
- )
289
 
290
  # Event handlers must be inside the Blocks context
291
  process_btn.click(
@@ -294,37 +101,6 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
294
  outputs=[full_doc_text, output_summary, output_entities, output_wordcloud]
295
  )
296
 
297
- def display_mindmap(text):
298
- try:
299
- img_path = generate_high_res_mindmap(text)
300
- if img_path and os.path.exists(img_path):
301
- return img_path
302
- return None
303
- except Exception as e:
304
- print(f"Display error: {e}")
305
- return None
306
-
307
- mindmap_btn.click(
308
- fn=display_mindmap,
309
- inputs=full_doc_text,
310
- outputs=output_mindmap,
311
- api_name="generate_mindmap",
312
- show_progress=True
313
- )
314
-
315
- # Add CSS for better image display
316
- css = """
317
- .mindmap-container img {
318
- max-width: 100% !important;
319
- height: auto !important;
320
- background: white !important;
321
- border: 2px solid #e0e0e0 !important;
322
- border-radius: 8px !important;
323
- padding: 10px !important;
324
- margin: 10px auto !important;
325
- display: block !important;
326
- }
327
- """
328
 
329
  if __name__ == "__main__":
330
  iface.launch(
 
6
  from wordcloud import WordCloud
7
  from summarization import summarizer
8
  from utils import list_files, process_file
 
 
9
 
10
  # Initialize FastAPI
11
  app = FastAPI()
 
14
  class TextRequest(BaseModel):
15
  text: str
16
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
  @app.post("/summarize")
18
  def summarize_text(request: TextRequest):
19
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
 
52
 
53
  # Gradio UI
54
  with gr.Blocks(theme=gr.themes.Soft(), css="""
55
+
 
 
 
 
 
 
 
 
 
56
  """) as iface:
57
 
58
  gr.Markdown("# JFK Document Analysis Suite")
 
92
  width=600
93
  )
94
 
95
+
 
 
 
 
 
 
 
 
 
 
 
 
 
96
 
97
  # Event handlers must be inside the Blocks context
98
  process_btn.click(
 
101
  outputs=[full_doc_text, output_summary, output_entities, output_wordcloud]
102
  )
103
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
104
 
105
  if __name__ == "__main__":
106
  iface.launch(
space/space/space/app.py CHANGED
@@ -6,8 +6,6 @@ from entity_recognition import extract_entities
6
  from wordcloud import WordCloud
7
  from summarization import summarizer
8
  from utils import list_files, process_file
9
- import pygraphviz as pgv
10
- import os
11
 
12
  # Initialize FastAPI
13
  app = FastAPI()
@@ -16,175 +14,6 @@ app = FastAPI()
16
  class TextRequest(BaseModel):
17
  text: str
18
 
19
- def wrap_label(label, max_length=15):
20
- """Improved label wrapping with hyphenation awareness"""
21
- if len(label) <= max_length:
22
- return label
23
-
24
- # Try to break at natural points
25
- break_chars = [" ", "-", "_", "/"]
26
- lines = []
27
- current = ""
28
-
29
- for char in label:
30
- if len(current) >= max_length and char in break_chars:
31
- lines.append(current.strip())
32
- current = char
33
- else:
34
- current += char
35
-
36
- if current:
37
- lines.append(current.strip())
38
-
39
- return "\\n".join(lines)
40
- def generate_high_res_mindmap(text):
41
- """Generate high-quality mind map with improved visibility"""
42
- try:
43
- # Verify we have entities to visualize
44
- entities = extract_entities(text)
45
- if not any(entities.values()):
46
- print("No entities found to generate mind map")
47
- return None
48
-
49
- # Create temporary directory
50
- temp_dir = "/tmp/mindmaps"
51
- os.makedirs(temp_dir, exist_ok=True)
52
- output_path = os.path.join(temp_dir, "mindmap.png")
53
-
54
- # Create graph with optimized settings
55
- G = pgv.AGraph(
56
- directed=True,
57
- rankdir="TB", # Top-to-bottom layout
58
- bgcolor="white",
59
- fontname="Arial", # More readable font
60
- splines="ortho", # Straight lines
61
- overlap="false",
62
- concentrate="true",
63
- ratio="compress",
64
- size="50,50", # Larger canvas
65
- dpi="1000", # Higher resolution
66
- pad="1.0",
67
- nodesep="1.2", # More space between nodes
68
- ranksep="1.5" # More vertical space
69
- )
70
-
71
- # Enhanced node styling for better visibility
72
- G.node_attr.update({
73
- "fontsize": "24", # Larger font
74
- "fontname": "Arial Bold",
75
- "shape": "box",
76
- "style": "rounded,filled",
77
- "fillcolor": "#E1F5FE",
78
- "color": "#0288D1",
79
- "height": "0.8",
80
- "width": "2.0",
81
- "penwidth": "2.0",
82
- "margin": "0.3,0.1" # Better text padding
83
- })
84
-
85
- # Enhanced edge styling
86
- G.edge_attr.update({
87
- "color": "#616161",
88
- "penwidth": "2.5",
89
- "arrowsize": "1.2",
90
- "fontname": "Arial",
91
- "fontsize": "20",
92
- "fontcolor": "#424242"
93
- })
94
-
95
- # Add central node with improved styling
96
- G.add_node("DOCUMENT",
97
- shape="doubleoctagon",
98
- fillcolor="#4FC3F7",
99
- fontsize="28",
100
- width="2.5",
101
- height="1.0",
102
- penwidth="3.0")
103
-
104
- # Add entities with better spacing
105
- max_categories = 5
106
- max_entities = 8
107
-
108
- for cat_idx, (category, values) in enumerate(entities.items()):
109
- if cat_idx >= max_categories:
110
- break
111
-
112
- # Main category node
113
- cat_node = f"CAT_{cat_idx}"
114
- G.add_node(cat_node,
115
- label=wrap_label(category, 18),
116
- shape="tab",
117
- fillcolor="#81D4FA",
118
- fontsize="22")
119
-
120
- G.add_edge("DOCUMENT", cat_node,
121
- label="contains",
122
- penwidth="3.0")
123
-
124
- # Add entities with grouping if needed
125
- if len(values) > max_entities:
126
- # Create subcategory groups
127
- for sub_idx, group in enumerate([values[i:i+max_entities]
128
- for i in range(0, len(values), max_entities)]):
129
- sub_node = f"SUB_{cat_idx}_{sub_idx}"
130
- G.add_node(sub_node,
131
- label=f"Group {sub_idx+1}",
132
- shape="folder",
133
- fillcolor="#B3E5FC")
134
- G.add_edge(cat_node, sub_node)
135
-
136
- for ent_idx, value in enumerate(group):
137
- ent_node = f"ENT_{cat_idx}_{sub_idx}_{ent_idx}"
138
- G.add_node(ent_node,
139
- label=wrap_label(value, 15),
140
- shape="note",
141
- fillcolor="#E1F5FE")
142
- G.add_edge(sub_node, ent_node)
143
- else:
144
- # Directly add entities
145
- for ent_idx, value in enumerate(values[:max_entities]):
146
- ent_node = f"ENT_{cat_idx}_{ent_idx}"
147
- G.add_node(ent_node,
148
- label=wrap_label(value, 15),
149
- shape="note",
150
- fillcolor="#E1F5FE")
151
- G.add_edge(cat_node, ent_node)
152
-
153
- # Generate output with multiple attempts
154
- for engine in ['dot', 'neato', 'sfdp']:
155
- try:
156
- G.draw(output_path,
157
- format="png",
158
- prog=engine,
159
- args=f"-Gdpi=300 -Gsize=50,50 -Goverlap=prism")
160
- print(f"Successfully generated with {engine}")
161
-
162
- # Verify the output
163
- if os.path.exists(output_path) and os.path.getsize(output_path) > 0:
164
- return output_path
165
-
166
- except Exception as e:
167
- print(f"Layout engine {engine} failed: {str(e)}")
168
- continue
169
-
170
- raise RuntimeError("All layout engines failed")
171
-
172
- except Exception as e:
173
- print(f"Mind map generation failed: {str(e)}")
174
- # Create error visualization
175
- try:
176
- import matplotlib.pyplot as plt
177
- plt.figure(figsize=(20, 10))
178
- plt.text(0.5, 0.5,
179
- f"Mind Map Generation Failed\n{str(e)}\n\nOriginal Text:\n{text[:200]}...",
180
- ha='center', va='center', wrap=True)
181
- plt.axis('off')
182
- error_path = os.path.join(temp_dir, "error_mindmap.png")
183
- plt.savefig(error_path, bbox_inches='tight', dpi=300)
184
- plt.close()
185
- return error_path
186
- except:
187
- return None
188
  @app.post("/summarize")
189
  def summarize_text(request: TextRequest):
190
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
@@ -223,16 +52,7 @@ def generate_word_cloud(request: TextRequest):
223
 
224
  # Gradio UI
225
  with gr.Blocks(theme=gr.themes.Soft(), css="""
226
- .mindmap-container img {
227
- max-height: none !important;
228
- min-width: 100% !important;
229
- object-fit: contain !important;
230
- background: white !important;
231
- border: 1px solid #e0e0e0 !important;
232
- border-radius: 8px !important;
233
- padding: 20px !important;
234
- }
235
- .gradio-container { max-width: 1400px !important; }
236
  """) as iface:
237
 
238
  gr.Markdown("# JFK Document Analysis Suite")
@@ -272,20 +92,7 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
272
  width=600
273
  )
274
 
275
- # Mind map section
276
- with gr.Row():
277
- mindmap_btn = gr.Button(
278
- "Generate Enhanced Mind Map",
279
- variant="primary"
280
- )
281
-
282
- with gr.Row():
283
- output_mindmap = gr.Image(
284
- label="High-Resolution Mind Map",
285
- elem_classes="mindmap-container",
286
- height=800,
287
- width=800
288
- )
289
 
290
  # Event handlers must be inside the Blocks context
291
  process_btn.click(
@@ -294,37 +101,6 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
294
  outputs=[full_doc_text, output_summary, output_entities, output_wordcloud]
295
  )
296
 
297
- def display_mindmap(text):
298
- try:
299
- img_path = generate_high_res_mindmap(text)
300
- if img_path and os.path.exists(img_path):
301
- return img_path
302
- return None
303
- except Exception as e:
304
- print(f"Display error: {e}")
305
- return None
306
-
307
- mindmap_btn.click(
308
- fn=display_mindmap,
309
- inputs=full_doc_text,
310
- outputs=output_mindmap,
311
- api_name="generate_mindmap",
312
- show_progress=True
313
- )
314
-
315
- # Add CSS for better image display
316
- css = """
317
- .mindmap-container img {
318
- max-width: 100% !important;
319
- height: auto !important;
320
- background: white !important;
321
- border: 2px solid #e0e0e0 !important;
322
- border-radius: 8px !important;
323
- padding: 10px !important;
324
- margin: 10px auto !important;
325
- display: block !important;
326
- }
327
- """
328
 
329
  if __name__ == "__main__":
330
  iface.launch(
 
6
  from wordcloud import WordCloud
7
  from summarization import summarizer
8
  from utils import list_files, process_file
 
 
9
 
10
  # Initialize FastAPI
11
  app = FastAPI()
 
14
  class TextRequest(BaseModel):
15
  text: str
16
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
  @app.post("/summarize")
18
  def summarize_text(request: TextRequest):
19
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
 
52
 
53
  # Gradio UI
54
  with gr.Blocks(theme=gr.themes.Soft(), css="""
55
+
 
 
 
 
 
 
 
 
 
56
  """) as iface:
57
 
58
  gr.Markdown("# JFK Document Analysis Suite")
 
92
  width=600
93
  )
94
 
95
+
 
 
 
 
 
 
 
 
 
 
 
 
 
96
 
97
  # Event handlers must be inside the Blocks context
98
  process_btn.click(
 
101
  outputs=[full_doc_text, output_summary, output_entities, output_wordcloud]
102
  )
103
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
104
 
105
  if __name__ == "__main__":
106
  iface.launch(
space/space/space/space/app.py CHANGED
@@ -6,8 +6,6 @@ from entity_recognition import extract_entities
6
  from wordcloud import WordCloud
7
  from summarization import summarizer
8
  from utils import list_files, process_file
9
- import pygraphviz as pgv
10
- import os
11
 
12
  # Initialize FastAPI
13
  app = FastAPI()
@@ -16,175 +14,6 @@ app = FastAPI()
16
  class TextRequest(BaseModel):
17
  text: str
18
 
19
- def wrap_label(label, max_length=15):
20
- """Improved label wrapping with hyphenation awareness"""
21
- if len(label) <= max_length:
22
- return label
23
-
24
- # Try to break at natural points
25
- break_chars = [" ", "-", "_", "/"]
26
- lines = []
27
- current = ""
28
-
29
- for char in label:
30
- if len(current) >= max_length and char in break_chars:
31
- lines.append(current.strip())
32
- current = char
33
- else:
34
- current += char
35
-
36
- if current:
37
- lines.append(current.strip())
38
-
39
- return "\\n".join(lines)
40
- def generate_high_res_mindmap(text):
41
- """Generate high-quality mind map with improved visibility"""
42
- try:
43
- # Verify we have entities to visualize
44
- entities = extract_entities(text)
45
- if not any(entities.values()):
46
- print("No entities found to generate mind map")
47
- return None
48
-
49
- # Create temporary directory
50
- temp_dir = "/tmp/mindmaps"
51
- os.makedirs(temp_dir, exist_ok=True)
52
- output_path = os.path.join(temp_dir, "mindmap.png")
53
-
54
- # Create graph with optimized settings
55
- G = pgv.AGraph(
56
- directed=True,
57
- rankdir="TB", # Top-to-bottom layout
58
- bgcolor="white",
59
- fontname="Arial", # More readable font
60
- splines="ortho", # Straight lines
61
- overlap="false",
62
- concentrate="true",
63
- ratio="compress",
64
- size="50,50", # Larger canvas
65
- dpi="1000", # Higher resolution
66
- pad="1.0",
67
- nodesep="1.2", # More space between nodes
68
- ranksep="1.5" # More vertical space
69
- )
70
-
71
- # Enhanced node styling for better visibility
72
- G.node_attr.update({
73
- "fontsize": "24", # Larger font
74
- "fontname": "Arial Bold",
75
- "shape": "box",
76
- "style": "rounded,filled",
77
- "fillcolor": "#E1F5FE",
78
- "color": "#0288D1",
79
- "height": "0.8",
80
- "width": "2.0",
81
- "penwidth": "2.0",
82
- "margin": "0.3,0.1" # Better text padding
83
- })
84
-
85
- # Enhanced edge styling
86
- G.edge_attr.update({
87
- "color": "#616161",
88
- "penwidth": "2.5",
89
- "arrowsize": "1.2",
90
- "fontname": "Arial",
91
- "fontsize": "20",
92
- "fontcolor": "#424242"
93
- })
94
-
95
- # Add central node with improved styling
96
- G.add_node("DOCUMENT",
97
- shape="doubleoctagon",
98
- fillcolor="#4FC3F7",
99
- fontsize="28",
100
- width="2.5",
101
- height="1.0",
102
- penwidth="3.0")
103
-
104
- # Add entities with better spacing
105
- max_categories = 5
106
- max_entities = 8
107
-
108
- for cat_idx, (category, values) in enumerate(entities.items()):
109
- if cat_idx >= max_categories:
110
- break
111
-
112
- # Main category node
113
- cat_node = f"CAT_{cat_idx}"
114
- G.add_node(cat_node,
115
- label=wrap_label(category, 18),
116
- shape="tab",
117
- fillcolor="#81D4FA",
118
- fontsize="22")
119
-
120
- G.add_edge("DOCUMENT", cat_node,
121
- label="contains",
122
- penwidth="3.0")
123
-
124
- # Add entities with grouping if needed
125
- if len(values) > max_entities:
126
- # Create subcategory groups
127
- for sub_idx, group in enumerate([values[i:i+max_entities]
128
- for i in range(0, len(values), max_entities)]):
129
- sub_node = f"SUB_{cat_idx}_{sub_idx}"
130
- G.add_node(sub_node,
131
- label=f"Group {sub_idx+1}",
132
- shape="folder",
133
- fillcolor="#B3E5FC")
134
- G.add_edge(cat_node, sub_node)
135
-
136
- for ent_idx, value in enumerate(group):
137
- ent_node = f"ENT_{cat_idx}_{sub_idx}_{ent_idx}"
138
- G.add_node(ent_node,
139
- label=wrap_label(value, 15),
140
- shape="note",
141
- fillcolor="#E1F5FE")
142
- G.add_edge(sub_node, ent_node)
143
- else:
144
- # Directly add entities
145
- for ent_idx, value in enumerate(values[:max_entities]):
146
- ent_node = f"ENT_{cat_idx}_{ent_idx}"
147
- G.add_node(ent_node,
148
- label=wrap_label(value, 15),
149
- shape="note",
150
- fillcolor="#E1F5FE")
151
- G.add_edge(cat_node, ent_node)
152
-
153
- # Generate output with multiple attempts
154
- for engine in ['dot', 'neato', 'sfdp']:
155
- try:
156
- G.draw(output_path,
157
- format="png",
158
- prog=engine,
159
- args=f"-Gdpi=300 -Gsize=50,50 -Goverlap=prism")
160
- print(f"Successfully generated with {engine}")
161
-
162
- # Verify the output
163
- if os.path.exists(output_path) and os.path.getsize(output_path) > 0:
164
- return output_path
165
-
166
- except Exception as e:
167
- print(f"Layout engine {engine} failed: {str(e)}")
168
- continue
169
-
170
- raise RuntimeError("All layout engines failed")
171
-
172
- except Exception as e:
173
- print(f"Mind map generation failed: {str(e)}")
174
- # Create error visualization
175
- try:
176
- import matplotlib.pyplot as plt
177
- plt.figure(figsize=(20, 10))
178
- plt.text(0.5, 0.5,
179
- f"Mind Map Generation Failed\n{str(e)}\n\nOriginal Text:\n{text[:200]}...",
180
- ha='center', va='center', wrap=True)
181
- plt.axis('off')
182
- error_path = os.path.join(temp_dir, "error_mindmap.png")
183
- plt.savefig(error_path, bbox_inches='tight', dpi=300)
184
- plt.close()
185
- return error_path
186
- except:
187
- return None
188
  @app.post("/summarize")
189
  def summarize_text(request: TextRequest):
190
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
@@ -223,16 +52,7 @@ def generate_word_cloud(request: TextRequest):
223
 
224
  # Gradio UI
225
  with gr.Blocks(theme=gr.themes.Soft(), css="""
226
- .mindmap-container img {
227
- max-height: none !important;
228
- min-width: 100% !important;
229
- object-fit: contain !important;
230
- background: white !important;
231
- border: 1px solid #e0e0e0 !important;
232
- border-radius: 8px !important;
233
- padding: 20px !important;
234
- }
235
- .gradio-container { max-width: 1400px !important; }
236
  """) as iface:
237
 
238
  gr.Markdown("# JFK Document Analysis Suite")
@@ -272,20 +92,7 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
272
  width=600
273
  )
274
 
275
- # Mind map section
276
- with gr.Row():
277
- mindmap_btn = gr.Button(
278
- "Generate Enhanced Mind Map",
279
- variant="primary"
280
- )
281
-
282
- with gr.Row():
283
- output_mindmap = gr.Image(
284
- label="High-Resolution Mind Map",
285
- elem_classes="mindmap-container",
286
- height=800,
287
- width=800
288
- )
289
 
290
  # Event handlers must be inside the Blocks context
291
  process_btn.click(
@@ -294,37 +101,6 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
294
  outputs=[full_doc_text, output_summary, output_entities, output_wordcloud]
295
  )
296
 
297
- def display_mindmap(text):
298
- try:
299
- img_path = generate_high_res_mindmap(text)
300
- if img_path and os.path.exists(img_path):
301
- return img_path
302
- return None
303
- except Exception as e:
304
- print(f"Display error: {e}")
305
- return None
306
-
307
- mindmap_btn.click(
308
- fn=display_mindmap,
309
- inputs=full_doc_text,
310
- outputs=output_mindmap,
311
- api_name="generate_mindmap",
312
- show_progress=True
313
- )
314
-
315
- # Add CSS for better image display
316
- css = """
317
- .mindmap-container img {
318
- max-width: 100% !important;
319
- height: auto !important;
320
- background: white !important;
321
- border: 2px solid #e0e0e0 !important;
322
- border-radius: 8px !important;
323
- padding: 10px !important;
324
- margin: 10px auto !important;
325
- display: block !important;
326
- }
327
- """
328
 
329
  if __name__ == "__main__":
330
  iface.launch(
 
6
  from wordcloud import WordCloud
7
  from summarization import summarizer
8
  from utils import list_files, process_file
 
 
9
 
10
  # Initialize FastAPI
11
  app = FastAPI()
 
14
  class TextRequest(BaseModel):
15
  text: str
16
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
  @app.post("/summarize")
18
  def summarize_text(request: TextRequest):
19
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
 
52
 
53
  # Gradio UI
54
  with gr.Blocks(theme=gr.themes.Soft(), css="""
55
+
 
 
 
 
 
 
 
 
 
56
  """) as iface:
57
 
58
  gr.Markdown("# JFK Document Analysis Suite")
 
92
  width=600
93
  )
94
 
95
+
 
 
 
 
 
 
 
 
 
 
 
 
 
96
 
97
  # Event handlers must be inside the Blocks context
98
  process_btn.click(
 
101
  outputs=[full_doc_text, output_summary, output_entities, output_wordcloud]
102
  )
103
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
104
 
105
  if __name__ == "__main__":
106
  iface.launch(
space/space/space/space/space/app.py CHANGED
@@ -6,8 +6,6 @@ from entity_recognition import extract_entities
6
  from wordcloud import WordCloud
7
  from summarization import summarizer
8
  from utils import list_files, process_file
9
- import pygraphviz as pgv
10
- import os
11
 
12
  # Initialize FastAPI
13
  app = FastAPI()
@@ -16,175 +14,6 @@ app = FastAPI()
16
  class TextRequest(BaseModel):
17
  text: str
18
 
19
- def wrap_label(label, max_length=15):
20
- """Improved label wrapping with hyphenation awareness"""
21
- if len(label) <= max_length:
22
- return label
23
-
24
- # Try to break at natural points
25
- break_chars = [" ", "-", "_", "/"]
26
- lines = []
27
- current = ""
28
-
29
- for char in label:
30
- if len(current) >= max_length and char in break_chars:
31
- lines.append(current.strip())
32
- current = char
33
- else:
34
- current += char
35
-
36
- if current:
37
- lines.append(current.strip())
38
-
39
- return "\\n".join(lines)
40
- def generate_high_res_mindmap(text):
41
- """Generate high-quality mind map with improved visibility"""
42
- try:
43
- # Verify we have entities to visualize
44
- entities = extract_entities(text)
45
- if not any(entities.values()):
46
- print("No entities found to generate mind map")
47
- return None
48
-
49
- # Create temporary directory
50
- temp_dir = "/tmp/mindmaps"
51
- os.makedirs(temp_dir, exist_ok=True)
52
- output_path = os.path.join(temp_dir, "mindmap.png")
53
-
54
- # Create graph with optimized settings
55
- G = pgv.AGraph(
56
- directed=True,
57
- rankdir="TB", # Top-to-bottom layout
58
- bgcolor="white",
59
- fontname="Arial", # More readable font
60
- splines="ortho", # Straight lines
61
- overlap="false",
62
- concentrate="true",
63
- ratio="compress",
64
- size="50,50", # Larger canvas
65
- dpi="1000", # Higher resolution
66
- pad="1.0",
67
- nodesep="1.2", # More space between nodes
68
- ranksep="1.5" # More vertical space
69
- )
70
-
71
- # Enhanced node styling for better visibility
72
- G.node_attr.update({
73
- "fontsize": "24", # Larger font
74
- "fontname": "Arial Bold",
75
- "shape": "box",
76
- "style": "rounded,filled",
77
- "fillcolor": "#E1F5FE",
78
- "color": "#0288D1",
79
- "height": "0.8",
80
- "width": "2.0",
81
- "penwidth": "2.0",
82
- "margin": "0.3,0.1" # Better text padding
83
- })
84
-
85
- # Enhanced edge styling
86
- G.edge_attr.update({
87
- "color": "#616161",
88
- "penwidth": "2.5",
89
- "arrowsize": "1.2",
90
- "fontname": "Arial",
91
- "fontsize": "20",
92
- "fontcolor": "#424242"
93
- })
94
-
95
- # Add central node with improved styling
96
- G.add_node("DOCUMENT",
97
- shape="doubleoctagon",
98
- fillcolor="#4FC3F7",
99
- fontsize="28",
100
- width="2.5",
101
- height="1.0",
102
- penwidth="3.0")
103
-
104
- # Add entities with better spacing
105
- max_categories = 5
106
- max_entities = 8
107
-
108
- for cat_idx, (category, values) in enumerate(entities.items()):
109
- if cat_idx >= max_categories:
110
- break
111
-
112
- # Main category node
113
- cat_node = f"CAT_{cat_idx}"
114
- G.add_node(cat_node,
115
- label=wrap_label(category, 18),
116
- shape="tab",
117
- fillcolor="#81D4FA",
118
- fontsize="22")
119
-
120
- G.add_edge("DOCUMENT", cat_node,
121
- label="contains",
122
- penwidth="3.0")
123
-
124
- # Add entities with grouping if needed
125
- if len(values) > max_entities:
126
- # Create subcategory groups
127
- for sub_idx, group in enumerate([values[i:i+max_entities]
128
- for i in range(0, len(values), max_entities)]):
129
- sub_node = f"SUB_{cat_idx}_{sub_idx}"
130
- G.add_node(sub_node,
131
- label=f"Group {sub_idx+1}",
132
- shape="folder",
133
- fillcolor="#B3E5FC")
134
- G.add_edge(cat_node, sub_node)
135
-
136
- for ent_idx, value in enumerate(group):
137
- ent_node = f"ENT_{cat_idx}_{sub_idx}_{ent_idx}"
138
- G.add_node(ent_node,
139
- label=wrap_label(value, 15),
140
- shape="note",
141
- fillcolor="#E1F5FE")
142
- G.add_edge(sub_node, ent_node)
143
- else:
144
- # Directly add entities
145
- for ent_idx, value in enumerate(values[:max_entities]):
146
- ent_node = f"ENT_{cat_idx}_{ent_idx}"
147
- G.add_node(ent_node,
148
- label=wrap_label(value, 15),
149
- shape="note",
150
- fillcolor="#E1F5FE")
151
- G.add_edge(cat_node, ent_node)
152
-
153
- # Generate output with multiple attempts
154
- for engine in ['dot', 'neato', 'sfdp']:
155
- try:
156
- G.draw(output_path,
157
- format="png",
158
- prog=engine,
159
- args=f"-Gdpi=300 -Gsize=50,50 -Goverlap=prism")
160
- print(f"Successfully generated with {engine}")
161
-
162
- # Verify the output
163
- if os.path.exists(output_path) and os.path.getsize(output_path) > 0:
164
- return output_path
165
-
166
- except Exception as e:
167
- print(f"Layout engine {engine} failed: {str(e)}")
168
- continue
169
-
170
- raise RuntimeError("All layout engines failed")
171
-
172
- except Exception as e:
173
- print(f"Mind map generation failed: {str(e)}")
174
- # Create error visualization
175
- try:
176
- import matplotlib.pyplot as plt
177
- plt.figure(figsize=(20, 10))
178
- plt.text(0.5, 0.5,
179
- f"Mind Map Generation Failed\n{str(e)}\n\nOriginal Text:\n{text[:200]}...",
180
- ha='center', va='center', wrap=True)
181
- plt.axis('off')
182
- error_path = os.path.join(temp_dir, "error_mindmap.png")
183
- plt.savefig(error_path, bbox_inches='tight', dpi=300)
184
- plt.close()
185
- return error_path
186
- except:
187
- return None
188
  @app.post("/summarize")
189
  def summarize_text(request: TextRequest):
190
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
@@ -223,16 +52,7 @@ def generate_word_cloud(request: TextRequest):
223
 
224
  # Gradio UI
225
  with gr.Blocks(theme=gr.themes.Soft(), css="""
226
- .mindmap-container img {
227
- max-height: none !important;
228
- min-width: 100% !important;
229
- object-fit: contain !important;
230
- background: white !important;
231
- border: 1px solid #e0e0e0 !important;
232
- border-radius: 8px !important;
233
- padding: 20px !important;
234
- }
235
- .gradio-container { max-width: 1400px !important; }
236
  """) as iface:
237
 
238
  gr.Markdown("# JFK Document Analysis Suite")
@@ -272,20 +92,7 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
272
  width=600
273
  )
274
 
275
- # Mind map section
276
- with gr.Row():
277
- mindmap_btn = gr.Button(
278
- "Generate Enhanced Mind Map",
279
- variant="primary"
280
- )
281
-
282
- with gr.Row():
283
- output_mindmap = gr.Image(
284
- label="High-Resolution Mind Map",
285
- elem_classes="mindmap-container",
286
- height=800,
287
- width=800
288
- )
289
 
290
  # Event handlers must be inside the Blocks context
291
  process_btn.click(
@@ -294,37 +101,6 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
294
  outputs=[full_doc_text, output_summary, output_entities, output_wordcloud]
295
  )
296
 
297
- def display_mindmap(text):
298
- try:
299
- img_path = generate_high_res_mindmap(text)
300
- if img_path and os.path.exists(img_path):
301
- return img_path
302
- return None
303
- except Exception as e:
304
- print(f"Display error: {e}")
305
- return None
306
-
307
- mindmap_btn.click(
308
- fn=display_mindmap,
309
- inputs=full_doc_text,
310
- outputs=output_mindmap,
311
- api_name="generate_mindmap",
312
- show_progress=True
313
- )
314
-
315
- # Add CSS for better image display
316
- css = """
317
- .mindmap-container img {
318
- max-width: 100% !important;
319
- height: auto !important;
320
- background: white !important;
321
- border: 2px solid #e0e0e0 !important;
322
- border-radius: 8px !important;
323
- padding: 10px !important;
324
- margin: 10px auto !important;
325
- display: block !important;
326
- }
327
- """
328
 
329
  if __name__ == "__main__":
330
  iface.launch(
 
6
  from wordcloud import WordCloud
7
  from summarization import summarizer
8
  from utils import list_files, process_file
 
 
9
 
10
  # Initialize FastAPI
11
  app = FastAPI()
 
14
  class TextRequest(BaseModel):
15
  text: str
16
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
  @app.post("/summarize")
18
  def summarize_text(request: TextRequest):
19
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
 
52
 
53
  # Gradio UI
54
  with gr.Blocks(theme=gr.themes.Soft(), css="""
55
+
 
 
 
 
 
 
 
 
 
56
  """) as iface:
57
 
58
  gr.Markdown("# JFK Document Analysis Suite")
 
92
  width=600
93
  )
94
 
95
+
 
 
 
 
 
 
 
 
 
 
 
 
 
96
 
97
  # Event handlers must be inside the Blocks context
98
  process_btn.click(
 
101
  outputs=[full_doc_text, output_summary, output_entities, output_wordcloud]
102
  )
103
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
104
 
105
  if __name__ == "__main__":
106
  iface.launch(
space/space/space/space/space/space/app.py CHANGED
@@ -6,8 +6,6 @@ from entity_recognition import extract_entities
6
  from wordcloud import WordCloud
7
  from summarization import summarizer
8
  from utils import list_files, process_file
9
- import pygraphviz as pgv
10
- import os
11
 
12
  # Initialize FastAPI
13
  app = FastAPI()
@@ -16,175 +14,6 @@ app = FastAPI()
16
  class TextRequest(BaseModel):
17
  text: str
18
 
19
- def wrap_label(label, max_length=15):
20
- """Improved label wrapping with hyphenation awareness"""
21
- if len(label) <= max_length:
22
- return label
23
-
24
- # Try to break at natural points
25
- break_chars = [" ", "-", "_", "/"]
26
- lines = []
27
- current = ""
28
-
29
- for char in label:
30
- if len(current) >= max_length and char in break_chars:
31
- lines.append(current.strip())
32
- current = char
33
- else:
34
- current += char
35
-
36
- if current:
37
- lines.append(current.strip())
38
-
39
- return "\\n".join(lines)
40
- def generate_high_res_mindmap(text):
41
- """Generate high-quality mind map with improved visibility"""
42
- try:
43
- # Verify we have entities to visualize
44
- entities = extract_entities(text)
45
- if not any(entities.values()):
46
- print("No entities found to generate mind map")
47
- return None
48
-
49
- # Create temporary directory
50
- temp_dir = "/tmp/mindmaps"
51
- os.makedirs(temp_dir, exist_ok=True)
52
- output_path = os.path.join(temp_dir, "mindmap.png")
53
-
54
- # Create graph with optimized settings
55
- G = pgv.AGraph(
56
- directed=True,
57
- rankdir="TB", # Top-to-bottom layout
58
- bgcolor="white",
59
- fontname="Arial", # More readable font
60
- splines="ortho", # Straight lines
61
- overlap="false",
62
- concentrate="true",
63
- ratio="compress",
64
- size="50,50", # Larger canvas
65
- dpi="1000", # Higher resolution
66
- pad="1.0",
67
- nodesep="1.2", # More space between nodes
68
- ranksep="1.5" # More vertical space
69
- )
70
-
71
- # Enhanced node styling for better visibility
72
- G.node_attr.update({
73
- "fontsize": "24", # Larger font
74
- "fontname": "Arial Bold",
75
- "shape": "box",
76
- "style": "rounded,filled",
77
- "fillcolor": "#E1F5FE",
78
- "color": "#0288D1",
79
- "height": "0.8",
80
- "width": "2.0",
81
- "penwidth": "2.0",
82
- "margin": "0.3,0.1" # Better text padding
83
- })
84
-
85
- # Enhanced edge styling
86
- G.edge_attr.update({
87
- "color": "#616161",
88
- "penwidth": "2.5",
89
- "arrowsize": "1.2",
90
- "fontname": "Arial",
91
- "fontsize": "20",
92
- "fontcolor": "#424242"
93
- })
94
-
95
- # Add central node with improved styling
96
- G.add_node("DOCUMENT",
97
- shape="doubleoctagon",
98
- fillcolor="#4FC3F7",
99
- fontsize="28",
100
- width="2.5",
101
- height="1.0",
102
- penwidth="3.0")
103
-
104
- # Add entities with better spacing
105
- max_categories = 5
106
- max_entities = 8
107
-
108
- for cat_idx, (category, values) in enumerate(entities.items()):
109
- if cat_idx >= max_categories:
110
- break
111
-
112
- # Main category node
113
- cat_node = f"CAT_{cat_idx}"
114
- G.add_node(cat_node,
115
- label=wrap_label(category, 18),
116
- shape="tab",
117
- fillcolor="#81D4FA",
118
- fontsize="22")
119
-
120
- G.add_edge("DOCUMENT", cat_node,
121
- label="contains",
122
- penwidth="3.0")
123
-
124
- # Add entities with grouping if needed
125
- if len(values) > max_entities:
126
- # Create subcategory groups
127
- for sub_idx, group in enumerate([values[i:i+max_entities]
128
- for i in range(0, len(values), max_entities)]):
129
- sub_node = f"SUB_{cat_idx}_{sub_idx}"
130
- G.add_node(sub_node,
131
- label=f"Group {sub_idx+1}",
132
- shape="folder",
133
- fillcolor="#B3E5FC")
134
- G.add_edge(cat_node, sub_node)
135
-
136
- for ent_idx, value in enumerate(group):
137
- ent_node = f"ENT_{cat_idx}_{sub_idx}_{ent_idx}"
138
- G.add_node(ent_node,
139
- label=wrap_label(value, 15),
140
- shape="note",
141
- fillcolor="#E1F5FE")
142
- G.add_edge(sub_node, ent_node)
143
- else:
144
- # Directly add entities
145
- for ent_idx, value in enumerate(values[:max_entities]):
146
- ent_node = f"ENT_{cat_idx}_{ent_idx}"
147
- G.add_node(ent_node,
148
- label=wrap_label(value, 15),
149
- shape="note",
150
- fillcolor="#E1F5FE")
151
- G.add_edge(cat_node, ent_node)
152
-
153
- # Generate output with multiple attempts
154
- for engine in ['dot', 'neato', 'sfdp']:
155
- try:
156
- G.draw(output_path,
157
- format="png",
158
- prog=engine,
159
- args=f"-Gdpi=300 -Gsize=50,50 -Goverlap=prism")
160
- print(f"Successfully generated with {engine}")
161
-
162
- # Verify the output
163
- if os.path.exists(output_path) and os.path.getsize(output_path) > 0:
164
- return output_path
165
-
166
- except Exception as e:
167
- print(f"Layout engine {engine} failed: {str(e)}")
168
- continue
169
-
170
- raise RuntimeError("All layout engines failed")
171
-
172
- except Exception as e:
173
- print(f"Mind map generation failed: {str(e)}")
174
- # Create error visualization
175
- try:
176
- import matplotlib.pyplot as plt
177
- plt.figure(figsize=(20, 10))
178
- plt.text(0.5, 0.5,
179
- f"Mind Map Generation Failed\n{str(e)}\n\nOriginal Text:\n{text[:200]}...",
180
- ha='center', va='center', wrap=True)
181
- plt.axis('off')
182
- error_path = os.path.join(temp_dir, "error_mindmap.png")
183
- plt.savefig(error_path, bbox_inches='tight', dpi=300)
184
- plt.close()
185
- return error_path
186
- except:
187
- return None
188
  @app.post("/summarize")
189
  def summarize_text(request: TextRequest):
190
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
@@ -223,16 +52,7 @@ def generate_word_cloud(request: TextRequest):
223
 
224
  # Gradio UI
225
  with gr.Blocks(theme=gr.themes.Soft(), css="""
226
- .mindmap-container img {
227
- max-height: none !important;
228
- min-width: 100% !important;
229
- object-fit: contain !important;
230
- background: white !important;
231
- border: 1px solid #e0e0e0 !important;
232
- border-radius: 8px !important;
233
- padding: 20px !important;
234
- }
235
- .gradio-container { max-width: 1400px !important; }
236
  """) as iface:
237
 
238
  gr.Markdown("# JFK Document Analysis Suite")
@@ -272,20 +92,7 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
272
  width=600
273
  )
274
 
275
- # Mind map section
276
- with gr.Row():
277
- mindmap_btn = gr.Button(
278
- "Generate Enhanced Mind Map",
279
- variant="primary"
280
- )
281
-
282
- with gr.Row():
283
- output_mindmap = gr.Image(
284
- label="High-Resolution Mind Map",
285
- elem_classes="mindmap-container",
286
- height=800,
287
- width=800
288
- )
289
 
290
  # Event handlers must be inside the Blocks context
291
  process_btn.click(
@@ -294,37 +101,6 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
294
  outputs=[full_doc_text, output_summary, output_entities, output_wordcloud]
295
  )
296
 
297
- def display_mindmap(text):
298
- try:
299
- img_path = generate_high_res_mindmap(text)
300
- if img_path and os.path.exists(img_path):
301
- return img_path
302
- return None
303
- except Exception as e:
304
- print(f"Display error: {e}")
305
- return None
306
-
307
- mindmap_btn.click(
308
- fn=display_mindmap,
309
- inputs=full_doc_text,
310
- outputs=output_mindmap,
311
- api_name="generate_mindmap",
312
- show_progress=True
313
- )
314
-
315
- # Add CSS for better image display
316
- css = """
317
- .mindmap-container img {
318
- max-width: 100% !important;
319
- height: auto !important;
320
- background: white !important;
321
- border: 2px solid #e0e0e0 !important;
322
- border-radius: 8px !important;
323
- padding: 10px !important;
324
- margin: 10px auto !important;
325
- display: block !important;
326
- }
327
- """
328
 
329
  if __name__ == "__main__":
330
  iface.launch(
 
6
  from wordcloud import WordCloud
7
  from summarization import summarizer
8
  from utils import list_files, process_file
 
 
9
 
10
  # Initialize FastAPI
11
  app = FastAPI()
 
14
  class TextRequest(BaseModel):
15
  text: str
16
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
  @app.post("/summarize")
18
  def summarize_text(request: TextRequest):
19
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
 
52
 
53
  # Gradio UI
54
  with gr.Blocks(theme=gr.themes.Soft(), css="""
55
+
 
 
 
 
 
 
 
 
 
56
  """) as iface:
57
 
58
  gr.Markdown("# JFK Document Analysis Suite")
 
92
  width=600
93
  )
94
 
95
+
 
 
 
 
 
 
 
 
 
 
 
 
 
96
 
97
  # Event handlers must be inside the Blocks context
98
  process_btn.click(
 
101
  outputs=[full_doc_text, output_summary, output_entities, output_wordcloud]
102
  )
103
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
104
 
105
  if __name__ == "__main__":
106
  iface.launch(
space/space/space/space/space/space/space/app.py CHANGED
@@ -6,8 +6,6 @@ from entity_recognition import extract_entities
6
  from wordcloud import WordCloud
7
  from summarization import summarizer
8
  from utils import list_files, process_file
9
- import pygraphviz as pgv
10
- import os
11
 
12
  # Initialize FastAPI
13
  app = FastAPI()
@@ -16,175 +14,6 @@ app = FastAPI()
16
  class TextRequest(BaseModel):
17
  text: str
18
 
19
- def wrap_label(label, max_length=15):
20
- """Improved label wrapping with hyphenation awareness"""
21
- if len(label) <= max_length:
22
- return label
23
-
24
- # Try to break at natural points
25
- break_chars = [" ", "-", "_", "/"]
26
- lines = []
27
- current = ""
28
-
29
- for char in label:
30
- if len(current) >= max_length and char in break_chars:
31
- lines.append(current.strip())
32
- current = char
33
- else:
34
- current += char
35
-
36
- if current:
37
- lines.append(current.strip())
38
-
39
- return "\\n".join(lines)
40
- def generate_high_res_mindmap(text):
41
- """Generate high-quality mind map with improved visibility"""
42
- try:
43
- # Verify we have entities to visualize
44
- entities = extract_entities(text)
45
- if not any(entities.values()):
46
- print("No entities found to generate mind map")
47
- return None
48
-
49
- # Create temporary directory
50
- temp_dir = "/tmp/mindmaps"
51
- os.makedirs(temp_dir, exist_ok=True)
52
- output_path = os.path.join(temp_dir, "mindmap.png")
53
-
54
- # Create graph with optimized settings
55
- G = pgv.AGraph(
56
- directed=True,
57
- rankdir="TB", # Top-to-bottom layout
58
- bgcolor="white",
59
- fontname="Arial", # More readable font
60
- splines="ortho", # Straight lines
61
- overlap="false",
62
- concentrate="true",
63
- ratio="compress",
64
- size="50,50", # Larger canvas
65
- dpi="1000", # Higher resolution
66
- pad="1.0",
67
- nodesep="1.2", # More space between nodes
68
- ranksep="1.5" # More vertical space
69
- )
70
-
71
- # Enhanced node styling for better visibility
72
- G.node_attr.update({
73
- "fontsize": "24", # Larger font
74
- "fontname": "Arial Bold",
75
- "shape": "box",
76
- "style": "rounded,filled",
77
- "fillcolor": "#E1F5FE",
78
- "color": "#0288D1",
79
- "height": "0.8",
80
- "width": "2.0",
81
- "penwidth": "2.0",
82
- "margin": "0.3,0.1" # Better text padding
83
- })
84
-
85
- # Enhanced edge styling
86
- G.edge_attr.update({
87
- "color": "#616161",
88
- "penwidth": "2.5",
89
- "arrowsize": "1.2",
90
- "fontname": "Arial",
91
- "fontsize": "20",
92
- "fontcolor": "#424242"
93
- })
94
-
95
- # Add central node with improved styling
96
- G.add_node("DOCUMENT",
97
- shape="doubleoctagon",
98
- fillcolor="#4FC3F7",
99
- fontsize="28",
100
- width="2.5",
101
- height="1.0",
102
- penwidth="3.0")
103
-
104
- # Add entities with better spacing
105
- max_categories = 5
106
- max_entities = 8
107
-
108
- for cat_idx, (category, values) in enumerate(entities.items()):
109
- if cat_idx >= max_categories:
110
- break
111
-
112
- # Main category node
113
- cat_node = f"CAT_{cat_idx}"
114
- G.add_node(cat_node,
115
- label=wrap_label(category, 18),
116
- shape="tab",
117
- fillcolor="#81D4FA",
118
- fontsize="22")
119
-
120
- G.add_edge("DOCUMENT", cat_node,
121
- label="contains",
122
- penwidth="3.0")
123
-
124
- # Add entities with grouping if needed
125
- if len(values) > max_entities:
126
- # Create subcategory groups
127
- for sub_idx, group in enumerate([values[i:i+max_entities]
128
- for i in range(0, len(values), max_entities)]):
129
- sub_node = f"SUB_{cat_idx}_{sub_idx}"
130
- G.add_node(sub_node,
131
- label=f"Group {sub_idx+1}",
132
- shape="folder",
133
- fillcolor="#B3E5FC")
134
- G.add_edge(cat_node, sub_node)
135
-
136
- for ent_idx, value in enumerate(group):
137
- ent_node = f"ENT_{cat_idx}_{sub_idx}_{ent_idx}"
138
- G.add_node(ent_node,
139
- label=wrap_label(value, 15),
140
- shape="note",
141
- fillcolor="#E1F5FE")
142
- G.add_edge(sub_node, ent_node)
143
- else:
144
- # Directly add entities
145
- for ent_idx, value in enumerate(values[:max_entities]):
146
- ent_node = f"ENT_{cat_idx}_{ent_idx}"
147
- G.add_node(ent_node,
148
- label=wrap_label(value, 15),
149
- shape="note",
150
- fillcolor="#E1F5FE")
151
- G.add_edge(cat_node, ent_node)
152
-
153
- # Generate output with multiple attempts
154
- for engine in ['dot', 'neato', 'sfdp']:
155
- try:
156
- G.draw(output_path,
157
- format="png",
158
- prog=engine,
159
- args=f"-Gdpi=300 -Gsize=50,50 -Goverlap=prism")
160
- print(f"Successfully generated with {engine}")
161
-
162
- # Verify the output
163
- if os.path.exists(output_path) and os.path.getsize(output_path) > 0:
164
- return output_path
165
-
166
- except Exception as e:
167
- print(f"Layout engine {engine} failed: {str(e)}")
168
- continue
169
-
170
- raise RuntimeError("All layout engines failed")
171
-
172
- except Exception as e:
173
- print(f"Mind map generation failed: {str(e)}")
174
- # Create error visualization
175
- try:
176
- import matplotlib.pyplot as plt
177
- plt.figure(figsize=(20, 10))
178
- plt.text(0.5, 0.5,
179
- f"Mind Map Generation Failed\n{str(e)}\n\nOriginal Text:\n{text[:200]}...",
180
- ha='center', va='center', wrap=True)
181
- plt.axis('off')
182
- error_path = os.path.join(temp_dir, "error_mindmap.png")
183
- plt.savefig(error_path, bbox_inches='tight', dpi=300)
184
- plt.close()
185
- return error_path
186
- except:
187
- return None
188
  @app.post("/summarize")
189
  def summarize_text(request: TextRequest):
190
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
@@ -223,16 +52,7 @@ def generate_word_cloud(request: TextRequest):
223
 
224
  # Gradio UI
225
  with gr.Blocks(theme=gr.themes.Soft(), css="""
226
- .mindmap-container img {
227
- max-height: none !important;
228
- min-width: 100% !important;
229
- object-fit: contain !important;
230
- background: white !important;
231
- border: 1px solid #e0e0e0 !important;
232
- border-radius: 8px !important;
233
- padding: 20px !important;
234
- }
235
- .gradio-container { max-width: 1400px !important; }
236
  """) as iface:
237
 
238
  gr.Markdown("# JFK Document Analysis Suite")
@@ -272,20 +92,7 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
272
  width=600
273
  )
274
 
275
- # Mind map section
276
- with gr.Row():
277
- mindmap_btn = gr.Button(
278
- "Generate Enhanced Mind Map",
279
- variant="primary"
280
- )
281
-
282
- with gr.Row():
283
- output_mindmap = gr.Image(
284
- label="High-Resolution Mind Map",
285
- elem_classes="mindmap-container",
286
- height=800,
287
- width=800
288
- )
289
 
290
  # Event handlers must be inside the Blocks context
291
  process_btn.click(
@@ -294,37 +101,6 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
294
  outputs=[full_doc_text, output_summary, output_entities, output_wordcloud]
295
  )
296
 
297
- def display_mindmap(text):
298
- try:
299
- img_path = generate_high_res_mindmap(text)
300
- if img_path and os.path.exists(img_path):
301
- return img_path
302
- return None
303
- except Exception as e:
304
- print(f"Display error: {e}")
305
- return None
306
-
307
- mindmap_btn.click(
308
- fn=display_mindmap,
309
- inputs=full_doc_text,
310
- outputs=output_mindmap,
311
- api_name="generate_mindmap",
312
- show_progress=True
313
- )
314
-
315
- # Add CSS for better image display
316
- css = """
317
- .mindmap-container img {
318
- max-width: 100% !important;
319
- height: auto !important;
320
- background: white !important;
321
- border: 2px solid #e0e0e0 !important;
322
- border-radius: 8px !important;
323
- padding: 10px !important;
324
- margin: 10px auto !important;
325
- display: block !important;
326
- }
327
- """
328
 
329
  if __name__ == "__main__":
330
  iface.launch(
 
6
  from wordcloud import WordCloud
7
  from summarization import summarizer
8
  from utils import list_files, process_file
 
 
9
 
10
  # Initialize FastAPI
11
  app = FastAPI()
 
14
  class TextRequest(BaseModel):
15
  text: str
16
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
  @app.post("/summarize")
18
  def summarize_text(request: TextRequest):
19
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
 
52
 
53
  # Gradio UI
54
  with gr.Blocks(theme=gr.themes.Soft(), css="""
55
+
 
 
 
 
 
 
 
 
 
56
  """) as iface:
57
 
58
  gr.Markdown("# JFK Document Analysis Suite")
 
92
  width=600
93
  )
94
 
95
+
 
 
 
 
 
 
 
 
 
 
 
 
 
96
 
97
  # Event handlers must be inside the Blocks context
98
  process_btn.click(
 
101
  outputs=[full_doc_text, output_summary, output_entities, output_wordcloud]
102
  )
103
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
104
 
105
  if __name__ == "__main__":
106
  iface.launch(
space/space/space/space/space/space/space/space/app.py CHANGED
@@ -6,8 +6,6 @@ from entity_recognition import extract_entities
6
  from wordcloud import WordCloud
7
  from summarization import summarizer
8
  from utils import list_files, process_file
9
- import pygraphviz as pgv
10
- import os
11
 
12
  # Initialize FastAPI
13
  app = FastAPI()
@@ -16,175 +14,6 @@ app = FastAPI()
16
  class TextRequest(BaseModel):
17
  text: str
18
 
19
- def wrap_label(label, max_length=15):
20
- """Improved label wrapping with hyphenation awareness"""
21
- if len(label) <= max_length:
22
- return label
23
-
24
- # Try to break at natural points
25
- break_chars = [" ", "-", "_", "/"]
26
- lines = []
27
- current = ""
28
-
29
- for char in label:
30
- if len(current) >= max_length and char in break_chars:
31
- lines.append(current.strip())
32
- current = char
33
- else:
34
- current += char
35
-
36
- if current:
37
- lines.append(current.strip())
38
-
39
- return "\\n".join(lines)
40
- def generate_high_res_mindmap(text):
41
- """Generate high-quality mind map with improved visibility"""
42
- try:
43
- # Verify we have entities to visualize
44
- entities = extract_entities(text)
45
- if not any(entities.values()):
46
- print("No entities found to generate mind map")
47
- return None
48
-
49
- # Create temporary directory
50
- temp_dir = "/tmp/mindmaps"
51
- os.makedirs(temp_dir, exist_ok=True)
52
- output_path = os.path.join(temp_dir, "mindmap.png")
53
-
54
- # Create graph with optimized settings
55
- G = pgv.AGraph(
56
- directed=True,
57
- rankdir="TB", # Top-to-bottom layout
58
- bgcolor="white",
59
- fontname="Arial", # More readable font
60
- splines="ortho", # Straight lines
61
- overlap="false",
62
- concentrate="true",
63
- ratio="compress",
64
- size="50,50", # Larger canvas
65
- dpi="1000", # Higher resolution
66
- pad="1.0",
67
- nodesep="1.2", # More space between nodes
68
- ranksep="1.5" # More vertical space
69
- )
70
-
71
- # Enhanced node styling for better visibility
72
- G.node_attr.update({
73
- "fontsize": "24", # Larger font
74
- "fontname": "Arial Bold",
75
- "shape": "box",
76
- "style": "rounded,filled",
77
- "fillcolor": "#E1F5FE",
78
- "color": "#0288D1",
79
- "height": "0.8",
80
- "width": "2.0",
81
- "penwidth": "2.0",
82
- "margin": "0.3,0.1" # Better text padding
83
- })
84
-
85
- # Enhanced edge styling
86
- G.edge_attr.update({
87
- "color": "#616161",
88
- "penwidth": "2.5",
89
- "arrowsize": "1.2",
90
- "fontname": "Arial",
91
- "fontsize": "20",
92
- "fontcolor": "#424242"
93
- })
94
-
95
- # Add central node with improved styling
96
- G.add_node("DOCUMENT",
97
- shape="doubleoctagon",
98
- fillcolor="#4FC3F7",
99
- fontsize="28",
100
- width="2.5",
101
- height="1.0",
102
- penwidth="3.0")
103
-
104
- # Add entities with better spacing
105
- max_categories = 5
106
- max_entities = 8
107
-
108
- for cat_idx, (category, values) in enumerate(entities.items()):
109
- if cat_idx >= max_categories:
110
- break
111
-
112
- # Main category node
113
- cat_node = f"CAT_{cat_idx}"
114
- G.add_node(cat_node,
115
- label=wrap_label(category, 18),
116
- shape="tab",
117
- fillcolor="#81D4FA",
118
- fontsize="22")
119
-
120
- G.add_edge("DOCUMENT", cat_node,
121
- label="contains",
122
- penwidth="3.0")
123
-
124
- # Add entities with grouping if needed
125
- if len(values) > max_entities:
126
- # Create subcategory groups
127
- for sub_idx, group in enumerate([values[i:i+max_entities]
128
- for i in range(0, len(values), max_entities)]):
129
- sub_node = f"SUB_{cat_idx}_{sub_idx}"
130
- G.add_node(sub_node,
131
- label=f"Group {sub_idx+1}",
132
- shape="folder",
133
- fillcolor="#B3E5FC")
134
- G.add_edge(cat_node, sub_node)
135
-
136
- for ent_idx, value in enumerate(group):
137
- ent_node = f"ENT_{cat_idx}_{sub_idx}_{ent_idx}"
138
- G.add_node(ent_node,
139
- label=wrap_label(value, 15),
140
- shape="note",
141
- fillcolor="#E1F5FE")
142
- G.add_edge(sub_node, ent_node)
143
- else:
144
- # Directly add entities
145
- for ent_idx, value in enumerate(values[:max_entities]):
146
- ent_node = f"ENT_{cat_idx}_{ent_idx}"
147
- G.add_node(ent_node,
148
- label=wrap_label(value, 15),
149
- shape="note",
150
- fillcolor="#E1F5FE")
151
- G.add_edge(cat_node, ent_node)
152
-
153
- # Generate output with multiple attempts
154
- for engine in ['dot', 'neato', 'sfdp']:
155
- try:
156
- G.draw(output_path,
157
- format="png",
158
- prog=engine,
159
- args=f"-Gdpi=300 -Gsize=50,50 -Goverlap=prism")
160
- print(f"Successfully generated with {engine}")
161
-
162
- # Verify the output
163
- if os.path.exists(output_path) and os.path.getsize(output_path) > 0:
164
- return output_path
165
-
166
- except Exception as e:
167
- print(f"Layout engine {engine} failed: {str(e)}")
168
- continue
169
-
170
- raise RuntimeError("All layout engines failed")
171
-
172
- except Exception as e:
173
- print(f"Mind map generation failed: {str(e)}")
174
- # Create error visualization
175
- try:
176
- import matplotlib.pyplot as plt
177
- plt.figure(figsize=(20, 10))
178
- plt.text(0.5, 0.5,
179
- f"Mind Map Generation Failed\n{str(e)}\n\nOriginal Text:\n{text[:200]}...",
180
- ha='center', va='center', wrap=True)
181
- plt.axis('off')
182
- error_path = os.path.join(temp_dir, "error_mindmap.png")
183
- plt.savefig(error_path, bbox_inches='tight', dpi=300)
184
- plt.close()
185
- return error_path
186
- except:
187
- return None
188
  @app.post("/summarize")
189
  def summarize_text(request: TextRequest):
190
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
@@ -223,16 +52,7 @@ def generate_word_cloud(request: TextRequest):
223
 
224
  # Gradio UI
225
  with gr.Blocks(theme=gr.themes.Soft(), css="""
226
- .mindmap-container img {
227
- max-height: none !important;
228
- min-width: 100% !important;
229
- object-fit: contain !important;
230
- background: white !important;
231
- border: 1px solid #e0e0e0 !important;
232
- border-radius: 8px !important;
233
- padding: 20px !important;
234
- }
235
- .gradio-container { max-width: 1400px !important; }
236
  """) as iface:
237
 
238
  gr.Markdown("# JFK Document Analysis Suite")
@@ -272,20 +92,7 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
272
  width=600
273
  )
274
 
275
- # Mind map section
276
- with gr.Row():
277
- mindmap_btn = gr.Button(
278
- "Generate Enhanced Mind Map",
279
- variant="primary"
280
- )
281
-
282
- with gr.Row():
283
- output_mindmap = gr.Image(
284
- label="High-Resolution Mind Map",
285
- elem_classes="mindmap-container",
286
- height=800,
287
- width=800
288
- )
289
 
290
  # Event handlers must be inside the Blocks context
291
  process_btn.click(
@@ -294,37 +101,6 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
294
  outputs=[full_doc_text, output_summary, output_entities, output_wordcloud]
295
  )
296
 
297
- def display_mindmap(text):
298
- try:
299
- img_path = generate_high_res_mindmap(text)
300
- if img_path and os.path.exists(img_path):
301
- return img_path
302
- return None
303
- except Exception as e:
304
- print(f"Display error: {e}")
305
- return None
306
-
307
- mindmap_btn.click(
308
- fn=display_mindmap,
309
- inputs=full_doc_text,
310
- outputs=output_mindmap,
311
- api_name="generate_mindmap",
312
- show_progress=True
313
- )
314
-
315
- # Add CSS for better image display
316
- css = """
317
- .mindmap-container img {
318
- max-width: 100% !important;
319
- height: auto !important;
320
- background: white !important;
321
- border: 2px solid #e0e0e0 !important;
322
- border-radius: 8px !important;
323
- padding: 10px !important;
324
- margin: 10px auto !important;
325
- display: block !important;
326
- }
327
- """
328
 
329
  if __name__ == "__main__":
330
  iface.launch(
 
6
  from wordcloud import WordCloud
7
  from summarization import summarizer
8
  from utils import list_files, process_file
 
 
9
 
10
  # Initialize FastAPI
11
  app = FastAPI()
 
14
  class TextRequest(BaseModel):
15
  text: str
16
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
  @app.post("/summarize")
18
  def summarize_text(request: TextRequest):
19
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
 
52
 
53
  # Gradio UI
54
  with gr.Blocks(theme=gr.themes.Soft(), css="""
55
+
 
 
 
 
 
 
 
 
 
56
  """) as iface:
57
 
58
  gr.Markdown("# JFK Document Analysis Suite")
 
92
  width=600
93
  )
94
 
95
+
 
 
 
 
 
 
 
 
 
 
 
 
 
96
 
97
  # Event handlers must be inside the Blocks context
98
  process_btn.click(
 
101
  outputs=[full_doc_text, output_summary, output_entities, output_wordcloud]
102
  )
103
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
104
 
105
  if __name__ == "__main__":
106
  iface.launch(
space/space/space/space/space/space/space/space/space/app.py CHANGED
@@ -6,8 +6,6 @@ from entity_recognition import extract_entities
6
  from wordcloud import WordCloud
7
  from summarization import summarizer
8
  from utils import list_files, process_file
9
- import pygraphviz as pgv
10
- import os
11
 
12
  # Initialize FastAPI
13
  app = FastAPI()
@@ -16,175 +14,6 @@ app = FastAPI()
16
  class TextRequest(BaseModel):
17
  text: str
18
 
19
- def wrap_label(label, max_length=15):
20
- """Improved label wrapping with hyphenation awareness"""
21
- if len(label) <= max_length:
22
- return label
23
-
24
- # Try to break at natural points
25
- break_chars = [" ", "-", "_", "/"]
26
- lines = []
27
- current = ""
28
-
29
- for char in label:
30
- if len(current) >= max_length and char in break_chars:
31
- lines.append(current.strip())
32
- current = char
33
- else:
34
- current += char
35
-
36
- if current:
37
- lines.append(current.strip())
38
-
39
- return "\\n".join(lines)
40
- def generate_high_res_mindmap(text):
41
- """Generate high-quality mind map with improved visibility"""
42
- try:
43
- # Verify we have entities to visualize
44
- entities = extract_entities(text)
45
- if not any(entities.values()):
46
- print("No entities found to generate mind map")
47
- return None
48
-
49
- # Create temporary directory
50
- temp_dir = "/tmp/mindmaps"
51
- os.makedirs(temp_dir, exist_ok=True)
52
- output_path = os.path.join(temp_dir, "mindmap.png")
53
-
54
- # Create graph with optimized settings
55
- G = pgv.AGraph(
56
- directed=True,
57
- rankdir="TB", # Top-to-bottom layout
58
- bgcolor="white",
59
- fontname="Arial", # More readable font
60
- splines="ortho", # Straight lines
61
- overlap="false",
62
- concentrate="true",
63
- ratio="compress",
64
- size="50,50", # Larger canvas
65
- dpi="1000", # Higher resolution
66
- pad="1.0",
67
- nodesep="1.2", # More space between nodes
68
- ranksep="1.5" # More vertical space
69
- )
70
-
71
- # Enhanced node styling for better visibility
72
- G.node_attr.update({
73
- "fontsize": "24", # Larger font
74
- "fontname": "Arial Bold",
75
- "shape": "box",
76
- "style": "rounded,filled",
77
- "fillcolor": "#E1F5FE",
78
- "color": "#0288D1",
79
- "height": "0.8",
80
- "width": "2.0",
81
- "penwidth": "2.0",
82
- "margin": "0.3,0.1" # Better text padding
83
- })
84
-
85
- # Enhanced edge styling
86
- G.edge_attr.update({
87
- "color": "#616161",
88
- "penwidth": "2.5",
89
- "arrowsize": "1.2",
90
- "fontname": "Arial",
91
- "fontsize": "20",
92
- "fontcolor": "#424242"
93
- })
94
-
95
- # Add central node with improved styling
96
- G.add_node("DOCUMENT",
97
- shape="doubleoctagon",
98
- fillcolor="#4FC3F7",
99
- fontsize="28",
100
- width="2.5",
101
- height="1.0",
102
- penwidth="3.0")
103
-
104
- # Add entities with better spacing
105
- max_categories = 5
106
- max_entities = 8
107
-
108
- for cat_idx, (category, values) in enumerate(entities.items()):
109
- if cat_idx >= max_categories:
110
- break
111
-
112
- # Main category node
113
- cat_node = f"CAT_{cat_idx}"
114
- G.add_node(cat_node,
115
- label=wrap_label(category, 18),
116
- shape="tab",
117
- fillcolor="#81D4FA",
118
- fontsize="22")
119
-
120
- G.add_edge("DOCUMENT", cat_node,
121
- label="contains",
122
- penwidth="3.0")
123
-
124
- # Add entities with grouping if needed
125
- if len(values) > max_entities:
126
- # Create subcategory groups
127
- for sub_idx, group in enumerate([values[i:i+max_entities]
128
- for i in range(0, len(values), max_entities)]):
129
- sub_node = f"SUB_{cat_idx}_{sub_idx}"
130
- G.add_node(sub_node,
131
- label=f"Group {sub_idx+1}",
132
- shape="folder",
133
- fillcolor="#B3E5FC")
134
- G.add_edge(cat_node, sub_node)
135
-
136
- for ent_idx, value in enumerate(group):
137
- ent_node = f"ENT_{cat_idx}_{sub_idx}_{ent_idx}"
138
- G.add_node(ent_node,
139
- label=wrap_label(value, 15),
140
- shape="note",
141
- fillcolor="#E1F5FE")
142
- G.add_edge(sub_node, ent_node)
143
- else:
144
- # Directly add entities
145
- for ent_idx, value in enumerate(values[:max_entities]):
146
- ent_node = f"ENT_{cat_idx}_{ent_idx}"
147
- G.add_node(ent_node,
148
- label=wrap_label(value, 15),
149
- shape="note",
150
- fillcolor="#E1F5FE")
151
- G.add_edge(cat_node, ent_node)
152
-
153
- # Generate output with multiple attempts
154
- for engine in ['dot', 'neato', 'sfdp']:
155
- try:
156
- G.draw(output_path,
157
- format="png",
158
- prog=engine,
159
- args=f"-Gdpi=300 -Gsize=50,50 -Goverlap=prism")
160
- print(f"Successfully generated with {engine}")
161
-
162
- # Verify the output
163
- if os.path.exists(output_path) and os.path.getsize(output_path) > 0:
164
- return output_path
165
-
166
- except Exception as e:
167
- print(f"Layout engine {engine} failed: {str(e)}")
168
- continue
169
-
170
- raise RuntimeError("All layout engines failed")
171
-
172
- except Exception as e:
173
- print(f"Mind map generation failed: {str(e)}")
174
- # Create error visualization
175
- try:
176
- import matplotlib.pyplot as plt
177
- plt.figure(figsize=(20, 10))
178
- plt.text(0.5, 0.5,
179
- f"Mind Map Generation Failed\n{str(e)}\n\nOriginal Text:\n{text[:200]}...",
180
- ha='center', va='center', wrap=True)
181
- plt.axis('off')
182
- error_path = os.path.join(temp_dir, "error_mindmap.png")
183
- plt.savefig(error_path, bbox_inches='tight', dpi=300)
184
- plt.close()
185
- return error_path
186
- except:
187
- return None
188
  @app.post("/summarize")
189
  def summarize_text(request: TextRequest):
190
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
@@ -223,16 +52,7 @@ def generate_word_cloud(request: TextRequest):
223
 
224
  # Gradio UI
225
  with gr.Blocks(theme=gr.themes.Soft(), css="""
226
- .mindmap-container img {
227
- max-height: none !important;
228
- min-width: 100% !important;
229
- object-fit: contain !important;
230
- background: white !important;
231
- border: 1px solid #e0e0e0 !important;
232
- border-radius: 8px !important;
233
- padding: 20px !important;
234
- }
235
- .gradio-container { max-width: 1400px !important; }
236
  """) as iface:
237
 
238
  gr.Markdown("# JFK Document Analysis Suite")
@@ -272,20 +92,7 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
272
  width=600
273
  )
274
 
275
- # Mind map section
276
- with gr.Row():
277
- mindmap_btn = gr.Button(
278
- "Generate Enhanced Mind Map",
279
- variant="primary"
280
- )
281
-
282
- with gr.Row():
283
- output_mindmap = gr.Image(
284
- label="High-Resolution Mind Map",
285
- elem_classes="mindmap-container",
286
- height=800,
287
- width=800
288
- )
289
 
290
  # Event handlers must be inside the Blocks context
291
  process_btn.click(
@@ -294,37 +101,6 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
294
  outputs=[full_doc_text, output_summary, output_entities, output_wordcloud]
295
  )
296
 
297
- def display_mindmap(text):
298
- try:
299
- img_path = generate_high_res_mindmap(text)
300
- if img_path and os.path.exists(img_path):
301
- return img_path
302
- return None
303
- except Exception as e:
304
- print(f"Display error: {e}")
305
- return None
306
-
307
- mindmap_btn.click(
308
- fn=display_mindmap,
309
- inputs=full_doc_text,
310
- outputs=output_mindmap,
311
- api_name="generate_mindmap",
312
- show_progress=True
313
- )
314
-
315
- # Add CSS for better image display
316
- css = """
317
- .mindmap-container img {
318
- max-width: 100% !important;
319
- height: auto !important;
320
- background: white !important;
321
- border: 2px solid #e0e0e0 !important;
322
- border-radius: 8px !important;
323
- padding: 10px !important;
324
- margin: 10px auto !important;
325
- display: block !important;
326
- }
327
- """
328
 
329
  if __name__ == "__main__":
330
  iface.launch(
 
6
  from wordcloud import WordCloud
7
  from summarization import summarizer
8
  from utils import list_files, process_file
 
 
9
 
10
  # Initialize FastAPI
11
  app = FastAPI()
 
14
  class TextRequest(BaseModel):
15
  text: str
16
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
  @app.post("/summarize")
18
  def summarize_text(request: TextRequest):
19
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
 
52
 
53
  # Gradio UI
54
  with gr.Blocks(theme=gr.themes.Soft(), css="""
55
+
 
 
 
 
 
 
 
 
 
56
  """) as iface:
57
 
58
  gr.Markdown("# JFK Document Analysis Suite")
 
92
  width=600
93
  )
94
 
95
+
 
 
 
 
 
 
 
 
 
 
 
 
 
96
 
97
  # Event handlers must be inside the Blocks context
98
  process_btn.click(
 
101
  outputs=[full_doc_text, output_summary, output_entities, output_wordcloud]
102
  )
103
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
104
 
105
  if __name__ == "__main__":
106
  iface.launch(
space/space/space/space/space/space/space/space/space/space/app.py CHANGED
@@ -6,8 +6,6 @@ from entity_recognition import extract_entities
6
  from wordcloud import WordCloud
7
  from summarization import summarizer
8
  from utils import list_files, process_file
9
- import pygraphviz as pgv
10
- import os
11
 
12
  # Initialize FastAPI
13
  app = FastAPI()
@@ -16,175 +14,6 @@ app = FastAPI()
16
  class TextRequest(BaseModel):
17
  text: str
18
 
19
- def wrap_label(label, max_length=15):
20
- """Improved label wrapping with hyphenation awareness"""
21
- if len(label) <= max_length:
22
- return label
23
-
24
- # Try to break at natural points
25
- break_chars = [" ", "-", "_", "/"]
26
- lines = []
27
- current = ""
28
-
29
- for char in label:
30
- if len(current) >= max_length and char in break_chars:
31
- lines.append(current.strip())
32
- current = char
33
- else:
34
- current += char
35
-
36
- if current:
37
- lines.append(current.strip())
38
-
39
- return "\\n".join(lines)
40
- def generate_high_res_mindmap(text):
41
- """Generate high-quality mind map with improved visibility"""
42
- try:
43
- # Verify we have entities to visualize
44
- entities = extract_entities(text)
45
- if not any(entities.values()):
46
- print("No entities found to generate mind map")
47
- return None
48
-
49
- # Create temporary directory
50
- temp_dir = "/tmp/mindmaps"
51
- os.makedirs(temp_dir, exist_ok=True)
52
- output_path = os.path.join(temp_dir, "mindmap.png")
53
-
54
- # Create graph with optimized settings
55
- G = pgv.AGraph(
56
- directed=True,
57
- rankdir="TB", # Top-to-bottom layout
58
- bgcolor="white",
59
- fontname="Arial", # More readable font
60
- splines="ortho", # Straight lines
61
- overlap="false",
62
- concentrate="true",
63
- ratio="compress",
64
- size="50,50", # Larger canvas
65
- dpi="1000", # Higher resolution
66
- pad="1.0",
67
- nodesep="1.2", # More space between nodes
68
- ranksep="1.5" # More vertical space
69
- )
70
-
71
- # Enhanced node styling for better visibility
72
- G.node_attr.update({
73
- "fontsize": "24", # Larger font
74
- "fontname": "Arial Bold",
75
- "shape": "box",
76
- "style": "rounded,filled",
77
- "fillcolor": "#E1F5FE",
78
- "color": "#0288D1",
79
- "height": "0.8",
80
- "width": "2.0",
81
- "penwidth": "2.0",
82
- "margin": "0.3,0.1" # Better text padding
83
- })
84
-
85
- # Enhanced edge styling
86
- G.edge_attr.update({
87
- "color": "#616161",
88
- "penwidth": "2.5",
89
- "arrowsize": "1.2",
90
- "fontname": "Arial",
91
- "fontsize": "20",
92
- "fontcolor": "#424242"
93
- })
94
-
95
- # Add central node with improved styling
96
- G.add_node("DOCUMENT",
97
- shape="doubleoctagon",
98
- fillcolor="#4FC3F7",
99
- fontsize="28",
100
- width="2.5",
101
- height="1.0",
102
- penwidth="3.0")
103
-
104
- # Add entities with better spacing
105
- max_categories = 5
106
- max_entities = 8
107
-
108
- for cat_idx, (category, values) in enumerate(entities.items()):
109
- if cat_idx >= max_categories:
110
- break
111
-
112
- # Main category node
113
- cat_node = f"CAT_{cat_idx}"
114
- G.add_node(cat_node,
115
- label=wrap_label(category, 18),
116
- shape="tab",
117
- fillcolor="#81D4FA",
118
- fontsize="22")
119
-
120
- G.add_edge("DOCUMENT", cat_node,
121
- label="contains",
122
- penwidth="3.0")
123
-
124
- # Add entities with grouping if needed
125
- if len(values) > max_entities:
126
- # Create subcategory groups
127
- for sub_idx, group in enumerate([values[i:i+max_entities]
128
- for i in range(0, len(values), max_entities)]):
129
- sub_node = f"SUB_{cat_idx}_{sub_idx}"
130
- G.add_node(sub_node,
131
- label=f"Group {sub_idx+1}",
132
- shape="folder",
133
- fillcolor="#B3E5FC")
134
- G.add_edge(cat_node, sub_node)
135
-
136
- for ent_idx, value in enumerate(group):
137
- ent_node = f"ENT_{cat_idx}_{sub_idx}_{ent_idx}"
138
- G.add_node(ent_node,
139
- label=wrap_label(value, 15),
140
- shape="note",
141
- fillcolor="#E1F5FE")
142
- G.add_edge(sub_node, ent_node)
143
- else:
144
- # Directly add entities
145
- for ent_idx, value in enumerate(values[:max_entities]):
146
- ent_node = f"ENT_{cat_idx}_{ent_idx}"
147
- G.add_node(ent_node,
148
- label=wrap_label(value, 15),
149
- shape="note",
150
- fillcolor="#E1F5FE")
151
- G.add_edge(cat_node, ent_node)
152
-
153
- # Generate output with multiple attempts
154
- for engine in ['dot', 'neato', 'sfdp']:
155
- try:
156
- G.draw(output_path,
157
- format="png",
158
- prog=engine,
159
- args=f"-Gdpi=300 -Gsize=50,50 -Goverlap=prism")
160
- print(f"Successfully generated with {engine}")
161
-
162
- # Verify the output
163
- if os.path.exists(output_path) and os.path.getsize(output_path) > 0:
164
- return output_path
165
-
166
- except Exception as e:
167
- print(f"Layout engine {engine} failed: {str(e)}")
168
- continue
169
-
170
- raise RuntimeError("All layout engines failed")
171
-
172
- except Exception as e:
173
- print(f"Mind map generation failed: {str(e)}")
174
- # Create error visualization
175
- try:
176
- import matplotlib.pyplot as plt
177
- plt.figure(figsize=(20, 10))
178
- plt.text(0.5, 0.5,
179
- f"Mind Map Generation Failed\n{str(e)}\n\nOriginal Text:\n{text[:200]}...",
180
- ha='center', va='center', wrap=True)
181
- plt.axis('off')
182
- error_path = os.path.join(temp_dir, "error_mindmap.png")
183
- plt.savefig(error_path, bbox_inches='tight', dpi=300)
184
- plt.close()
185
- return error_path
186
- except:
187
- return None
188
  @app.post("/summarize")
189
  def summarize_text(request: TextRequest):
190
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
@@ -223,16 +52,7 @@ def generate_word_cloud(request: TextRequest):
223
 
224
  # Gradio UI
225
  with gr.Blocks(theme=gr.themes.Soft(), css="""
226
- .mindmap-container img {
227
- max-height: none !important;
228
- min-width: 100% !important;
229
- object-fit: contain !important;
230
- background: white !important;
231
- border: 1px solid #e0e0e0 !important;
232
- border-radius: 8px !important;
233
- padding: 20px !important;
234
- }
235
- .gradio-container { max-width: 1400px !important; }
236
  """) as iface:
237
 
238
  gr.Markdown("# JFK Document Analysis Suite")
@@ -272,20 +92,7 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
272
  width=600
273
  )
274
 
275
- # Mind map section
276
- with gr.Row():
277
- mindmap_btn = gr.Button(
278
- "Generate Enhanced Mind Map",
279
- variant="primary"
280
- )
281
-
282
- with gr.Row():
283
- output_mindmap = gr.Image(
284
- label="High-Resolution Mind Map",
285
- elem_classes="mindmap-container",
286
- height=800,
287
- width=800
288
- )
289
 
290
  # Event handlers must be inside the Blocks context
291
  process_btn.click(
@@ -294,37 +101,6 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
294
  outputs=[full_doc_text, output_summary, output_entities, output_wordcloud]
295
  )
296
 
297
- def display_mindmap(text):
298
- try:
299
- img_path = generate_high_res_mindmap(text)
300
- if img_path and os.path.exists(img_path):
301
- return img_path
302
- return None
303
- except Exception as e:
304
- print(f"Display error: {e}")
305
- return None
306
-
307
- mindmap_btn.click(
308
- fn=display_mindmap,
309
- inputs=full_doc_text,
310
- outputs=output_mindmap,
311
- api_name="generate_mindmap",
312
- show_progress=True
313
- )
314
-
315
- # Add CSS for better image display
316
- css = """
317
- .mindmap-container img {
318
- max-width: 100% !important;
319
- height: auto !important;
320
- background: white !important;
321
- border: 2px solid #e0e0e0 !important;
322
- border-radius: 8px !important;
323
- padding: 10px !important;
324
- margin: 10px auto !important;
325
- display: block !important;
326
- }
327
- """
328
 
329
  if __name__ == "__main__":
330
  iface.launch(
 
6
  from wordcloud import WordCloud
7
  from summarization import summarizer
8
  from utils import list_files, process_file
 
 
9
 
10
  # Initialize FastAPI
11
  app = FastAPI()
 
14
  class TextRequest(BaseModel):
15
  text: str
16
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
  @app.post("/summarize")
18
  def summarize_text(request: TextRequest):
19
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
 
52
 
53
  # Gradio UI
54
  with gr.Blocks(theme=gr.themes.Soft(), css="""
55
+
 
 
 
 
 
 
 
 
 
56
  """) as iface:
57
 
58
  gr.Markdown("# JFK Document Analysis Suite")
 
92
  width=600
93
  )
94
 
95
+
 
 
 
 
 
 
 
 
 
 
 
 
 
96
 
97
  # Event handlers must be inside the Blocks context
98
  process_btn.click(
 
101
  outputs=[full_doc_text, output_summary, output_entities, output_wordcloud]
102
  )
103
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
104
 
105
  if __name__ == "__main__":
106
  iface.launch(
space/space/space/space/space/space/space/space/space/space/space/app.py CHANGED
@@ -6,8 +6,6 @@ from entity_recognition import extract_entities
6
  from wordcloud import WordCloud
7
  from summarization import summarizer
8
  from utils import list_files, process_file
9
- import pygraphviz as pgv
10
- import os
11
 
12
  # Initialize FastAPI
13
  app = FastAPI()
@@ -16,175 +14,6 @@ app = FastAPI()
16
  class TextRequest(BaseModel):
17
  text: str
18
 
19
- def wrap_label(label, max_length=15):
20
- """Improved label wrapping with hyphenation awareness"""
21
- if len(label) <= max_length:
22
- return label
23
-
24
- # Try to break at natural points
25
- break_chars = [" ", "-", "_", "/"]
26
- lines = []
27
- current = ""
28
-
29
- for char in label:
30
- if len(current) >= max_length and char in break_chars:
31
- lines.append(current.strip())
32
- current = char
33
- else:
34
- current += char
35
-
36
- if current:
37
- lines.append(current.strip())
38
-
39
- return "\\n".join(lines)
40
- def generate_high_res_mindmap(text):
41
- """Generate high-quality mind map with improved visibility"""
42
- try:
43
- # Verify we have entities to visualize
44
- entities = extract_entities(text)
45
- if not any(entities.values()):
46
- print("No entities found to generate mind map")
47
- return None
48
-
49
- # Create temporary directory
50
- temp_dir = "/tmp/mindmaps"
51
- os.makedirs(temp_dir, exist_ok=True)
52
- output_path = os.path.join(temp_dir, "mindmap.png")
53
-
54
- # Create graph with optimized settings
55
- G = pgv.AGraph(
56
- directed=True,
57
- rankdir="TB", # Top-to-bottom layout
58
- bgcolor="white",
59
- fontname="Arial", # More readable font
60
- splines="ortho", # Straight lines
61
- overlap="false",
62
- concentrate="true",
63
- ratio="compress",
64
- size="50,50", # Larger canvas
65
- dpi="1000", # Higher resolution
66
- pad="1.0",
67
- nodesep="1.2", # More space between nodes
68
- ranksep="1.5" # More vertical space
69
- )
70
-
71
- # Enhanced node styling for better visibility
72
- G.node_attr.update({
73
- "fontsize": "24", # Larger font
74
- "fontname": "Arial Bold",
75
- "shape": "box",
76
- "style": "rounded,filled",
77
- "fillcolor": "#E1F5FE",
78
- "color": "#0288D1",
79
- "height": "0.8",
80
- "width": "2.0",
81
- "penwidth": "2.0",
82
- "margin": "0.3,0.1" # Better text padding
83
- })
84
-
85
- # Enhanced edge styling
86
- G.edge_attr.update({
87
- "color": "#616161",
88
- "penwidth": "2.5",
89
- "arrowsize": "1.2",
90
- "fontname": "Arial",
91
- "fontsize": "20",
92
- "fontcolor": "#424242"
93
- })
94
-
95
- # Add central node with improved styling
96
- G.add_node("DOCUMENT",
97
- shape="doubleoctagon",
98
- fillcolor="#4FC3F7",
99
- fontsize="28",
100
- width="2.5",
101
- height="1.0",
102
- penwidth="3.0")
103
-
104
- # Add entities with better spacing
105
- max_categories = 5
106
- max_entities = 8
107
-
108
- for cat_idx, (category, values) in enumerate(entities.items()):
109
- if cat_idx >= max_categories:
110
- break
111
-
112
- # Main category node
113
- cat_node = f"CAT_{cat_idx}"
114
- G.add_node(cat_node,
115
- label=wrap_label(category, 18),
116
- shape="tab",
117
- fillcolor="#81D4FA",
118
- fontsize="22")
119
-
120
- G.add_edge("DOCUMENT", cat_node,
121
- label="contains",
122
- penwidth="3.0")
123
-
124
- # Add entities with grouping if needed
125
- if len(values) > max_entities:
126
- # Create subcategory groups
127
- for sub_idx, group in enumerate([values[i:i+max_entities]
128
- for i in range(0, len(values), max_entities)]):
129
- sub_node = f"SUB_{cat_idx}_{sub_idx}"
130
- G.add_node(sub_node,
131
- label=f"Group {sub_idx+1}",
132
- shape="folder",
133
- fillcolor="#B3E5FC")
134
- G.add_edge(cat_node, sub_node)
135
-
136
- for ent_idx, value in enumerate(group):
137
- ent_node = f"ENT_{cat_idx}_{sub_idx}_{ent_idx}"
138
- G.add_node(ent_node,
139
- label=wrap_label(value, 15),
140
- shape="note",
141
- fillcolor="#E1F5FE")
142
- G.add_edge(sub_node, ent_node)
143
- else:
144
- # Directly add entities
145
- for ent_idx, value in enumerate(values[:max_entities]):
146
- ent_node = f"ENT_{cat_idx}_{ent_idx}"
147
- G.add_node(ent_node,
148
- label=wrap_label(value, 15),
149
- shape="note",
150
- fillcolor="#E1F5FE")
151
- G.add_edge(cat_node, ent_node)
152
-
153
- # Generate output with multiple attempts
154
- for engine in ['dot', 'neato', 'sfdp']:
155
- try:
156
- G.draw(output_path,
157
- format="png",
158
- prog=engine,
159
- args=f"-Gdpi=300 -Gsize=50,50 -Goverlap=prism")
160
- print(f"Successfully generated with {engine}")
161
-
162
- # Verify the output
163
- if os.path.exists(output_path) and os.path.getsize(output_path) > 0:
164
- return output_path
165
-
166
- except Exception as e:
167
- print(f"Layout engine {engine} failed: {str(e)}")
168
- continue
169
-
170
- raise RuntimeError("All layout engines failed")
171
-
172
- except Exception as e:
173
- print(f"Mind map generation failed: {str(e)}")
174
- # Create error visualization
175
- try:
176
- import matplotlib.pyplot as plt
177
- plt.figure(figsize=(20, 10))
178
- plt.text(0.5, 0.5,
179
- f"Mind Map Generation Failed\n{str(e)}\n\nOriginal Text:\n{text[:200]}...",
180
- ha='center', va='center', wrap=True)
181
- plt.axis('off')
182
- error_path = os.path.join(temp_dir, "error_mindmap.png")
183
- plt.savefig(error_path, bbox_inches='tight', dpi=300)
184
- plt.close()
185
- return error_path
186
- except:
187
- return None
188
  @app.post("/summarize")
189
  def summarize_text(request: TextRequest):
190
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
@@ -223,16 +52,7 @@ def generate_word_cloud(request: TextRequest):
223
 
224
  # Gradio UI
225
  with gr.Blocks(theme=gr.themes.Soft(), css="""
226
- .mindmap-container img {
227
- max-height: none !important;
228
- min-width: 100% !important;
229
- object-fit: contain !important;
230
- background: white !important;
231
- border: 1px solid #e0e0e0 !important;
232
- border-radius: 8px !important;
233
- padding: 20px !important;
234
- }
235
- .gradio-container { max-width: 1400px !important; }
236
  """) as iface:
237
 
238
  gr.Markdown("# JFK Document Analysis Suite")
@@ -272,20 +92,7 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
272
  width=600
273
  )
274
 
275
- # Mind map section
276
- with gr.Row():
277
- mindmap_btn = gr.Button(
278
- "Generate Enhanced Mind Map",
279
- variant="primary"
280
- )
281
-
282
- with gr.Row():
283
- output_mindmap = gr.Image(
284
- label="High-Resolution Mind Map",
285
- elem_classes="mindmap-container",
286
- height=800,
287
- width=800
288
- )
289
 
290
  # Event handlers must be inside the Blocks context
291
  process_btn.click(
@@ -294,37 +101,6 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
294
  outputs=[full_doc_text, output_summary, output_entities, output_wordcloud]
295
  )
296
 
297
- def display_mindmap(text):
298
- try:
299
- img_path = generate_high_res_mindmap(text)
300
- if img_path and os.path.exists(img_path):
301
- return img_path
302
- return None
303
- except Exception as e:
304
- print(f"Display error: {e}")
305
- return None
306
-
307
- mindmap_btn.click(
308
- fn=display_mindmap,
309
- inputs=full_doc_text,
310
- outputs=output_mindmap,
311
- api_name="generate_mindmap",
312
- show_progress=True
313
- )
314
-
315
- # Add CSS for better image display
316
- css = """
317
- .mindmap-container img {
318
- max-width: 100% !important;
319
- height: auto !important;
320
- background: white !important;
321
- border: 2px solid #e0e0e0 !important;
322
- border-radius: 8px !important;
323
- padding: 10px !important;
324
- margin: 10px auto !important;
325
- display: block !important;
326
- }
327
- """
328
 
329
  if __name__ == "__main__":
330
  iface.launch(
 
6
  from wordcloud import WordCloud
7
  from summarization import summarizer
8
  from utils import list_files, process_file
 
 
9
 
10
  # Initialize FastAPI
11
  app = FastAPI()
 
14
  class TextRequest(BaseModel):
15
  text: str
16
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
  @app.post("/summarize")
18
  def summarize_text(request: TextRequest):
19
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
 
52
 
53
  # Gradio UI
54
  with gr.Blocks(theme=gr.themes.Soft(), css="""
55
+
 
 
 
 
 
 
 
 
 
56
  """) as iface:
57
 
58
  gr.Markdown("# JFK Document Analysis Suite")
 
92
  width=600
93
  )
94
 
95
+
 
 
 
 
 
 
 
 
 
 
 
 
 
96
 
97
  # Event handlers must be inside the Blocks context
98
  process_btn.click(
 
101
  outputs=[full_doc_text, output_summary, output_entities, output_wordcloud]
102
  )
103
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
104
 
105
  if __name__ == "__main__":
106
  iface.launch(
space/space/space/space/space/space/space/space/space/space/space/space/app.py CHANGED
@@ -6,8 +6,6 @@ from entity_recognition import extract_entities
6
  from wordcloud import WordCloud
7
  from summarization import summarizer
8
  from utils import list_files, process_file
9
- import pygraphviz as pgv
10
- import os
11
 
12
  # Initialize FastAPI
13
  app = FastAPI()
@@ -16,175 +14,6 @@ app = FastAPI()
16
  class TextRequest(BaseModel):
17
  text: str
18
 
19
- def wrap_label(label, max_length=15):
20
- """Improved label wrapping with hyphenation awareness"""
21
- if len(label) <= max_length:
22
- return label
23
-
24
- # Try to break at natural points
25
- break_chars = [" ", "-", "_", "/"]
26
- lines = []
27
- current = ""
28
-
29
- for char in label:
30
- if len(current) >= max_length and char in break_chars:
31
- lines.append(current.strip())
32
- current = char
33
- else:
34
- current += char
35
-
36
- if current:
37
- lines.append(current.strip())
38
-
39
- return "\\n".join(lines)
40
- def generate_high_res_mindmap(text):
41
- """Generate high-quality mind map with improved visibility"""
42
- try:
43
- # Verify we have entities to visualize
44
- entities = extract_entities(text)
45
- if not any(entities.values()):
46
- print("No entities found to generate mind map")
47
- return None
48
-
49
- # Create temporary directory
50
- temp_dir = "/tmp/mindmaps"
51
- os.makedirs(temp_dir, exist_ok=True)
52
- output_path = os.path.join(temp_dir, "mindmap.png")
53
-
54
- # Create graph with optimized settings
55
- G = pgv.AGraph(
56
- directed=True,
57
- rankdir="TB", # Top-to-bottom layout
58
- bgcolor="white",
59
- fontname="Arial", # More readable font
60
- splines="ortho", # Straight lines
61
- overlap="false",
62
- concentrate="true",
63
- ratio="compress",
64
- size="50,50", # Larger canvas
65
- dpi="1000", # Higher resolution
66
- pad="1.0",
67
- nodesep="1.2", # More space between nodes
68
- ranksep="1.5" # More vertical space
69
- )
70
-
71
- # Enhanced node styling for better visibility
72
- G.node_attr.update({
73
- "fontsize": "24", # Larger font
74
- "fontname": "Arial Bold",
75
- "shape": "box",
76
- "style": "rounded,filled",
77
- "fillcolor": "#E1F5FE",
78
- "color": "#0288D1",
79
- "height": "0.8",
80
- "width": "2.0",
81
- "penwidth": "2.0",
82
- "margin": "0.3,0.1" # Better text padding
83
- })
84
-
85
- # Enhanced edge styling
86
- G.edge_attr.update({
87
- "color": "#616161",
88
- "penwidth": "2.5",
89
- "arrowsize": "1.2",
90
- "fontname": "Arial",
91
- "fontsize": "20",
92
- "fontcolor": "#424242"
93
- })
94
-
95
- # Add central node with improved styling
96
- G.add_node("DOCUMENT",
97
- shape="doubleoctagon",
98
- fillcolor="#4FC3F7",
99
- fontsize="28",
100
- width="2.5",
101
- height="1.0",
102
- penwidth="3.0")
103
-
104
- # Add entities with better spacing
105
- max_categories = 5
106
- max_entities = 8
107
-
108
- for cat_idx, (category, values) in enumerate(entities.items()):
109
- if cat_idx >= max_categories:
110
- break
111
-
112
- # Main category node
113
- cat_node = f"CAT_{cat_idx}"
114
- G.add_node(cat_node,
115
- label=wrap_label(category, 18),
116
- shape="tab",
117
- fillcolor="#81D4FA",
118
- fontsize="22")
119
-
120
- G.add_edge("DOCUMENT", cat_node,
121
- label="contains",
122
- penwidth="3.0")
123
-
124
- # Add entities with grouping if needed
125
- if len(values) > max_entities:
126
- # Create subcategory groups
127
- for sub_idx, group in enumerate([values[i:i+max_entities]
128
- for i in range(0, len(values), max_entities)]):
129
- sub_node = f"SUB_{cat_idx}_{sub_idx}"
130
- G.add_node(sub_node,
131
- label=f"Group {sub_idx+1}",
132
- shape="folder",
133
- fillcolor="#B3E5FC")
134
- G.add_edge(cat_node, sub_node)
135
-
136
- for ent_idx, value in enumerate(group):
137
- ent_node = f"ENT_{cat_idx}_{sub_idx}_{ent_idx}"
138
- G.add_node(ent_node,
139
- label=wrap_label(value, 15),
140
- shape="note",
141
- fillcolor="#E1F5FE")
142
- G.add_edge(sub_node, ent_node)
143
- else:
144
- # Directly add entities
145
- for ent_idx, value in enumerate(values[:max_entities]):
146
- ent_node = f"ENT_{cat_idx}_{ent_idx}"
147
- G.add_node(ent_node,
148
- label=wrap_label(value, 15),
149
- shape="note",
150
- fillcolor="#E1F5FE")
151
- G.add_edge(cat_node, ent_node)
152
-
153
- # Generate output with multiple attempts
154
- for engine in ['dot', 'neato', 'sfdp']:
155
- try:
156
- G.draw(output_path,
157
- format="png",
158
- prog=engine,
159
- args=f"-Gdpi=300 -Gsize=50,50 -Goverlap=prism")
160
- print(f"Successfully generated with {engine}")
161
-
162
- # Verify the output
163
- if os.path.exists(output_path) and os.path.getsize(output_path) > 0:
164
- return output_path
165
-
166
- except Exception as e:
167
- print(f"Layout engine {engine} failed: {str(e)}")
168
- continue
169
-
170
- raise RuntimeError("All layout engines failed")
171
-
172
- except Exception as e:
173
- print(f"Mind map generation failed: {str(e)}")
174
- # Create error visualization
175
- try:
176
- import matplotlib.pyplot as plt
177
- plt.figure(figsize=(20, 10))
178
- plt.text(0.5, 0.5,
179
- f"Mind Map Generation Failed\n{str(e)}\n\nOriginal Text:\n{text[:200]}...",
180
- ha='center', va='center', wrap=True)
181
- plt.axis('off')
182
- error_path = os.path.join(temp_dir, "error_mindmap.png")
183
- plt.savefig(error_path, bbox_inches='tight', dpi=300)
184
- plt.close()
185
- return error_path
186
- except:
187
- return None
188
  @app.post("/summarize")
189
  def summarize_text(request: TextRequest):
190
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
@@ -223,16 +52,7 @@ def generate_word_cloud(request: TextRequest):
223
 
224
  # Gradio UI
225
  with gr.Blocks(theme=gr.themes.Soft(), css="""
226
- .mindmap-container img {
227
- max-height: none !important;
228
- min-width: 100% !important;
229
- object-fit: contain !important;
230
- background: white !important;
231
- border: 1px solid #e0e0e0 !important;
232
- border-radius: 8px !important;
233
- padding: 20px !important;
234
- }
235
- .gradio-container { max-width: 1400px !important; }
236
  """) as iface:
237
 
238
  gr.Markdown("# JFK Document Analysis Suite")
@@ -272,20 +92,7 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
272
  width=600
273
  )
274
 
275
- # Mind map section
276
- with gr.Row():
277
- mindmap_btn = gr.Button(
278
- "Generate Enhanced Mind Map",
279
- variant="primary"
280
- )
281
-
282
- with gr.Row():
283
- output_mindmap = gr.Image(
284
- label="High-Resolution Mind Map",
285
- elem_classes="mindmap-container",
286
- height=800,
287
- width=800
288
- )
289
 
290
  # Event handlers must be inside the Blocks context
291
  process_btn.click(
@@ -294,37 +101,6 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
294
  outputs=[full_doc_text, output_summary, output_entities, output_wordcloud]
295
  )
296
 
297
- def display_mindmap(text):
298
- try:
299
- img_path = generate_high_res_mindmap(text)
300
- if img_path and os.path.exists(img_path):
301
- return img_path
302
- return None
303
- except Exception as e:
304
- print(f"Display error: {e}")
305
- return None
306
-
307
- mindmap_btn.click(
308
- fn=display_mindmap,
309
- inputs=full_doc_text,
310
- outputs=output_mindmap,
311
- api_name="generate_mindmap",
312
- show_progress=True
313
- )
314
-
315
- # Add CSS for better image display
316
- css = """
317
- .mindmap-container img {
318
- max-width: 100% !important;
319
- height: auto !important;
320
- background: white !important;
321
- border: 2px solid #e0e0e0 !important;
322
- border-radius: 8px !important;
323
- padding: 10px !important;
324
- margin: 10px auto !important;
325
- display: block !important;
326
- }
327
- """
328
 
329
  if __name__ == "__main__":
330
  iface.launch(
 
6
  from wordcloud import WordCloud
7
  from summarization import summarizer
8
  from utils import list_files, process_file
 
 
9
 
10
  # Initialize FastAPI
11
  app = FastAPI()
 
14
  class TextRequest(BaseModel):
15
  text: str
16
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
  @app.post("/summarize")
18
  def summarize_text(request: TextRequest):
19
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
 
52
 
53
  # Gradio UI
54
  with gr.Blocks(theme=gr.themes.Soft(), css="""
55
+
 
 
 
 
 
 
 
 
 
56
  """) as iface:
57
 
58
  gr.Markdown("# JFK Document Analysis Suite")
 
92
  width=600
93
  )
94
 
95
+
 
 
 
 
 
 
 
 
 
 
 
 
 
96
 
97
  # Event handlers must be inside the Blocks context
98
  process_btn.click(
 
101
  outputs=[full_doc_text, output_summary, output_entities, output_wordcloud]
102
  )
103
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
104
 
105
  if __name__ == "__main__":
106
  iface.launch(
space/space/space/space/space/space/space/space/space/space/space/space/space/app.py CHANGED
@@ -6,8 +6,6 @@ from entity_recognition import extract_entities
6
  from wordcloud import WordCloud
7
  from summarization import summarizer
8
  from utils import list_files, process_file
9
- import pygraphviz as pgv
10
- import os
11
 
12
  # Initialize FastAPI
13
  app = FastAPI()
@@ -16,175 +14,6 @@ app = FastAPI()
16
  class TextRequest(BaseModel):
17
  text: str
18
 
19
- def wrap_label(label, max_length=15):
20
- """Improved label wrapping with hyphenation awareness"""
21
- if len(label) <= max_length:
22
- return label
23
-
24
- # Try to break at natural points
25
- break_chars = [" ", "-", "_", "/"]
26
- lines = []
27
- current = ""
28
-
29
- for char in label:
30
- if len(current) >= max_length and char in break_chars:
31
- lines.append(current.strip())
32
- current = char
33
- else:
34
- current += char
35
-
36
- if current:
37
- lines.append(current.strip())
38
-
39
- return "\\n".join(lines)
40
- def generate_high_res_mindmap(text):
41
- """Generate high-quality mind map with improved visibility"""
42
- try:
43
- # Verify we have entities to visualize
44
- entities = extract_entities(text)
45
- if not any(entities.values()):
46
- print("No entities found to generate mind map")
47
- return None
48
-
49
- # Create temporary directory
50
- temp_dir = "/tmp/mindmaps"
51
- os.makedirs(temp_dir, exist_ok=True)
52
- output_path = os.path.join(temp_dir, "mindmap.png")
53
-
54
- # Create graph with optimized settings
55
- G = pgv.AGraph(
56
- directed=True,
57
- rankdir="TB", # Top-to-bottom layout
58
- bgcolor="white",
59
- fontname="Arial", # More readable font
60
- splines="ortho", # Straight lines
61
- overlap="false",
62
- concentrate="true",
63
- ratio="compress",
64
- size="50,50", # Larger canvas
65
- dpi="1000", # Higher resolution
66
- pad="1.0",
67
- nodesep="1.2", # More space between nodes
68
- ranksep="1.5" # More vertical space
69
- )
70
-
71
- # Enhanced node styling for better visibility
72
- G.node_attr.update({
73
- "fontsize": "24", # Larger font
74
- "fontname": "Arial Bold",
75
- "shape": "box",
76
- "style": "rounded,filled",
77
- "fillcolor": "#E1F5FE",
78
- "color": "#0288D1",
79
- "height": "0.8",
80
- "width": "2.0",
81
- "penwidth": "2.0",
82
- "margin": "0.3,0.1" # Better text padding
83
- })
84
-
85
- # Enhanced edge styling
86
- G.edge_attr.update({
87
- "color": "#616161",
88
- "penwidth": "2.5",
89
- "arrowsize": "1.2",
90
- "fontname": "Arial",
91
- "fontsize": "20",
92
- "fontcolor": "#424242"
93
- })
94
-
95
- # Add central node with improved styling
96
- G.add_node("DOCUMENT",
97
- shape="doubleoctagon",
98
- fillcolor="#4FC3F7",
99
- fontsize="28",
100
- width="2.5",
101
- height="1.0",
102
- penwidth="3.0")
103
-
104
- # Add entities with better spacing
105
- max_categories = 5
106
- max_entities = 8
107
-
108
- for cat_idx, (category, values) in enumerate(entities.items()):
109
- if cat_idx >= max_categories:
110
- break
111
-
112
- # Main category node
113
- cat_node = f"CAT_{cat_idx}"
114
- G.add_node(cat_node,
115
- label=wrap_label(category, 18),
116
- shape="tab",
117
- fillcolor="#81D4FA",
118
- fontsize="22")
119
-
120
- G.add_edge("DOCUMENT", cat_node,
121
- label="contains",
122
- penwidth="3.0")
123
-
124
- # Add entities with grouping if needed
125
- if len(values) > max_entities:
126
- # Create subcategory groups
127
- for sub_idx, group in enumerate([values[i:i+max_entities]
128
- for i in range(0, len(values), max_entities)]):
129
- sub_node = f"SUB_{cat_idx}_{sub_idx}"
130
- G.add_node(sub_node,
131
- label=f"Group {sub_idx+1}",
132
- shape="folder",
133
- fillcolor="#B3E5FC")
134
- G.add_edge(cat_node, sub_node)
135
-
136
- for ent_idx, value in enumerate(group):
137
- ent_node = f"ENT_{cat_idx}_{sub_idx}_{ent_idx}"
138
- G.add_node(ent_node,
139
- label=wrap_label(value, 15),
140
- shape="note",
141
- fillcolor="#E1F5FE")
142
- G.add_edge(sub_node, ent_node)
143
- else:
144
- # Directly add entities
145
- for ent_idx, value in enumerate(values[:max_entities]):
146
- ent_node = f"ENT_{cat_idx}_{ent_idx}"
147
- G.add_node(ent_node,
148
- label=wrap_label(value, 15),
149
- shape="note",
150
- fillcolor="#E1F5FE")
151
- G.add_edge(cat_node, ent_node)
152
-
153
- # Generate output with multiple attempts
154
- for engine in ['dot', 'neato', 'sfdp']:
155
- try:
156
- G.draw(output_path,
157
- format="png",
158
- prog=engine,
159
- args=f"-Gdpi=300 -Gsize=50,50 -Goverlap=prism")
160
- print(f"Successfully generated with {engine}")
161
-
162
- # Verify the output
163
- if os.path.exists(output_path) and os.path.getsize(output_path) > 0:
164
- return output_path
165
-
166
- except Exception as e:
167
- print(f"Layout engine {engine} failed: {str(e)}")
168
- continue
169
-
170
- raise RuntimeError("All layout engines failed")
171
-
172
- except Exception as e:
173
- print(f"Mind map generation failed: {str(e)}")
174
- # Create error visualization
175
- try:
176
- import matplotlib.pyplot as plt
177
- plt.figure(figsize=(20, 10))
178
- plt.text(0.5, 0.5,
179
- f"Mind Map Generation Failed\n{str(e)}\n\nOriginal Text:\n{text[:200]}...",
180
- ha='center', va='center', wrap=True)
181
- plt.axis('off')
182
- error_path = os.path.join(temp_dir, "error_mindmap.png")
183
- plt.savefig(error_path, bbox_inches='tight', dpi=300)
184
- plt.close()
185
- return error_path
186
- except:
187
- return None
188
  @app.post("/summarize")
189
  def summarize_text(request: TextRequest):
190
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
@@ -223,16 +52,7 @@ def generate_word_cloud(request: TextRequest):
223
 
224
  # Gradio UI
225
  with gr.Blocks(theme=gr.themes.Soft(), css="""
226
- .mindmap-container img {
227
- max-height: none !important;
228
- min-width: 100% !important;
229
- object-fit: contain !important;
230
- background: white !important;
231
- border: 1px solid #e0e0e0 !important;
232
- border-radius: 8px !important;
233
- padding: 20px !important;
234
- }
235
- .gradio-container { max-width: 1400px !important; }
236
  """) as iface:
237
 
238
  gr.Markdown("# JFK Document Analysis Suite")
@@ -272,20 +92,7 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
272
  width=600
273
  )
274
 
275
- # Mind map section
276
- with gr.Row():
277
- mindmap_btn = gr.Button(
278
- "Generate Enhanced Mind Map",
279
- variant="primary"
280
- )
281
-
282
- with gr.Row():
283
- output_mindmap = gr.Image(
284
- label="High-Resolution Mind Map",
285
- elem_classes="mindmap-container",
286
- height=800,
287
- width=800
288
- )
289
 
290
  # Event handlers must be inside the Blocks context
291
  process_btn.click(
@@ -294,37 +101,6 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
294
  outputs=[full_doc_text, output_summary, output_entities, output_wordcloud]
295
  )
296
 
297
- def display_mindmap(text):
298
- try:
299
- img_path = generate_high_res_mindmap(text)
300
- if img_path and os.path.exists(img_path):
301
- return img_path
302
- return None
303
- except Exception as e:
304
- print(f"Display error: {e}")
305
- return None
306
-
307
- mindmap_btn.click(
308
- fn=display_mindmap,
309
- inputs=full_doc_text,
310
- outputs=output_mindmap,
311
- api_name="generate_mindmap",
312
- show_progress=True
313
- )
314
-
315
- # Add CSS for better image display
316
- css = """
317
- .mindmap-container img {
318
- max-width: 100% !important;
319
- height: auto !important;
320
- background: white !important;
321
- border: 2px solid #e0e0e0 !important;
322
- border-radius: 8px !important;
323
- padding: 10px !important;
324
- margin: 10px auto !important;
325
- display: block !important;
326
- }
327
- """
328
 
329
  if __name__ == "__main__":
330
  iface.launch(
 
6
  from wordcloud import WordCloud
7
  from summarization import summarizer
8
  from utils import list_files, process_file
 
 
9
 
10
  # Initialize FastAPI
11
  app = FastAPI()
 
14
  class TextRequest(BaseModel):
15
  text: str
16
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
  @app.post("/summarize")
18
  def summarize_text(request: TextRequest):
19
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
 
52
 
53
  # Gradio UI
54
  with gr.Blocks(theme=gr.themes.Soft(), css="""
55
+
 
 
 
 
 
 
 
 
 
56
  """) as iface:
57
 
58
  gr.Markdown("# JFK Document Analysis Suite")
 
92
  width=600
93
  )
94
 
95
+
 
 
 
 
 
 
 
 
 
 
 
 
 
96
 
97
  # Event handlers must be inside the Blocks context
98
  process_btn.click(
 
101
  outputs=[full_doc_text, output_summary, output_entities, output_wordcloud]
102
  )
103
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
104
 
105
  if __name__ == "__main__":
106
  iface.launch(
space/space/space/space/space/space/space/space/space/space/space/space/space/space/app.py CHANGED
@@ -6,8 +6,6 @@ from entity_recognition import extract_entities
6
  from wordcloud import WordCloud
7
  from summarization import summarizer
8
  from utils import list_files, process_file
9
- import pygraphviz as pgv
10
- import os
11
 
12
  # Initialize FastAPI
13
  app = FastAPI()
@@ -16,175 +14,6 @@ app = FastAPI()
16
  class TextRequest(BaseModel):
17
  text: str
18
 
19
- def wrap_label(label, max_length=15):
20
- """Improved label wrapping with hyphenation awareness"""
21
- if len(label) <= max_length:
22
- return label
23
-
24
- # Try to break at natural points
25
- break_chars = [" ", "-", "_", "/"]
26
- lines = []
27
- current = ""
28
-
29
- for char in label:
30
- if len(current) >= max_length and char in break_chars:
31
- lines.append(current.strip())
32
- current = char
33
- else:
34
- current += char
35
-
36
- if current:
37
- lines.append(current.strip())
38
-
39
- return "\\n".join(lines)
40
- def generate_high_res_mindmap(text):
41
- """Generate high-quality mind map with improved visibility"""
42
- try:
43
- # Verify we have entities to visualize
44
- entities = extract_entities(text)
45
- if not any(entities.values()):
46
- print("No entities found to generate mind map")
47
- return None
48
-
49
- # Create temporary directory
50
- temp_dir = "/tmp/mindmaps"
51
- os.makedirs(temp_dir, exist_ok=True)
52
- output_path = os.path.join(temp_dir, "mindmap.png")
53
-
54
- # Create graph with optimized settings
55
- G = pgv.AGraph(
56
- directed=True,
57
- rankdir="TB", # Top-to-bottom layout
58
- bgcolor="white",
59
- fontname="Arial", # More readable font
60
- splines="ortho", # Straight lines
61
- overlap="false",
62
- concentrate="true",
63
- ratio="compress",
64
- size="50,50", # Larger canvas
65
- dpi="1000", # Higher resolution
66
- pad="1.0",
67
- nodesep="1.2", # More space between nodes
68
- ranksep="1.5" # More vertical space
69
- )
70
-
71
- # Enhanced node styling for better visibility
72
- G.node_attr.update({
73
- "fontsize": "24", # Larger font
74
- "fontname": "Arial Bold",
75
- "shape": "box",
76
- "style": "rounded,filled",
77
- "fillcolor": "#E1F5FE",
78
- "color": "#0288D1",
79
- "height": "0.8",
80
- "width": "2.0",
81
- "penwidth": "2.0",
82
- "margin": "0.3,0.1" # Better text padding
83
- })
84
-
85
- # Enhanced edge styling
86
- G.edge_attr.update({
87
- "color": "#616161",
88
- "penwidth": "2.5",
89
- "arrowsize": "1.2",
90
- "fontname": "Arial",
91
- "fontsize": "20",
92
- "fontcolor": "#424242"
93
- })
94
-
95
- # Add central node with improved styling
96
- G.add_node("DOCUMENT",
97
- shape="doubleoctagon",
98
- fillcolor="#4FC3F7",
99
- fontsize="28",
100
- width="2.5",
101
- height="1.0",
102
- penwidth="3.0")
103
-
104
- # Add entities with better spacing
105
- max_categories = 5
106
- max_entities = 8
107
-
108
- for cat_idx, (category, values) in enumerate(entities.items()):
109
- if cat_idx >= max_categories:
110
- break
111
-
112
- # Main category node
113
- cat_node = f"CAT_{cat_idx}"
114
- G.add_node(cat_node,
115
- label=wrap_label(category, 18),
116
- shape="tab",
117
- fillcolor="#81D4FA",
118
- fontsize="22")
119
-
120
- G.add_edge("DOCUMENT", cat_node,
121
- label="contains",
122
- penwidth="3.0")
123
-
124
- # Add entities with grouping if needed
125
- if len(values) > max_entities:
126
- # Create subcategory groups
127
- for sub_idx, group in enumerate([values[i:i+max_entities]
128
- for i in range(0, len(values), max_entities)]):
129
- sub_node = f"SUB_{cat_idx}_{sub_idx}"
130
- G.add_node(sub_node,
131
- label=f"Group {sub_idx+1}",
132
- shape="folder",
133
- fillcolor="#B3E5FC")
134
- G.add_edge(cat_node, sub_node)
135
-
136
- for ent_idx, value in enumerate(group):
137
- ent_node = f"ENT_{cat_idx}_{sub_idx}_{ent_idx}"
138
- G.add_node(ent_node,
139
- label=wrap_label(value, 15),
140
- shape="note",
141
- fillcolor="#E1F5FE")
142
- G.add_edge(sub_node, ent_node)
143
- else:
144
- # Directly add entities
145
- for ent_idx, value in enumerate(values[:max_entities]):
146
- ent_node = f"ENT_{cat_idx}_{ent_idx}"
147
- G.add_node(ent_node,
148
- label=wrap_label(value, 15),
149
- shape="note",
150
- fillcolor="#E1F5FE")
151
- G.add_edge(cat_node, ent_node)
152
-
153
- # Generate output with multiple attempts
154
- for engine in ['dot', 'neato', 'sfdp']:
155
- try:
156
- G.draw(output_path,
157
- format="png",
158
- prog=engine,
159
- args=f"-Gdpi=300 -Gsize=50,50 -Goverlap=prism")
160
- print(f"Successfully generated with {engine}")
161
-
162
- # Verify the output
163
- if os.path.exists(output_path) and os.path.getsize(output_path) > 0:
164
- return output_path
165
-
166
- except Exception as e:
167
- print(f"Layout engine {engine} failed: {str(e)}")
168
- continue
169
-
170
- raise RuntimeError("All layout engines failed")
171
-
172
- except Exception as e:
173
- print(f"Mind map generation failed: {str(e)}")
174
- # Create error visualization
175
- try:
176
- import matplotlib.pyplot as plt
177
- plt.figure(figsize=(20, 10))
178
- plt.text(0.5, 0.5,
179
- f"Mind Map Generation Failed\n{str(e)}\n\nOriginal Text:\n{text[:200]}...",
180
- ha='center', va='center', wrap=True)
181
- plt.axis('off')
182
- error_path = os.path.join(temp_dir, "error_mindmap.png")
183
- plt.savefig(error_path, bbox_inches='tight', dpi=300)
184
- plt.close()
185
- return error_path
186
- except:
187
- return None
188
  @app.post("/summarize")
189
  def summarize_text(request: TextRequest):
190
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
@@ -223,16 +52,7 @@ def generate_word_cloud(request: TextRequest):
223
 
224
  # Gradio UI
225
  with gr.Blocks(theme=gr.themes.Soft(), css="""
226
- .mindmap-container img {
227
- max-height: none !important;
228
- min-width: 100% !important;
229
- object-fit: contain !important;
230
- background: white !important;
231
- border: 1px solid #e0e0e0 !important;
232
- border-radius: 8px !important;
233
- padding: 20px !important;
234
- }
235
- .gradio-container { max-width: 1400px !important; }
236
  """) as iface:
237
 
238
  gr.Markdown("# JFK Document Analysis Suite")
@@ -272,20 +92,7 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
272
  width=600
273
  )
274
 
275
- # Mind map section
276
- with gr.Row():
277
- mindmap_btn = gr.Button(
278
- "Generate Enhanced Mind Map",
279
- variant="primary"
280
- )
281
-
282
- with gr.Row():
283
- output_mindmap = gr.Image(
284
- label="High-Resolution Mind Map",
285
- elem_classes="mindmap-container",
286
- height=800,
287
- width=800
288
- )
289
 
290
  # Event handlers must be inside the Blocks context
291
  process_btn.click(
@@ -294,37 +101,6 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
294
  outputs=[full_doc_text, output_summary, output_entities, output_wordcloud]
295
  )
296
 
297
- def display_mindmap(text):
298
- try:
299
- img_path = generate_high_res_mindmap(text)
300
- if img_path and os.path.exists(img_path):
301
- return img_path
302
- return None
303
- except Exception as e:
304
- print(f"Display error: {e}")
305
- return None
306
-
307
- mindmap_btn.click(
308
- fn=display_mindmap,
309
- inputs=full_doc_text,
310
- outputs=output_mindmap,
311
- api_name="generate_mindmap",
312
- show_progress=True
313
- )
314
-
315
- # Add CSS for better image display
316
- css = """
317
- .mindmap-container img {
318
- max-width: 100% !important;
319
- height: auto !important;
320
- background: white !important;
321
- border: 2px solid #e0e0e0 !important;
322
- border-radius: 8px !important;
323
- padding: 10px !important;
324
- margin: 10px auto !important;
325
- display: block !important;
326
- }
327
- """
328
 
329
  if __name__ == "__main__":
330
  iface.launch(
 
6
  from wordcloud import WordCloud
7
  from summarization import summarizer
8
  from utils import list_files, process_file
 
 
9
 
10
  # Initialize FastAPI
11
  app = FastAPI()
 
14
  class TextRequest(BaseModel):
15
  text: str
16
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
  @app.post("/summarize")
18
  def summarize_text(request: TextRequest):
19
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
 
52
 
53
  # Gradio UI
54
  with gr.Blocks(theme=gr.themes.Soft(), css="""
55
+
 
 
 
 
 
 
 
 
 
56
  """) as iface:
57
 
58
  gr.Markdown("# JFK Document Analysis Suite")
 
92
  width=600
93
  )
94
 
95
+
 
 
 
 
 
 
 
 
 
 
 
 
 
96
 
97
  # Event handlers must be inside the Blocks context
98
  process_btn.click(
 
101
  outputs=[full_doc_text, output_summary, output_entities, output_wordcloud]
102
  )
103
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
104
 
105
  if __name__ == "__main__":
106
  iface.launch(
space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/app.py CHANGED
@@ -6,8 +6,6 @@ from entity_recognition import extract_entities
6
  from wordcloud import WordCloud
7
  from summarization import summarizer
8
  from utils import list_files, process_file
9
- import pygraphviz as pgv
10
- import os
11
 
12
  # Initialize FastAPI
13
  app = FastAPI()
@@ -16,175 +14,6 @@ app = FastAPI()
16
  class TextRequest(BaseModel):
17
  text: str
18
 
19
- def wrap_label(label, max_length=15):
20
- """Improved label wrapping with hyphenation awareness"""
21
- if len(label) <= max_length:
22
- return label
23
-
24
- # Try to break at natural points
25
- break_chars = [" ", "-", "_", "/"]
26
- lines = []
27
- current = ""
28
-
29
- for char in label:
30
- if len(current) >= max_length and char in break_chars:
31
- lines.append(current.strip())
32
- current = char
33
- else:
34
- current += char
35
-
36
- if current:
37
- lines.append(current.strip())
38
-
39
- return "\\n".join(lines)
40
- def generate_high_res_mindmap(text):
41
- """Generate high-quality mind map with improved visibility"""
42
- try:
43
- # Verify we have entities to visualize
44
- entities = extract_entities(text)
45
- if not any(entities.values()):
46
- print("No entities found to generate mind map")
47
- return None
48
-
49
- # Create temporary directory
50
- temp_dir = "/tmp/mindmaps"
51
- os.makedirs(temp_dir, exist_ok=True)
52
- output_path = os.path.join(temp_dir, "mindmap.png")
53
-
54
- # Create graph with optimized settings
55
- G = pgv.AGraph(
56
- directed=True,
57
- rankdir="TB", # Top-to-bottom layout
58
- bgcolor="white",
59
- fontname="Arial", # More readable font
60
- splines="ortho", # Straight lines
61
- overlap="false",
62
- concentrate="true",
63
- ratio="compress",
64
- size="50,50", # Larger canvas
65
- dpi="1000", # Higher resolution
66
- pad="1.0",
67
- nodesep="1.2", # More space between nodes
68
- ranksep="1.5" # More vertical space
69
- )
70
-
71
- # Enhanced node styling for better visibility
72
- G.node_attr.update({
73
- "fontsize": "24", # Larger font
74
- "fontname": "Arial Bold",
75
- "shape": "box",
76
- "style": "rounded,filled",
77
- "fillcolor": "#E1F5FE",
78
- "color": "#0288D1",
79
- "height": "0.8",
80
- "width": "2.0",
81
- "penwidth": "2.0",
82
- "margin": "0.3,0.1" # Better text padding
83
- })
84
-
85
- # Enhanced edge styling
86
- G.edge_attr.update({
87
- "color": "#616161",
88
- "penwidth": "2.5",
89
- "arrowsize": "1.2",
90
- "fontname": "Arial",
91
- "fontsize": "20",
92
- "fontcolor": "#424242"
93
- })
94
-
95
- # Add central node with improved styling
96
- G.add_node("DOCUMENT",
97
- shape="doubleoctagon",
98
- fillcolor="#4FC3F7",
99
- fontsize="28",
100
- width="2.5",
101
- height="1.0",
102
- penwidth="3.0")
103
-
104
- # Add entities with better spacing
105
- max_categories = 5
106
- max_entities = 8
107
-
108
- for cat_idx, (category, values) in enumerate(entities.items()):
109
- if cat_idx >= max_categories:
110
- break
111
-
112
- # Main category node
113
- cat_node = f"CAT_{cat_idx}"
114
- G.add_node(cat_node,
115
- label=wrap_label(category, 18),
116
- shape="tab",
117
- fillcolor="#81D4FA",
118
- fontsize="22")
119
-
120
- G.add_edge("DOCUMENT", cat_node,
121
- label="contains",
122
- penwidth="3.0")
123
-
124
- # Add entities with grouping if needed
125
- if len(values) > max_entities:
126
- # Create subcategory groups
127
- for sub_idx, group in enumerate([values[i:i+max_entities]
128
- for i in range(0, len(values), max_entities)]):
129
- sub_node = f"SUB_{cat_idx}_{sub_idx}"
130
- G.add_node(sub_node,
131
- label=f"Group {sub_idx+1}",
132
- shape="folder",
133
- fillcolor="#B3E5FC")
134
- G.add_edge(cat_node, sub_node)
135
-
136
- for ent_idx, value in enumerate(group):
137
- ent_node = f"ENT_{cat_idx}_{sub_idx}_{ent_idx}"
138
- G.add_node(ent_node,
139
- label=wrap_label(value, 15),
140
- shape="note",
141
- fillcolor="#E1F5FE")
142
- G.add_edge(sub_node, ent_node)
143
- else:
144
- # Directly add entities
145
- for ent_idx, value in enumerate(values[:max_entities]):
146
- ent_node = f"ENT_{cat_idx}_{ent_idx}"
147
- G.add_node(ent_node,
148
- label=wrap_label(value, 15),
149
- shape="note",
150
- fillcolor="#E1F5FE")
151
- G.add_edge(cat_node, ent_node)
152
-
153
- # Generate output with multiple attempts
154
- for engine in ['dot', 'neato', 'sfdp']:
155
- try:
156
- G.draw(output_path,
157
- format="png",
158
- prog=engine,
159
- args=f"-Gdpi=300 -Gsize=50,50 -Goverlap=prism")
160
- print(f"Successfully generated with {engine}")
161
-
162
- # Verify the output
163
- if os.path.exists(output_path) and os.path.getsize(output_path) > 0:
164
- return output_path
165
-
166
- except Exception as e:
167
- print(f"Layout engine {engine} failed: {str(e)}")
168
- continue
169
-
170
- raise RuntimeError("All layout engines failed")
171
-
172
- except Exception as e:
173
- print(f"Mind map generation failed: {str(e)}")
174
- # Create error visualization
175
- try:
176
- import matplotlib.pyplot as plt
177
- plt.figure(figsize=(20, 10))
178
- plt.text(0.5, 0.5,
179
- f"Mind Map Generation Failed\n{str(e)}\n\nOriginal Text:\n{text[:200]}...",
180
- ha='center', va='center', wrap=True)
181
- plt.axis('off')
182
- error_path = os.path.join(temp_dir, "error_mindmap.png")
183
- plt.savefig(error_path, bbox_inches='tight', dpi=300)
184
- plt.close()
185
- return error_path
186
- except:
187
- return None
188
  @app.post("/summarize")
189
  def summarize_text(request: TextRequest):
190
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
@@ -223,16 +52,7 @@ def generate_word_cloud(request: TextRequest):
223
 
224
  # Gradio UI
225
  with gr.Blocks(theme=gr.themes.Soft(), css="""
226
- .mindmap-container img {
227
- max-height: none !important;
228
- min-width: 100% !important;
229
- object-fit: contain !important;
230
- background: white !important;
231
- border: 1px solid #e0e0e0 !important;
232
- border-radius: 8px !important;
233
- padding: 20px !important;
234
- }
235
- .gradio-container { max-width: 1400px !important; }
236
  """) as iface:
237
 
238
  gr.Markdown("# JFK Document Analysis Suite")
@@ -272,20 +92,7 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
272
  width=600
273
  )
274
 
275
- # Mind map section
276
- with gr.Row():
277
- mindmap_btn = gr.Button(
278
- "Generate Enhanced Mind Map",
279
- variant="primary"
280
- )
281
-
282
- with gr.Row():
283
- output_mindmap = gr.Image(
284
- label="High-Resolution Mind Map",
285
- elem_classes="mindmap-container",
286
- height=800,
287
- width=800
288
- )
289
 
290
  # Event handlers must be inside the Blocks context
291
  process_btn.click(
@@ -294,37 +101,6 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
294
  outputs=[full_doc_text, output_summary, output_entities, output_wordcloud]
295
  )
296
 
297
- def display_mindmap(text):
298
- try:
299
- img_path = generate_high_res_mindmap(text)
300
- if img_path and os.path.exists(img_path):
301
- return img_path
302
- return None
303
- except Exception as e:
304
- print(f"Display error: {e}")
305
- return None
306
-
307
- mindmap_btn.click(
308
- fn=display_mindmap,
309
- inputs=full_doc_text,
310
- outputs=output_mindmap,
311
- api_name="generate_mindmap",
312
- show_progress=True
313
- )
314
-
315
- # Add CSS for better image display
316
- css = """
317
- .mindmap-container img {
318
- max-width: 100% !important;
319
- height: auto !important;
320
- background: white !important;
321
- border: 2px solid #e0e0e0 !important;
322
- border-radius: 8px !important;
323
- padding: 10px !important;
324
- margin: 10px auto !important;
325
- display: block !important;
326
- }
327
- """
328
 
329
  if __name__ == "__main__":
330
  iface.launch(
 
6
  from wordcloud import WordCloud
7
  from summarization import summarizer
8
  from utils import list_files, process_file
 
 
9
 
10
  # Initialize FastAPI
11
  app = FastAPI()
 
14
  class TextRequest(BaseModel):
15
  text: str
16
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
  @app.post("/summarize")
18
  def summarize_text(request: TextRequest):
19
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
 
52
 
53
  # Gradio UI
54
  with gr.Blocks(theme=gr.themes.Soft(), css="""
55
+
 
 
 
 
 
 
 
 
 
56
  """) as iface:
57
 
58
  gr.Markdown("# JFK Document Analysis Suite")
 
92
  width=600
93
  )
94
 
95
+
 
 
 
 
 
 
 
 
 
 
 
 
 
96
 
97
  # Event handlers must be inside the Blocks context
98
  process_btn.click(
 
101
  outputs=[full_doc_text, output_summary, output_entities, output_wordcloud]
102
  )
103
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
104
 
105
  if __name__ == "__main__":
106
  iface.launch(
space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/app.py CHANGED
@@ -6,8 +6,6 @@ from entity_recognition import extract_entities
6
  from wordcloud import WordCloud
7
  from summarization import summarizer
8
  from utils import list_files, process_file
9
- import pygraphviz as pgv
10
- import os
11
 
12
  # Initialize FastAPI
13
  app = FastAPI()
@@ -16,175 +14,6 @@ app = FastAPI()
16
  class TextRequest(BaseModel):
17
  text: str
18
 
19
- def wrap_label(label, max_length=15):
20
- """Improved label wrapping with hyphenation awareness"""
21
- if len(label) <= max_length:
22
- return label
23
-
24
- # Try to break at natural points
25
- break_chars = [" ", "-", "_", "/"]
26
- lines = []
27
- current = ""
28
-
29
- for char in label:
30
- if len(current) >= max_length and char in break_chars:
31
- lines.append(current.strip())
32
- current = char
33
- else:
34
- current += char
35
-
36
- if current:
37
- lines.append(current.strip())
38
-
39
- return "\\n".join(lines)
40
- def generate_high_res_mindmap(text):
41
- """Generate high-quality mind map with improved visibility"""
42
- try:
43
- # Verify we have entities to visualize
44
- entities = extract_entities(text)
45
- if not any(entities.values()):
46
- print("No entities found to generate mind map")
47
- return None
48
-
49
- # Create temporary directory
50
- temp_dir = "/tmp/mindmaps"
51
- os.makedirs(temp_dir, exist_ok=True)
52
- output_path = os.path.join(temp_dir, "mindmap.png")
53
-
54
- # Create graph with optimized settings
55
- G = pgv.AGraph(
56
- directed=True,
57
- rankdir="TB", # Top-to-bottom layout
58
- bgcolor="white",
59
- fontname="Arial", # More readable font
60
- splines="ortho", # Straight lines
61
- overlap="false",
62
- concentrate="true",
63
- ratio="compress",
64
- size="50,50", # Larger canvas
65
- dpi="1000", # Higher resolution
66
- pad="1.0",
67
- nodesep="1.2", # More space between nodes
68
- ranksep="1.5" # More vertical space
69
- )
70
-
71
- # Enhanced node styling for better visibility
72
- G.node_attr.update({
73
- "fontsize": "24", # Larger font
74
- "fontname": "Arial Bold",
75
- "shape": "box",
76
- "style": "rounded,filled",
77
- "fillcolor": "#E1F5FE",
78
- "color": "#0288D1",
79
- "height": "0.8",
80
- "width": "2.0",
81
- "penwidth": "2.0",
82
- "margin": "0.3,0.1" # Better text padding
83
- })
84
-
85
- # Enhanced edge styling
86
- G.edge_attr.update({
87
- "color": "#616161",
88
- "penwidth": "2.5",
89
- "arrowsize": "1.2",
90
- "fontname": "Arial",
91
- "fontsize": "20",
92
- "fontcolor": "#424242"
93
- })
94
-
95
- # Add central node with improved styling
96
- G.add_node("DOCUMENT",
97
- shape="doubleoctagon",
98
- fillcolor="#4FC3F7",
99
- fontsize="28",
100
- width="2.5",
101
- height="1.0",
102
- penwidth="3.0")
103
-
104
- # Add entities with better spacing
105
- max_categories = 5
106
- max_entities = 8
107
-
108
- for cat_idx, (category, values) in enumerate(entities.items()):
109
- if cat_idx >= max_categories:
110
- break
111
-
112
- # Main category node
113
- cat_node = f"CAT_{cat_idx}"
114
- G.add_node(cat_node,
115
- label=wrap_label(category, 18),
116
- shape="tab",
117
- fillcolor="#81D4FA",
118
- fontsize="22")
119
-
120
- G.add_edge("DOCUMENT", cat_node,
121
- label="contains",
122
- penwidth="3.0")
123
-
124
- # Add entities with grouping if needed
125
- if len(values) > max_entities:
126
- # Create subcategory groups
127
- for sub_idx, group in enumerate([values[i:i+max_entities]
128
- for i in range(0, len(values), max_entities)]):
129
- sub_node = f"SUB_{cat_idx}_{sub_idx}"
130
- G.add_node(sub_node,
131
- label=f"Group {sub_idx+1}",
132
- shape="folder",
133
- fillcolor="#B3E5FC")
134
- G.add_edge(cat_node, sub_node)
135
-
136
- for ent_idx, value in enumerate(group):
137
- ent_node = f"ENT_{cat_idx}_{sub_idx}_{ent_idx}"
138
- G.add_node(ent_node,
139
- label=wrap_label(value, 15),
140
- shape="note",
141
- fillcolor="#E1F5FE")
142
- G.add_edge(sub_node, ent_node)
143
- else:
144
- # Directly add entities
145
- for ent_idx, value in enumerate(values[:max_entities]):
146
- ent_node = f"ENT_{cat_idx}_{ent_idx}"
147
- G.add_node(ent_node,
148
- label=wrap_label(value, 15),
149
- shape="note",
150
- fillcolor="#E1F5FE")
151
- G.add_edge(cat_node, ent_node)
152
-
153
- # Generate output with multiple attempts
154
- for engine in ['dot', 'neato', 'sfdp']:
155
- try:
156
- G.draw(output_path,
157
- format="png",
158
- prog=engine,
159
- args=f"-Gdpi=300 -Gsize=50,50 -Goverlap=prism")
160
- print(f"Successfully generated with {engine}")
161
-
162
- # Verify the output
163
- if os.path.exists(output_path) and os.path.getsize(output_path) > 0:
164
- return output_path
165
-
166
- except Exception as e:
167
- print(f"Layout engine {engine} failed: {str(e)}")
168
- continue
169
-
170
- raise RuntimeError("All layout engines failed")
171
-
172
- except Exception as e:
173
- print(f"Mind map generation failed: {str(e)}")
174
- # Create error visualization
175
- try:
176
- import matplotlib.pyplot as plt
177
- plt.figure(figsize=(20, 10))
178
- plt.text(0.5, 0.5,
179
- f"Mind Map Generation Failed\n{str(e)}\n\nOriginal Text:\n{text[:200]}...",
180
- ha='center', va='center', wrap=True)
181
- plt.axis('off')
182
- error_path = os.path.join(temp_dir, "error_mindmap.png")
183
- plt.savefig(error_path, bbox_inches='tight', dpi=300)
184
- plt.close()
185
- return error_path
186
- except:
187
- return None
188
  @app.post("/summarize")
189
  def summarize_text(request: TextRequest):
190
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
@@ -223,16 +52,7 @@ def generate_word_cloud(request: TextRequest):
223
 
224
  # Gradio UI
225
  with gr.Blocks(theme=gr.themes.Soft(), css="""
226
- .mindmap-container img {
227
- max-height: none !important;
228
- min-width: 100% !important;
229
- object-fit: contain !important;
230
- background: white !important;
231
- border: 1px solid #e0e0e0 !important;
232
- border-radius: 8px !important;
233
- padding: 20px !important;
234
- }
235
- .gradio-container { max-width: 1400px !important; }
236
  """) as iface:
237
 
238
  gr.Markdown("# JFK Document Analysis Suite")
@@ -272,20 +92,7 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
272
  width=600
273
  )
274
 
275
- # Mind map section
276
- with gr.Row():
277
- mindmap_btn = gr.Button(
278
- "Generate Enhanced Mind Map",
279
- variant="primary"
280
- )
281
-
282
- with gr.Row():
283
- output_mindmap = gr.Image(
284
- label="High-Resolution Mind Map",
285
- elem_classes="mindmap-container",
286
- height=800,
287
- width=800
288
- )
289
 
290
  # Event handlers must be inside the Blocks context
291
  process_btn.click(
@@ -294,37 +101,6 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
294
  outputs=[full_doc_text, output_summary, output_entities, output_wordcloud]
295
  )
296
 
297
- def display_mindmap(text):
298
- try:
299
- img_path = generate_high_res_mindmap(text)
300
- if img_path and os.path.exists(img_path):
301
- return img_path
302
- return None
303
- except Exception as e:
304
- print(f"Display error: {e}")
305
- return None
306
-
307
- mindmap_btn.click(
308
- fn=display_mindmap,
309
- inputs=full_doc_text,
310
- outputs=output_mindmap,
311
- api_name="generate_mindmap",
312
- show_progress=True
313
- )
314
-
315
- # Add CSS for better image display
316
- css = """
317
- .mindmap-container img {
318
- max-width: 100% !important;
319
- height: auto !important;
320
- background: white !important;
321
- border: 2px solid #e0e0e0 !important;
322
- border-radius: 8px !important;
323
- padding: 10px !important;
324
- margin: 10px auto !important;
325
- display: block !important;
326
- }
327
- """
328
 
329
  if __name__ == "__main__":
330
  iface.launch(
 
6
  from wordcloud import WordCloud
7
  from summarization import summarizer
8
  from utils import list_files, process_file
 
 
9
 
10
  # Initialize FastAPI
11
  app = FastAPI()
 
14
  class TextRequest(BaseModel):
15
  text: str
16
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
  @app.post("/summarize")
18
  def summarize_text(request: TextRequest):
19
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
 
52
 
53
  # Gradio UI
54
  with gr.Blocks(theme=gr.themes.Soft(), css="""
55
+
 
 
 
 
 
 
 
 
 
56
  """) as iface:
57
 
58
  gr.Markdown("# JFK Document Analysis Suite")
 
92
  width=600
93
  )
94
 
95
+
 
 
 
 
 
 
 
 
 
 
 
 
 
96
 
97
  # Event handlers must be inside the Blocks context
98
  process_btn.click(
 
101
  outputs=[full_doc_text, output_summary, output_entities, output_wordcloud]
102
  )
103
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
104
 
105
  if __name__ == "__main__":
106
  iface.launch(
space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/app.py CHANGED
@@ -6,8 +6,6 @@ from entity_recognition import extract_entities
6
  from wordcloud import WordCloud
7
  from summarization import summarizer
8
  from utils import list_files, process_file
9
- import pygraphviz as pgv
10
- import os
11
 
12
  # Initialize FastAPI
13
  app = FastAPI()
@@ -16,175 +14,6 @@ app = FastAPI()
16
  class TextRequest(BaseModel):
17
  text: str
18
 
19
- def wrap_label(label, max_length=15):
20
- """Improved label wrapping with hyphenation awareness"""
21
- if len(label) <= max_length:
22
- return label
23
-
24
- # Try to break at natural points
25
- break_chars = [" ", "-", "_", "/"]
26
- lines = []
27
- current = ""
28
-
29
- for char in label:
30
- if len(current) >= max_length and char in break_chars:
31
- lines.append(current.strip())
32
- current = char
33
- else:
34
- current += char
35
-
36
- if current:
37
- lines.append(current.strip())
38
-
39
- return "\\n".join(lines)
40
- def generate_high_res_mindmap(text):
41
- """Generate high-quality mind map with improved visibility"""
42
- try:
43
- # Verify we have entities to visualize
44
- entities = extract_entities(text)
45
- if not any(entities.values()):
46
- print("No entities found to generate mind map")
47
- return None
48
-
49
- # Create temporary directory
50
- temp_dir = "/tmp/mindmaps"
51
- os.makedirs(temp_dir, exist_ok=True)
52
- output_path = os.path.join(temp_dir, "mindmap.png")
53
-
54
- # Create graph with optimized settings
55
- G = pgv.AGraph(
56
- directed=True,
57
- rankdir="TB", # Top-to-bottom layout
58
- bgcolor="white",
59
- fontname="Arial", # More readable font
60
- splines="ortho", # Straight lines
61
- overlap="false",
62
- concentrate="true",
63
- ratio="compress",
64
- size="50,50", # Larger canvas
65
- dpi="1000", # Higher resolution
66
- pad="1.0",
67
- nodesep="1.2", # More space between nodes
68
- ranksep="1.5" # More vertical space
69
- )
70
-
71
- # Enhanced node styling for better visibility
72
- G.node_attr.update({
73
- "fontsize": "24", # Larger font
74
- "fontname": "Arial Bold",
75
- "shape": "box",
76
- "style": "rounded,filled",
77
- "fillcolor": "#E1F5FE",
78
- "color": "#0288D1",
79
- "height": "0.8",
80
- "width": "2.0",
81
- "penwidth": "2.0",
82
- "margin": "0.3,0.1" # Better text padding
83
- })
84
-
85
- # Enhanced edge styling
86
- G.edge_attr.update({
87
- "color": "#616161",
88
- "penwidth": "2.5",
89
- "arrowsize": "1.2",
90
- "fontname": "Arial",
91
- "fontsize": "20",
92
- "fontcolor": "#424242"
93
- })
94
-
95
- # Add central node with improved styling
96
- G.add_node("DOCUMENT",
97
- shape="doubleoctagon",
98
- fillcolor="#4FC3F7",
99
- fontsize="28",
100
- width="2.5",
101
- height="1.0",
102
- penwidth="3.0")
103
-
104
- # Add entities with better spacing
105
- max_categories = 5
106
- max_entities = 8
107
-
108
- for cat_idx, (category, values) in enumerate(entities.items()):
109
- if cat_idx >= max_categories:
110
- break
111
-
112
- # Main category node
113
- cat_node = f"CAT_{cat_idx}"
114
- G.add_node(cat_node,
115
- label=wrap_label(category, 18),
116
- shape="tab",
117
- fillcolor="#81D4FA",
118
- fontsize="22")
119
-
120
- G.add_edge("DOCUMENT", cat_node,
121
- label="contains",
122
- penwidth="3.0")
123
-
124
- # Add entities with grouping if needed
125
- if len(values) > max_entities:
126
- # Create subcategory groups
127
- for sub_idx, group in enumerate([values[i:i+max_entities]
128
- for i in range(0, len(values), max_entities)]):
129
- sub_node = f"SUB_{cat_idx}_{sub_idx}"
130
- G.add_node(sub_node,
131
- label=f"Group {sub_idx+1}",
132
- shape="folder",
133
- fillcolor="#B3E5FC")
134
- G.add_edge(cat_node, sub_node)
135
-
136
- for ent_idx, value in enumerate(group):
137
- ent_node = f"ENT_{cat_idx}_{sub_idx}_{ent_idx}"
138
- G.add_node(ent_node,
139
- label=wrap_label(value, 15),
140
- shape="note",
141
- fillcolor="#E1F5FE")
142
- G.add_edge(sub_node, ent_node)
143
- else:
144
- # Directly add entities
145
- for ent_idx, value in enumerate(values[:max_entities]):
146
- ent_node = f"ENT_{cat_idx}_{ent_idx}"
147
- G.add_node(ent_node,
148
- label=wrap_label(value, 15),
149
- shape="note",
150
- fillcolor="#E1F5FE")
151
- G.add_edge(cat_node, ent_node)
152
-
153
- # Generate output with multiple attempts
154
- for engine in ['dot', 'neato', 'sfdp']:
155
- try:
156
- G.draw(output_path,
157
- format="png",
158
- prog=engine,
159
- args=f"-Gdpi=300 -Gsize=50,50 -Goverlap=prism")
160
- print(f"Successfully generated with {engine}")
161
-
162
- # Verify the output
163
- if os.path.exists(output_path) and os.path.getsize(output_path) > 0:
164
- return output_path
165
-
166
- except Exception as e:
167
- print(f"Layout engine {engine} failed: {str(e)}")
168
- continue
169
-
170
- raise RuntimeError("All layout engines failed")
171
-
172
- except Exception as e:
173
- print(f"Mind map generation failed: {str(e)}")
174
- # Create error visualization
175
- try:
176
- import matplotlib.pyplot as plt
177
- plt.figure(figsize=(20, 10))
178
- plt.text(0.5, 0.5,
179
- f"Mind Map Generation Failed\n{str(e)}\n\nOriginal Text:\n{text[:200]}...",
180
- ha='center', va='center', wrap=True)
181
- plt.axis('off')
182
- error_path = os.path.join(temp_dir, "error_mindmap.png")
183
- plt.savefig(error_path, bbox_inches='tight', dpi=300)
184
- plt.close()
185
- return error_path
186
- except:
187
- return None
188
  @app.post("/summarize")
189
  def summarize_text(request: TextRequest):
190
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
@@ -223,16 +52,7 @@ def generate_word_cloud(request: TextRequest):
223
 
224
  # Gradio UI
225
  with gr.Blocks(theme=gr.themes.Soft(), css="""
226
- .mindmap-container img {
227
- max-height: none !important;
228
- min-width: 100% !important;
229
- object-fit: contain !important;
230
- background: white !important;
231
- border: 1px solid #e0e0e0 !important;
232
- border-radius: 8px !important;
233
- padding: 20px !important;
234
- }
235
- .gradio-container { max-width: 1400px !important; }
236
  """) as iface:
237
 
238
  gr.Markdown("# JFK Document Analysis Suite")
@@ -272,20 +92,7 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
272
  width=600
273
  )
274
 
275
- # Mind map section
276
- with gr.Row():
277
- mindmap_btn = gr.Button(
278
- "Generate Enhanced Mind Map",
279
- variant="primary"
280
- )
281
-
282
- with gr.Row():
283
- output_mindmap = gr.Image(
284
- label="High-Resolution Mind Map",
285
- elem_classes="mindmap-container",
286
- height=800,
287
- width=800
288
- )
289
 
290
  # Event handlers must be inside the Blocks context
291
  process_btn.click(
@@ -294,37 +101,6 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
294
  outputs=[full_doc_text, output_summary, output_entities, output_wordcloud]
295
  )
296
 
297
- def display_mindmap(text):
298
- try:
299
- img_path = generate_high_res_mindmap(text)
300
- if img_path and os.path.exists(img_path):
301
- return img_path
302
- return None
303
- except Exception as e:
304
- print(f"Display error: {e}")
305
- return None
306
-
307
- mindmap_btn.click(
308
- fn=display_mindmap,
309
- inputs=full_doc_text,
310
- outputs=output_mindmap,
311
- api_name="generate_mindmap",
312
- show_progress=True
313
- )
314
-
315
- # Add CSS for better image display
316
- css = """
317
- .mindmap-container img {
318
- max-width: 100% !important;
319
- height: auto !important;
320
- background: white !important;
321
- border: 2px solid #e0e0e0 !important;
322
- border-radius: 8px !important;
323
- padding: 10px !important;
324
- margin: 10px auto !important;
325
- display: block !important;
326
- }
327
- """
328
 
329
  if __name__ == "__main__":
330
  iface.launch(
 
6
  from wordcloud import WordCloud
7
  from summarization import summarizer
8
  from utils import list_files, process_file
 
 
9
 
10
  # Initialize FastAPI
11
  app = FastAPI()
 
14
  class TextRequest(BaseModel):
15
  text: str
16
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
  @app.post("/summarize")
18
  def summarize_text(request: TextRequest):
19
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
 
52
 
53
  # Gradio UI
54
  with gr.Blocks(theme=gr.themes.Soft(), css="""
55
+
 
 
 
 
 
 
 
 
 
56
  """) as iface:
57
 
58
  gr.Markdown("# JFK Document Analysis Suite")
 
92
  width=600
93
  )
94
 
95
+
 
 
 
 
 
 
 
 
 
 
 
 
 
96
 
97
  # Event handlers must be inside the Blocks context
98
  process_btn.click(
 
101
  outputs=[full_doc_text, output_summary, output_entities, output_wordcloud]
102
  )
103
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
104
 
105
  if __name__ == "__main__":
106
  iface.launch(
space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/app.py CHANGED
@@ -6,8 +6,6 @@ from entity_recognition import extract_entities
6
  from wordcloud import WordCloud
7
  from summarization import summarizer
8
  from utils import list_files, process_file
9
- import pygraphviz as pgv
10
- import os
11
 
12
  # Initialize FastAPI
13
  app = FastAPI()
@@ -16,175 +14,6 @@ app = FastAPI()
16
  class TextRequest(BaseModel):
17
  text: str
18
 
19
- def wrap_label(label, max_length=15):
20
- """Improved label wrapping with hyphenation awareness"""
21
- if len(label) <= max_length:
22
- return label
23
-
24
- # Try to break at natural points
25
- break_chars = [" ", "-", "_", "/"]
26
- lines = []
27
- current = ""
28
-
29
- for char in label:
30
- if len(current) >= max_length and char in break_chars:
31
- lines.append(current.strip())
32
- current = char
33
- else:
34
- current += char
35
-
36
- if current:
37
- lines.append(current.strip())
38
-
39
- return "\\n".join(lines)
40
- def generate_high_res_mindmap(text):
41
- """Generate high-quality mind map with improved visibility"""
42
- try:
43
- # Verify we have entities to visualize
44
- entities = extract_entities(text)
45
- if not any(entities.values()):
46
- print("No entities found to generate mind map")
47
- return None
48
-
49
- # Create temporary directory
50
- temp_dir = "/tmp/mindmaps"
51
- os.makedirs(temp_dir, exist_ok=True)
52
- output_path = os.path.join(temp_dir, "mindmap.png")
53
-
54
- # Create graph with optimized settings
55
- G = pgv.AGraph(
56
- directed=True,
57
- rankdir="TB", # Top-to-bottom layout
58
- bgcolor="white",
59
- fontname="Arial", # More readable font
60
- splines="ortho", # Straight lines
61
- overlap="false",
62
- concentrate="true",
63
- ratio="compress",
64
- size="50,50", # Larger canvas
65
- dpi="1000", # Higher resolution
66
- pad="1.0",
67
- nodesep="1.2", # More space between nodes
68
- ranksep="1.5" # More vertical space
69
- )
70
-
71
- # Enhanced node styling for better visibility
72
- G.node_attr.update({
73
- "fontsize": "24", # Larger font
74
- "fontname": "Arial Bold",
75
- "shape": "box",
76
- "style": "rounded,filled",
77
- "fillcolor": "#E1F5FE",
78
- "color": "#0288D1",
79
- "height": "0.8",
80
- "width": "2.0",
81
- "penwidth": "2.0",
82
- "margin": "0.3,0.1" # Better text padding
83
- })
84
-
85
- # Enhanced edge styling
86
- G.edge_attr.update({
87
- "color": "#616161",
88
- "penwidth": "2.5",
89
- "arrowsize": "1.2",
90
- "fontname": "Arial",
91
- "fontsize": "20",
92
- "fontcolor": "#424242"
93
- })
94
-
95
- # Add central node with improved styling
96
- G.add_node("DOCUMENT",
97
- shape="doubleoctagon",
98
- fillcolor="#4FC3F7",
99
- fontsize="28",
100
- width="2.5",
101
- height="1.0",
102
- penwidth="3.0")
103
-
104
- # Add entities with better spacing
105
- max_categories = 5
106
- max_entities = 8
107
-
108
- for cat_idx, (category, values) in enumerate(entities.items()):
109
- if cat_idx >= max_categories:
110
- break
111
-
112
- # Main category node
113
- cat_node = f"CAT_{cat_idx}"
114
- G.add_node(cat_node,
115
- label=wrap_label(category, 18),
116
- shape="tab",
117
- fillcolor="#81D4FA",
118
- fontsize="22")
119
-
120
- G.add_edge("DOCUMENT", cat_node,
121
- label="contains",
122
- penwidth="3.0")
123
-
124
- # Add entities with grouping if needed
125
- if len(values) > max_entities:
126
- # Create subcategory groups
127
- for sub_idx, group in enumerate([values[i:i+max_entities]
128
- for i in range(0, len(values), max_entities)]):
129
- sub_node = f"SUB_{cat_idx}_{sub_idx}"
130
- G.add_node(sub_node,
131
- label=f"Group {sub_idx+1}",
132
- shape="folder",
133
- fillcolor="#B3E5FC")
134
- G.add_edge(cat_node, sub_node)
135
-
136
- for ent_idx, value in enumerate(group):
137
- ent_node = f"ENT_{cat_idx}_{sub_idx}_{ent_idx}"
138
- G.add_node(ent_node,
139
- label=wrap_label(value, 15),
140
- shape="note",
141
- fillcolor="#E1F5FE")
142
- G.add_edge(sub_node, ent_node)
143
- else:
144
- # Directly add entities
145
- for ent_idx, value in enumerate(values[:max_entities]):
146
- ent_node = f"ENT_{cat_idx}_{ent_idx}"
147
- G.add_node(ent_node,
148
- label=wrap_label(value, 15),
149
- shape="note",
150
- fillcolor="#E1F5FE")
151
- G.add_edge(cat_node, ent_node)
152
-
153
- # Generate output with multiple attempts
154
- for engine in ['dot', 'neato', 'sfdp']:
155
- try:
156
- G.draw(output_path,
157
- format="png",
158
- prog=engine,
159
- args=f"-Gdpi=300 -Gsize=50,50 -Goverlap=prism")
160
- print(f"Successfully generated with {engine}")
161
-
162
- # Verify the output
163
- if os.path.exists(output_path) and os.path.getsize(output_path) > 0:
164
- return output_path
165
-
166
- except Exception as e:
167
- print(f"Layout engine {engine} failed: {str(e)}")
168
- continue
169
-
170
- raise RuntimeError("All layout engines failed")
171
-
172
- except Exception as e:
173
- print(f"Mind map generation failed: {str(e)}")
174
- # Create error visualization
175
- try:
176
- import matplotlib.pyplot as plt
177
- plt.figure(figsize=(20, 10))
178
- plt.text(0.5, 0.5,
179
- f"Mind Map Generation Failed\n{str(e)}\n\nOriginal Text:\n{text[:200]}...",
180
- ha='center', va='center', wrap=True)
181
- plt.axis('off')
182
- error_path = os.path.join(temp_dir, "error_mindmap.png")
183
- plt.savefig(error_path, bbox_inches='tight', dpi=300)
184
- plt.close()
185
- return error_path
186
- except:
187
- return None
188
  @app.post("/summarize")
189
  def summarize_text(request: TextRequest):
190
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
@@ -223,16 +52,7 @@ def generate_word_cloud(request: TextRequest):
223
 
224
  # Gradio UI
225
  with gr.Blocks(theme=gr.themes.Soft(), css="""
226
- .mindmap-container img {
227
- max-height: none !important;
228
- min-width: 100% !important;
229
- object-fit: contain !important;
230
- background: white !important;
231
- border: 1px solid #e0e0e0 !important;
232
- border-radius: 8px !important;
233
- padding: 20px !important;
234
- }
235
- .gradio-container { max-width: 1400px !important; }
236
  """) as iface:
237
 
238
  gr.Markdown("# JFK Document Analysis Suite")
@@ -272,20 +92,7 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
272
  width=600
273
  )
274
 
275
- # Mind map section
276
- with gr.Row():
277
- mindmap_btn = gr.Button(
278
- "Generate Enhanced Mind Map",
279
- variant="primary"
280
- )
281
-
282
- with gr.Row():
283
- output_mindmap = gr.Image(
284
- label="High-Resolution Mind Map",
285
- elem_classes="mindmap-container",
286
- height=800,
287
- width=800
288
- )
289
 
290
  # Event handlers must be inside the Blocks context
291
  process_btn.click(
@@ -294,37 +101,6 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
294
  outputs=[full_doc_text, output_summary, output_entities, output_wordcloud]
295
  )
296
 
297
- def display_mindmap(text):
298
- try:
299
- img_path = generate_high_res_mindmap(text)
300
- if img_path and os.path.exists(img_path):
301
- return img_path
302
- return None
303
- except Exception as e:
304
- print(f"Display error: {e}")
305
- return None
306
-
307
- mindmap_btn.click(
308
- fn=display_mindmap,
309
- inputs=full_doc_text,
310
- outputs=output_mindmap,
311
- api_name="generate_mindmap",
312
- show_progress=True
313
- )
314
-
315
- # Add CSS for better image display
316
- css = """
317
- .mindmap-container img {
318
- max-width: 100% !important;
319
- height: auto !important;
320
- background: white !important;
321
- border: 2px solid #e0e0e0 !important;
322
- border-radius: 8px !important;
323
- padding: 10px !important;
324
- margin: 10px auto !important;
325
- display: block !important;
326
- }
327
- """
328
 
329
  if __name__ == "__main__":
330
  iface.launch(
 
6
  from wordcloud import WordCloud
7
  from summarization import summarizer
8
  from utils import list_files, process_file
 
 
9
 
10
  # Initialize FastAPI
11
  app = FastAPI()
 
14
  class TextRequest(BaseModel):
15
  text: str
16
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
  @app.post("/summarize")
18
  def summarize_text(request: TextRequest):
19
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
 
52
 
53
  # Gradio UI
54
  with gr.Blocks(theme=gr.themes.Soft(), css="""
55
+
 
 
 
 
 
 
 
 
 
56
  """) as iface:
57
 
58
  gr.Markdown("# JFK Document Analysis Suite")
 
92
  width=600
93
  )
94
 
95
+
 
 
 
 
 
 
 
 
 
 
 
 
 
96
 
97
  # Event handlers must be inside the Blocks context
98
  process_btn.click(
 
101
  outputs=[full_doc_text, output_summary, output_entities, output_wordcloud]
102
  )
103
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
104
 
105
  if __name__ == "__main__":
106
  iface.launch(
space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/app.py CHANGED
@@ -6,8 +6,6 @@ from entity_recognition import extract_entities
6
  from wordcloud import WordCloud
7
  from summarization import summarizer
8
  from utils import list_files, process_file
9
- import pygraphviz as pgv
10
- import os
11
 
12
  # Initialize FastAPI
13
  app = FastAPI()
@@ -16,175 +14,6 @@ app = FastAPI()
16
  class TextRequest(BaseModel):
17
  text: str
18
 
19
- def wrap_label(label, max_length=15):
20
- """Improved label wrapping with hyphenation awareness"""
21
- if len(label) <= max_length:
22
- return label
23
-
24
- # Try to break at natural points
25
- break_chars = [" ", "-", "_", "/"]
26
- lines = []
27
- current = ""
28
-
29
- for char in label:
30
- if len(current) >= max_length and char in break_chars:
31
- lines.append(current.strip())
32
- current = char
33
- else:
34
- current += char
35
-
36
- if current:
37
- lines.append(current.strip())
38
-
39
- return "\\n".join(lines)
40
- def generate_high_res_mindmap(text):
41
- """Generate high-quality mind map with improved visibility"""
42
- try:
43
- # Verify we have entities to visualize
44
- entities = extract_entities(text)
45
- if not any(entities.values()):
46
- print("No entities found to generate mind map")
47
- return None
48
-
49
- # Create temporary directory
50
- temp_dir = "/tmp/mindmaps"
51
- os.makedirs(temp_dir, exist_ok=True)
52
- output_path = os.path.join(temp_dir, "mindmap.png")
53
-
54
- # Create graph with optimized settings
55
- G = pgv.AGraph(
56
- directed=True,
57
- rankdir="TB", # Top-to-bottom layout
58
- bgcolor="white",
59
- fontname="Arial", # More readable font
60
- splines="ortho", # Straight lines
61
- overlap="false",
62
- concentrate="true",
63
- ratio="compress",
64
- size="50,50", # Larger canvas
65
- dpi="1000", # Higher resolution
66
- pad="1.0",
67
- nodesep="1.2", # More space between nodes
68
- ranksep="1.5" # More vertical space
69
- )
70
-
71
- # Enhanced node styling for better visibility
72
- G.node_attr.update({
73
- "fontsize": "24", # Larger font
74
- "fontname": "Arial Bold",
75
- "shape": "box",
76
- "style": "rounded,filled",
77
- "fillcolor": "#E1F5FE",
78
- "color": "#0288D1",
79
- "height": "0.8",
80
- "width": "2.0",
81
- "penwidth": "2.0",
82
- "margin": "0.3,0.1" # Better text padding
83
- })
84
-
85
- # Enhanced edge styling
86
- G.edge_attr.update({
87
- "color": "#616161",
88
- "penwidth": "2.5",
89
- "arrowsize": "1.2",
90
- "fontname": "Arial",
91
- "fontsize": "20",
92
- "fontcolor": "#424242"
93
- })
94
-
95
- # Add central node with improved styling
96
- G.add_node("DOCUMENT",
97
- shape="doubleoctagon",
98
- fillcolor="#4FC3F7",
99
- fontsize="28",
100
- width="2.5",
101
- height="1.0",
102
- penwidth="3.0")
103
-
104
- # Add entities with better spacing
105
- max_categories = 5
106
- max_entities = 8
107
-
108
- for cat_idx, (category, values) in enumerate(entities.items()):
109
- if cat_idx >= max_categories:
110
- break
111
-
112
- # Main category node
113
- cat_node = f"CAT_{cat_idx}"
114
- G.add_node(cat_node,
115
- label=wrap_label(category, 18),
116
- shape="tab",
117
- fillcolor="#81D4FA",
118
- fontsize="22")
119
-
120
- G.add_edge("DOCUMENT", cat_node,
121
- label="contains",
122
- penwidth="3.0")
123
-
124
- # Add entities with grouping if needed
125
- if len(values) > max_entities:
126
- # Create subcategory groups
127
- for sub_idx, group in enumerate([values[i:i+max_entities]
128
- for i in range(0, len(values), max_entities)]):
129
- sub_node = f"SUB_{cat_idx}_{sub_idx}"
130
- G.add_node(sub_node,
131
- label=f"Group {sub_idx+1}",
132
- shape="folder",
133
- fillcolor="#B3E5FC")
134
- G.add_edge(cat_node, sub_node)
135
-
136
- for ent_idx, value in enumerate(group):
137
- ent_node = f"ENT_{cat_idx}_{sub_idx}_{ent_idx}"
138
- G.add_node(ent_node,
139
- label=wrap_label(value, 15),
140
- shape="note",
141
- fillcolor="#E1F5FE")
142
- G.add_edge(sub_node, ent_node)
143
- else:
144
- # Directly add entities
145
- for ent_idx, value in enumerate(values[:max_entities]):
146
- ent_node = f"ENT_{cat_idx}_{ent_idx}"
147
- G.add_node(ent_node,
148
- label=wrap_label(value, 15),
149
- shape="note",
150
- fillcolor="#E1F5FE")
151
- G.add_edge(cat_node, ent_node)
152
-
153
- # Generate output with multiple attempts
154
- for engine in ['dot', 'neato', 'sfdp']:
155
- try:
156
- G.draw(output_path,
157
- format="png",
158
- prog=engine,
159
- args=f"-Gdpi=300 -Gsize=50,50 -Goverlap=prism")
160
- print(f"Successfully generated with {engine}")
161
-
162
- # Verify the output
163
- if os.path.exists(output_path) and os.path.getsize(output_path) > 0:
164
- return output_path
165
-
166
- except Exception as e:
167
- print(f"Layout engine {engine} failed: {str(e)}")
168
- continue
169
-
170
- raise RuntimeError("All layout engines failed")
171
-
172
- except Exception as e:
173
- print(f"Mind map generation failed: {str(e)}")
174
- # Create error visualization
175
- try:
176
- import matplotlib.pyplot as plt
177
- plt.figure(figsize=(20, 10))
178
- plt.text(0.5, 0.5,
179
- f"Mind Map Generation Failed\n{str(e)}\n\nOriginal Text:\n{text[:200]}...",
180
- ha='center', va='center', wrap=True)
181
- plt.axis('off')
182
- error_path = os.path.join(temp_dir, "error_mindmap.png")
183
- plt.savefig(error_path, bbox_inches='tight', dpi=300)
184
- plt.close()
185
- return error_path
186
- except:
187
- return None
188
  @app.post("/summarize")
189
  def summarize_text(request: TextRequest):
190
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
@@ -223,16 +52,7 @@ def generate_word_cloud(request: TextRequest):
223
 
224
  # Gradio UI
225
  with gr.Blocks(theme=gr.themes.Soft(), css="""
226
- .mindmap-container img {
227
- max-height: none !important;
228
- min-width: 100% !important;
229
- object-fit: contain !important;
230
- background: white !important;
231
- border: 1px solid #e0e0e0 !important;
232
- border-radius: 8px !important;
233
- padding: 20px !important;
234
- }
235
- .gradio-container { max-width: 1400px !important; }
236
  """) as iface:
237
 
238
  gr.Markdown("# JFK Document Analysis Suite")
@@ -272,20 +92,7 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
272
  width=600
273
  )
274
 
275
- # Mind map section
276
- with gr.Row():
277
- mindmap_btn = gr.Button(
278
- "Generate Enhanced Mind Map",
279
- variant="primary"
280
- )
281
-
282
- with gr.Row():
283
- output_mindmap = gr.Image(
284
- label="High-Resolution Mind Map",
285
- elem_classes="mindmap-container",
286
- height=800,
287
- width=800
288
- )
289
 
290
  # Event handlers must be inside the Blocks context
291
  process_btn.click(
@@ -294,37 +101,6 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
294
  outputs=[full_doc_text, output_summary, output_entities, output_wordcloud]
295
  )
296
 
297
- def display_mindmap(text):
298
- try:
299
- img_path = generate_high_res_mindmap(text)
300
- if img_path and os.path.exists(img_path):
301
- return img_path
302
- return None
303
- except Exception as e:
304
- print(f"Display error: {e}")
305
- return None
306
-
307
- mindmap_btn.click(
308
- fn=display_mindmap,
309
- inputs=full_doc_text,
310
- outputs=output_mindmap,
311
- api_name="generate_mindmap",
312
- show_progress=True
313
- )
314
-
315
- # Add CSS for better image display
316
- css = """
317
- .mindmap-container img {
318
- max-width: 100% !important;
319
- height: auto !important;
320
- background: white !important;
321
- border: 2px solid #e0e0e0 !important;
322
- border-radius: 8px !important;
323
- padding: 10px !important;
324
- margin: 10px auto !important;
325
- display: block !important;
326
- }
327
- """
328
 
329
  if __name__ == "__main__":
330
  iface.launch(
 
6
  from wordcloud import WordCloud
7
  from summarization import summarizer
8
  from utils import list_files, process_file
 
 
9
 
10
  # Initialize FastAPI
11
  app = FastAPI()
 
14
  class TextRequest(BaseModel):
15
  text: str
16
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
  @app.post("/summarize")
18
  def summarize_text(request: TextRequest):
19
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
 
52
 
53
  # Gradio UI
54
  with gr.Blocks(theme=gr.themes.Soft(), css="""
55
+
 
 
 
 
 
 
 
 
 
56
  """) as iface:
57
 
58
  gr.Markdown("# JFK Document Analysis Suite")
 
92
  width=600
93
  )
94
 
95
+
 
 
 
 
 
 
 
 
 
 
 
 
 
96
 
97
  # Event handlers must be inside the Blocks context
98
  process_btn.click(
 
101
  outputs=[full_doc_text, output_summary, output_entities, output_wordcloud]
102
  )
103
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
104
 
105
  if __name__ == "__main__":
106
  iface.launch(
space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/app.py CHANGED
@@ -6,8 +6,6 @@ from entity_recognition import extract_entities
6
  from wordcloud import WordCloud
7
  from summarization import summarizer
8
  from utils import list_files, process_file
9
- import pygraphviz as pgv
10
- import os
11
 
12
  # Initialize FastAPI
13
  app = FastAPI()
@@ -16,175 +14,6 @@ app = FastAPI()
16
  class TextRequest(BaseModel):
17
  text: str
18
 
19
- def wrap_label(label, max_length=15):
20
- """Improved label wrapping with hyphenation awareness"""
21
- if len(label) <= max_length:
22
- return label
23
-
24
- # Try to break at natural points
25
- break_chars = [" ", "-", "_", "/"]
26
- lines = []
27
- current = ""
28
-
29
- for char in label:
30
- if len(current) >= max_length and char in break_chars:
31
- lines.append(current.strip())
32
- current = char
33
- else:
34
- current += char
35
-
36
- if current:
37
- lines.append(current.strip())
38
-
39
- return "\\n".join(lines)
40
- def generate_high_res_mindmap(text):
41
- """Generate high-quality mind map with improved visibility"""
42
- try:
43
- # Verify we have entities to visualize
44
- entities = extract_entities(text)
45
- if not any(entities.values()):
46
- print("No entities found to generate mind map")
47
- return None
48
-
49
- # Create temporary directory
50
- temp_dir = "/tmp/mindmaps"
51
- os.makedirs(temp_dir, exist_ok=True)
52
- output_path = os.path.join(temp_dir, "mindmap.png")
53
-
54
- # Create graph with optimized settings
55
- G = pgv.AGraph(
56
- directed=True,
57
- rankdir="TB", # Top-to-bottom layout
58
- bgcolor="white",
59
- fontname="Arial", # More readable font
60
- splines="ortho", # Straight lines
61
- overlap="false",
62
- concentrate="true",
63
- ratio="compress",
64
- size="50,50", # Larger canvas
65
- dpi="1000", # Higher resolution
66
- pad="1.0",
67
- nodesep="1.2", # More space between nodes
68
- ranksep="1.5" # More vertical space
69
- )
70
-
71
- # Enhanced node styling for better visibility
72
- G.node_attr.update({
73
- "fontsize": "24", # Larger font
74
- "fontname": "Arial Bold",
75
- "shape": "box",
76
- "style": "rounded,filled",
77
- "fillcolor": "#E1F5FE",
78
- "color": "#0288D1",
79
- "height": "0.8",
80
- "width": "2.0",
81
- "penwidth": "2.0",
82
- "margin": "0.3,0.1" # Better text padding
83
- })
84
-
85
- # Enhanced edge styling
86
- G.edge_attr.update({
87
- "color": "#616161",
88
- "penwidth": "2.5",
89
- "arrowsize": "1.2",
90
- "fontname": "Arial",
91
- "fontsize": "20",
92
- "fontcolor": "#424242"
93
- })
94
-
95
- # Add central node with improved styling
96
- G.add_node("DOCUMENT",
97
- shape="doubleoctagon",
98
- fillcolor="#4FC3F7",
99
- fontsize="28",
100
- width="2.5",
101
- height="1.0",
102
- penwidth="3.0")
103
-
104
- # Add entities with better spacing
105
- max_categories = 5
106
- max_entities = 8
107
-
108
- for cat_idx, (category, values) in enumerate(entities.items()):
109
- if cat_idx >= max_categories:
110
- break
111
-
112
- # Main category node
113
- cat_node = f"CAT_{cat_idx}"
114
- G.add_node(cat_node,
115
- label=wrap_label(category, 18),
116
- shape="tab",
117
- fillcolor="#81D4FA",
118
- fontsize="22")
119
-
120
- G.add_edge("DOCUMENT", cat_node,
121
- label="contains",
122
- penwidth="3.0")
123
-
124
- # Add entities with grouping if needed
125
- if len(values) > max_entities:
126
- # Create subcategory groups
127
- for sub_idx, group in enumerate([values[i:i+max_entities]
128
- for i in range(0, len(values), max_entities)]):
129
- sub_node = f"SUB_{cat_idx}_{sub_idx}"
130
- G.add_node(sub_node,
131
- label=f"Group {sub_idx+1}",
132
- shape="folder",
133
- fillcolor="#B3E5FC")
134
- G.add_edge(cat_node, sub_node)
135
-
136
- for ent_idx, value in enumerate(group):
137
- ent_node = f"ENT_{cat_idx}_{sub_idx}_{ent_idx}"
138
- G.add_node(ent_node,
139
- label=wrap_label(value, 15),
140
- shape="note",
141
- fillcolor="#E1F5FE")
142
- G.add_edge(sub_node, ent_node)
143
- else:
144
- # Directly add entities
145
- for ent_idx, value in enumerate(values[:max_entities]):
146
- ent_node = f"ENT_{cat_idx}_{ent_idx}"
147
- G.add_node(ent_node,
148
- label=wrap_label(value, 15),
149
- shape="note",
150
- fillcolor="#E1F5FE")
151
- G.add_edge(cat_node, ent_node)
152
-
153
- # Generate output with multiple attempts
154
- for engine in ['dot', 'neato', 'sfdp']:
155
- try:
156
- G.draw(output_path,
157
- format="png",
158
- prog=engine,
159
- args=f"-Gdpi=300 -Gsize=50,50 -Goverlap=prism")
160
- print(f"Successfully generated with {engine}")
161
-
162
- # Verify the output
163
- if os.path.exists(output_path) and os.path.getsize(output_path) > 0:
164
- return output_path
165
-
166
- except Exception as e:
167
- print(f"Layout engine {engine} failed: {str(e)}")
168
- continue
169
-
170
- raise RuntimeError("All layout engines failed")
171
-
172
- except Exception as e:
173
- print(f"Mind map generation failed: {str(e)}")
174
- # Create error visualization
175
- try:
176
- import matplotlib.pyplot as plt
177
- plt.figure(figsize=(20, 10))
178
- plt.text(0.5, 0.5,
179
- f"Mind Map Generation Failed\n{str(e)}\n\nOriginal Text:\n{text[:200]}...",
180
- ha='center', va='center', wrap=True)
181
- plt.axis('off')
182
- error_path = os.path.join(temp_dir, "error_mindmap.png")
183
- plt.savefig(error_path, bbox_inches='tight', dpi=300)
184
- plt.close()
185
- return error_path
186
- except:
187
- return None
188
  @app.post("/summarize")
189
  def summarize_text(request: TextRequest):
190
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
@@ -223,16 +52,7 @@ def generate_word_cloud(request: TextRequest):
223
 
224
  # Gradio UI
225
  with gr.Blocks(theme=gr.themes.Soft(), css="""
226
- .mindmap-container img {
227
- max-height: none !important;
228
- min-width: 100% !important;
229
- object-fit: contain !important;
230
- background: white !important;
231
- border: 1px solid #e0e0e0 !important;
232
- border-radius: 8px !important;
233
- padding: 20px !important;
234
- }
235
- .gradio-container { max-width: 1400px !important; }
236
  """) as iface:
237
 
238
  gr.Markdown("# JFK Document Analysis Suite")
@@ -272,20 +92,7 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
272
  width=600
273
  )
274
 
275
- # Mind map section
276
- with gr.Row():
277
- mindmap_btn = gr.Button(
278
- "Generate Enhanced Mind Map",
279
- variant="primary"
280
- )
281
-
282
- with gr.Row():
283
- output_mindmap = gr.Image(
284
- label="High-Resolution Mind Map",
285
- elem_classes="mindmap-container",
286
- height=800,
287
- width=800
288
- )
289
 
290
  # Event handlers must be inside the Blocks context
291
  process_btn.click(
@@ -294,37 +101,6 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
294
  outputs=[full_doc_text, output_summary, output_entities, output_wordcloud]
295
  )
296
 
297
- def display_mindmap(text):
298
- try:
299
- img_path = generate_high_res_mindmap(text)
300
- if img_path and os.path.exists(img_path):
301
- return img_path
302
- return None
303
- except Exception as e:
304
- print(f"Display error: {e}")
305
- return None
306
-
307
- mindmap_btn.click(
308
- fn=display_mindmap,
309
- inputs=full_doc_text,
310
- outputs=output_mindmap,
311
- api_name="generate_mindmap",
312
- show_progress=True
313
- )
314
-
315
- # Add CSS for better image display
316
- css = """
317
- .mindmap-container img {
318
- max-width: 100% !important;
319
- height: auto !important;
320
- background: white !important;
321
- border: 2px solid #e0e0e0 !important;
322
- border-radius: 8px !important;
323
- padding: 10px !important;
324
- margin: 10px auto !important;
325
- display: block !important;
326
- }
327
- """
328
 
329
  if __name__ == "__main__":
330
  iface.launch(
 
6
  from wordcloud import WordCloud
7
  from summarization import summarizer
8
  from utils import list_files, process_file
 
 
9
 
10
  # Initialize FastAPI
11
  app = FastAPI()
 
14
  class TextRequest(BaseModel):
15
  text: str
16
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
  @app.post("/summarize")
18
  def summarize_text(request: TextRequest):
19
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
 
52
 
53
  # Gradio UI
54
  with gr.Blocks(theme=gr.themes.Soft(), css="""
55
+
 
 
 
 
 
 
 
 
 
56
  """) as iface:
57
 
58
  gr.Markdown("# JFK Document Analysis Suite")
 
92
  width=600
93
  )
94
 
95
+
 
 
 
 
 
 
 
 
 
 
 
 
 
96
 
97
  # Event handlers must be inside the Blocks context
98
  process_btn.click(
 
101
  outputs=[full_doc_text, output_summary, output_entities, output_wordcloud]
102
  )
103
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
104
 
105
  if __name__ == "__main__":
106
  iface.launch(
space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/app.py CHANGED
@@ -6,8 +6,6 @@ from entity_recognition import extract_entities
6
  from wordcloud import WordCloud
7
  from summarization import summarizer
8
  from utils import list_files, process_file
9
- import pygraphviz as pgv
10
- import os
11
 
12
  # Initialize FastAPI
13
  app = FastAPI()
@@ -16,175 +14,6 @@ app = FastAPI()
16
  class TextRequest(BaseModel):
17
  text: str
18
 
19
- def wrap_label(label, max_length=15):
20
- """Improved label wrapping with hyphenation awareness"""
21
- if len(label) <= max_length:
22
- return label
23
-
24
- # Try to break at natural points
25
- break_chars = [" ", "-", "_", "/"]
26
- lines = []
27
- current = ""
28
-
29
- for char in label:
30
- if len(current) >= max_length and char in break_chars:
31
- lines.append(current.strip())
32
- current = char
33
- else:
34
- current += char
35
-
36
- if current:
37
- lines.append(current.strip())
38
-
39
- return "\\n".join(lines)
40
- def generate_high_res_mindmap(text):
41
- """Generate high-quality mind map with improved visibility"""
42
- try:
43
- # Verify we have entities to visualize
44
- entities = extract_entities(text)
45
- if not any(entities.values()):
46
- print("No entities found to generate mind map")
47
- return None
48
-
49
- # Create temporary directory
50
- temp_dir = "/tmp/mindmaps"
51
- os.makedirs(temp_dir, exist_ok=True)
52
- output_path = os.path.join(temp_dir, "mindmap.png")
53
-
54
- # Create graph with optimized settings
55
- G = pgv.AGraph(
56
- directed=True,
57
- rankdir="TB", # Top-to-bottom layout
58
- bgcolor="white",
59
- fontname="Arial", # More readable font
60
- splines="ortho", # Straight lines
61
- overlap="false",
62
- concentrate="true",
63
- ratio="compress",
64
- size="50,50", # Larger canvas
65
- dpi="1000", # Higher resolution
66
- pad="1.0",
67
- nodesep="1.2", # More space between nodes
68
- ranksep="1.5" # More vertical space
69
- )
70
-
71
- # Enhanced node styling for better visibility
72
- G.node_attr.update({
73
- "fontsize": "24", # Larger font
74
- "fontname": "Arial Bold",
75
- "shape": "box",
76
- "style": "rounded,filled",
77
- "fillcolor": "#E1F5FE",
78
- "color": "#0288D1",
79
- "height": "0.8",
80
- "width": "2.0",
81
- "penwidth": "2.0",
82
- "margin": "0.3,0.1" # Better text padding
83
- })
84
-
85
- # Enhanced edge styling
86
- G.edge_attr.update({
87
- "color": "#616161",
88
- "penwidth": "2.5",
89
- "arrowsize": "1.2",
90
- "fontname": "Arial",
91
- "fontsize": "20",
92
- "fontcolor": "#424242"
93
- })
94
-
95
- # Add central node with improved styling
96
- G.add_node("DOCUMENT",
97
- shape="doubleoctagon",
98
- fillcolor="#4FC3F7",
99
- fontsize="28",
100
- width="2.5",
101
- height="1.0",
102
- penwidth="3.0")
103
-
104
- # Add entities with better spacing
105
- max_categories = 5
106
- max_entities = 8
107
-
108
- for cat_idx, (category, values) in enumerate(entities.items()):
109
- if cat_idx >= max_categories:
110
- break
111
-
112
- # Main category node
113
- cat_node = f"CAT_{cat_idx}"
114
- G.add_node(cat_node,
115
- label=wrap_label(category, 18),
116
- shape="tab",
117
- fillcolor="#81D4FA",
118
- fontsize="22")
119
-
120
- G.add_edge("DOCUMENT", cat_node,
121
- label="contains",
122
- penwidth="3.0")
123
-
124
- # Add entities with grouping if needed
125
- if len(values) > max_entities:
126
- # Create subcategory groups
127
- for sub_idx, group in enumerate([values[i:i+max_entities]
128
- for i in range(0, len(values), max_entities)]):
129
- sub_node = f"SUB_{cat_idx}_{sub_idx}"
130
- G.add_node(sub_node,
131
- label=f"Group {sub_idx+1}",
132
- shape="folder",
133
- fillcolor="#B3E5FC")
134
- G.add_edge(cat_node, sub_node)
135
-
136
- for ent_idx, value in enumerate(group):
137
- ent_node = f"ENT_{cat_idx}_{sub_idx}_{ent_idx}"
138
- G.add_node(ent_node,
139
- label=wrap_label(value, 15),
140
- shape="note",
141
- fillcolor="#E1F5FE")
142
- G.add_edge(sub_node, ent_node)
143
- else:
144
- # Directly add entities
145
- for ent_idx, value in enumerate(values[:max_entities]):
146
- ent_node = f"ENT_{cat_idx}_{ent_idx}"
147
- G.add_node(ent_node,
148
- label=wrap_label(value, 15),
149
- shape="note",
150
- fillcolor="#E1F5FE")
151
- G.add_edge(cat_node, ent_node)
152
-
153
- # Generate output with multiple attempts
154
- for engine in ['dot', 'neato', 'sfdp']:
155
- try:
156
- G.draw(output_path,
157
- format="png",
158
- prog=engine,
159
- args=f"-Gdpi=300 -Gsize=50,50 -Goverlap=prism")
160
- print(f"Successfully generated with {engine}")
161
-
162
- # Verify the output
163
- if os.path.exists(output_path) and os.path.getsize(output_path) > 0:
164
- return output_path
165
-
166
- except Exception as e:
167
- print(f"Layout engine {engine} failed: {str(e)}")
168
- continue
169
-
170
- raise RuntimeError("All layout engines failed")
171
-
172
- except Exception as e:
173
- print(f"Mind map generation failed: {str(e)}")
174
- # Create error visualization
175
- try:
176
- import matplotlib.pyplot as plt
177
- plt.figure(figsize=(20, 10))
178
- plt.text(0.5, 0.5,
179
- f"Mind Map Generation Failed\n{str(e)}\n\nOriginal Text:\n{text[:200]}...",
180
- ha='center', va='center', wrap=True)
181
- plt.axis('off')
182
- error_path = os.path.join(temp_dir, "error_mindmap.png")
183
- plt.savefig(error_path, bbox_inches='tight', dpi=300)
184
- plt.close()
185
- return error_path
186
- except:
187
- return None
188
  @app.post("/summarize")
189
  def summarize_text(request: TextRequest):
190
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
@@ -223,16 +52,7 @@ def generate_word_cloud(request: TextRequest):
223
 
224
  # Gradio UI
225
  with gr.Blocks(theme=gr.themes.Soft(), css="""
226
- .mindmap-container img {
227
- max-height: none !important;
228
- min-width: 100% !important;
229
- object-fit: contain !important;
230
- background: white !important;
231
- border: 1px solid #e0e0e0 !important;
232
- border-radius: 8px !important;
233
- padding: 20px !important;
234
- }
235
- .gradio-container { max-width: 1400px !important; }
236
  """) as iface:
237
 
238
  gr.Markdown("# JFK Document Analysis Suite")
@@ -272,20 +92,7 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
272
  width=600
273
  )
274
 
275
- # Mind map section
276
- with gr.Row():
277
- mindmap_btn = gr.Button(
278
- "Generate Enhanced Mind Map",
279
- variant="primary"
280
- )
281
-
282
- with gr.Row():
283
- output_mindmap = gr.Image(
284
- label="High-Resolution Mind Map",
285
- elem_classes="mindmap-container",
286
- height=800,
287
- width=800
288
- )
289
 
290
  # Event handlers must be inside the Blocks context
291
  process_btn.click(
@@ -294,37 +101,6 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
294
  outputs=[full_doc_text, output_summary, output_entities, output_wordcloud]
295
  )
296
 
297
- def display_mindmap(text):
298
- try:
299
- img_path = generate_high_res_mindmap(text)
300
- if img_path and os.path.exists(img_path):
301
- return img_path
302
- return None
303
- except Exception as e:
304
- print(f"Display error: {e}")
305
- return None
306
-
307
- mindmap_btn.click(
308
- fn=display_mindmap,
309
- inputs=full_doc_text,
310
- outputs=output_mindmap,
311
- api_name="generate_mindmap",
312
- show_progress=True
313
- )
314
-
315
- # Add CSS for better image display
316
- css = """
317
- .mindmap-container img {
318
- max-width: 100% !important;
319
- height: auto !important;
320
- background: white !important;
321
- border: 2px solid #e0e0e0 !important;
322
- border-radius: 8px !important;
323
- padding: 10px !important;
324
- margin: 10px auto !important;
325
- display: block !important;
326
- }
327
- """
328
 
329
  if __name__ == "__main__":
330
  iface.launch(
 
6
  from wordcloud import WordCloud
7
  from summarization import summarizer
8
  from utils import list_files, process_file
 
 
9
 
10
  # Initialize FastAPI
11
  app = FastAPI()
 
14
  class TextRequest(BaseModel):
15
  text: str
16
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
  @app.post("/summarize")
18
  def summarize_text(request: TextRequest):
19
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
 
52
 
53
  # Gradio UI
54
  with gr.Blocks(theme=gr.themes.Soft(), css="""
55
+
 
 
 
 
 
 
 
 
 
56
  """) as iface:
57
 
58
  gr.Markdown("# JFK Document Analysis Suite")
 
92
  width=600
93
  )
94
 
95
+
 
 
 
 
 
 
 
 
 
 
 
 
 
96
 
97
  # Event handlers must be inside the Blocks context
98
  process_btn.click(
 
101
  outputs=[full_doc_text, output_summary, output_entities, output_wordcloud]
102
  )
103
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
104
 
105
  if __name__ == "__main__":
106
  iface.launch(
space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/app.py CHANGED
@@ -6,8 +6,6 @@ from entity_recognition import extract_entities
6
  from wordcloud import WordCloud
7
  from summarization import summarizer
8
  from utils import list_files, process_file
9
- import pygraphviz as pgv
10
- import os
11
 
12
  # Initialize FastAPI
13
  app = FastAPI()
@@ -16,175 +14,6 @@ app = FastAPI()
16
  class TextRequest(BaseModel):
17
  text: str
18
 
19
- def wrap_label(label, max_length=15):
20
- """Improved label wrapping with hyphenation awareness"""
21
- if len(label) <= max_length:
22
- return label
23
-
24
- # Try to break at natural points
25
- break_chars = [" ", "-", "_", "/"]
26
- lines = []
27
- current = ""
28
-
29
- for char in label:
30
- if len(current) >= max_length and char in break_chars:
31
- lines.append(current.strip())
32
- current = char
33
- else:
34
- current += char
35
-
36
- if current:
37
- lines.append(current.strip())
38
-
39
- return "\\n".join(lines)
40
- def generate_high_res_mindmap(text):
41
- """Generate high-quality mind map with improved visibility"""
42
- try:
43
- # Verify we have entities to visualize
44
- entities = extract_entities(text)
45
- if not any(entities.values()):
46
- print("No entities found to generate mind map")
47
- return None
48
-
49
- # Create temporary directory
50
- temp_dir = "/tmp/mindmaps"
51
- os.makedirs(temp_dir, exist_ok=True)
52
- output_path = os.path.join(temp_dir, "mindmap.png")
53
-
54
- # Create graph with optimized settings
55
- G = pgv.AGraph(
56
- directed=True,
57
- rankdir="TB", # Top-to-bottom layout
58
- bgcolor="white",
59
- fontname="Arial", # More readable font
60
- splines="ortho", # Straight lines
61
- overlap="false",
62
- concentrate="true",
63
- ratio="compress",
64
- size="50,50", # Larger canvas
65
- dpi="1000", # Higher resolution
66
- pad="1.0",
67
- nodesep="1.2", # More space between nodes
68
- ranksep="1.5" # More vertical space
69
- )
70
-
71
- # Enhanced node styling for better visibility
72
- G.node_attr.update({
73
- "fontsize": "24", # Larger font
74
- "fontname": "Arial Bold",
75
- "shape": "box",
76
- "style": "rounded,filled",
77
- "fillcolor": "#E1F5FE",
78
- "color": "#0288D1",
79
- "height": "0.8",
80
- "width": "2.0",
81
- "penwidth": "2.0",
82
- "margin": "0.3,0.1" # Better text padding
83
- })
84
-
85
- # Enhanced edge styling
86
- G.edge_attr.update({
87
- "color": "#616161",
88
- "penwidth": "2.5",
89
- "arrowsize": "1.2",
90
- "fontname": "Arial",
91
- "fontsize": "20",
92
- "fontcolor": "#424242"
93
- })
94
-
95
- # Add central node with improved styling
96
- G.add_node("DOCUMENT",
97
- shape="doubleoctagon",
98
- fillcolor="#4FC3F7",
99
- fontsize="28",
100
- width="2.5",
101
- height="1.0",
102
- penwidth="3.0")
103
-
104
- # Add entities with better spacing
105
- max_categories = 5
106
- max_entities = 8
107
-
108
- for cat_idx, (category, values) in enumerate(entities.items()):
109
- if cat_idx >= max_categories:
110
- break
111
-
112
- # Main category node
113
- cat_node = f"CAT_{cat_idx}"
114
- G.add_node(cat_node,
115
- label=wrap_label(category, 18),
116
- shape="tab",
117
- fillcolor="#81D4FA",
118
- fontsize="22")
119
-
120
- G.add_edge("DOCUMENT", cat_node,
121
- label="contains",
122
- penwidth="3.0")
123
-
124
- # Add entities with grouping if needed
125
- if len(values) > max_entities:
126
- # Create subcategory groups
127
- for sub_idx, group in enumerate([values[i:i+max_entities]
128
- for i in range(0, len(values), max_entities)]):
129
- sub_node = f"SUB_{cat_idx}_{sub_idx}"
130
- G.add_node(sub_node,
131
- label=f"Group {sub_idx+1}",
132
- shape="folder",
133
- fillcolor="#B3E5FC")
134
- G.add_edge(cat_node, sub_node)
135
-
136
- for ent_idx, value in enumerate(group):
137
- ent_node = f"ENT_{cat_idx}_{sub_idx}_{ent_idx}"
138
- G.add_node(ent_node,
139
- label=wrap_label(value, 15),
140
- shape="note",
141
- fillcolor="#E1F5FE")
142
- G.add_edge(sub_node, ent_node)
143
- else:
144
- # Directly add entities
145
- for ent_idx, value in enumerate(values[:max_entities]):
146
- ent_node = f"ENT_{cat_idx}_{ent_idx}"
147
- G.add_node(ent_node,
148
- label=wrap_label(value, 15),
149
- shape="note",
150
- fillcolor="#E1F5FE")
151
- G.add_edge(cat_node, ent_node)
152
-
153
- # Generate output with multiple attempts
154
- for engine in ['dot', 'neato', 'sfdp']:
155
- try:
156
- G.draw(output_path,
157
- format="png",
158
- prog=engine,
159
- args=f"-Gdpi=300 -Gsize=50,50 -Goverlap=prism")
160
- print(f"Successfully generated with {engine}")
161
-
162
- # Verify the output
163
- if os.path.exists(output_path) and os.path.getsize(output_path) > 0:
164
- return output_path
165
-
166
- except Exception as e:
167
- print(f"Layout engine {engine} failed: {str(e)}")
168
- continue
169
-
170
- raise RuntimeError("All layout engines failed")
171
-
172
- except Exception as e:
173
- print(f"Mind map generation failed: {str(e)}")
174
- # Create error visualization
175
- try:
176
- import matplotlib.pyplot as plt
177
- plt.figure(figsize=(20, 10))
178
- plt.text(0.5, 0.5,
179
- f"Mind Map Generation Failed\n{str(e)}\n\nOriginal Text:\n{text[:200]}...",
180
- ha='center', va='center', wrap=True)
181
- plt.axis('off')
182
- error_path = os.path.join(temp_dir, "error_mindmap.png")
183
- plt.savefig(error_path, bbox_inches='tight', dpi=300)
184
- plt.close()
185
- return error_path
186
- except:
187
- return None
188
  @app.post("/summarize")
189
  def summarize_text(request: TextRequest):
190
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
@@ -223,16 +52,7 @@ def generate_word_cloud(request: TextRequest):
223
 
224
  # Gradio UI
225
  with gr.Blocks(theme=gr.themes.Soft(), css="""
226
- .mindmap-container img {
227
- max-height: none !important;
228
- min-width: 100% !important;
229
- object-fit: contain !important;
230
- background: white !important;
231
- border: 1px solid #e0e0e0 !important;
232
- border-radius: 8px !important;
233
- padding: 20px !important;
234
- }
235
- .gradio-container { max-width: 1400px !important; }
236
  """) as iface:
237
 
238
  gr.Markdown("# JFK Document Analysis Suite")
@@ -272,20 +92,7 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
272
  width=600
273
  )
274
 
275
- # Mind map section
276
- with gr.Row():
277
- mindmap_btn = gr.Button(
278
- "Generate Enhanced Mind Map",
279
- variant="primary"
280
- )
281
-
282
- with gr.Row():
283
- output_mindmap = gr.Image(
284
- label="High-Resolution Mind Map",
285
- elem_classes="mindmap-container",
286
- height=800,
287
- width=800
288
- )
289
 
290
  # Event handlers must be inside the Blocks context
291
  process_btn.click(
@@ -294,37 +101,6 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
294
  outputs=[full_doc_text, output_summary, output_entities, output_wordcloud]
295
  )
296
 
297
- def display_mindmap(text):
298
- try:
299
- img_path = generate_high_res_mindmap(text)
300
- if img_path and os.path.exists(img_path):
301
- return img_path
302
- return None
303
- except Exception as e:
304
- print(f"Display error: {e}")
305
- return None
306
-
307
- mindmap_btn.click(
308
- fn=display_mindmap,
309
- inputs=full_doc_text,
310
- outputs=output_mindmap,
311
- api_name="generate_mindmap",
312
- show_progress=True
313
- )
314
-
315
- # Add CSS for better image display
316
- css = """
317
- .mindmap-container img {
318
- max-width: 100% !important;
319
- height: auto !important;
320
- background: white !important;
321
- border: 2px solid #e0e0e0 !important;
322
- border-radius: 8px !important;
323
- padding: 10px !important;
324
- margin: 10px auto !important;
325
- display: block !important;
326
- }
327
- """
328
 
329
  if __name__ == "__main__":
330
  iface.launch(
 
6
  from wordcloud import WordCloud
7
  from summarization import summarizer
8
  from utils import list_files, process_file
 
 
9
 
10
  # Initialize FastAPI
11
  app = FastAPI()
 
14
  class TextRequest(BaseModel):
15
  text: str
16
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
  @app.post("/summarize")
18
  def summarize_text(request: TextRequest):
19
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
 
52
 
53
  # Gradio UI
54
  with gr.Blocks(theme=gr.themes.Soft(), css="""
55
+
 
 
 
 
 
 
 
 
 
56
  """) as iface:
57
 
58
  gr.Markdown("# JFK Document Analysis Suite")
 
92
  width=600
93
  )
94
 
95
+
 
 
 
 
 
 
 
 
 
 
 
 
 
96
 
97
  # Event handlers must be inside the Blocks context
98
  process_btn.click(
 
101
  outputs=[full_doc_text, output_summary, output_entities, output_wordcloud]
102
  )
103
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
104
 
105
  if __name__ == "__main__":
106
  iface.launch(
space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/app.py CHANGED
@@ -6,8 +6,6 @@ from entity_recognition import extract_entities
6
  from wordcloud import WordCloud
7
  from summarization import summarizer
8
  from utils import list_files, process_file
9
- import pygraphviz as pgv
10
- import os
11
 
12
  # Initialize FastAPI
13
  app = FastAPI()
@@ -16,175 +14,6 @@ app = FastAPI()
16
  class TextRequest(BaseModel):
17
  text: str
18
 
19
- def wrap_label(label, max_length=15):
20
- """Improved label wrapping with hyphenation awareness"""
21
- if len(label) <= max_length:
22
- return label
23
-
24
- # Try to break at natural points
25
- break_chars = [" ", "-", "_", "/"]
26
- lines = []
27
- current = ""
28
-
29
- for char in label:
30
- if len(current) >= max_length and char in break_chars:
31
- lines.append(current.strip())
32
- current = char
33
- else:
34
- current += char
35
-
36
- if current:
37
- lines.append(current.strip())
38
-
39
- return "\\n".join(lines)
40
- def generate_high_res_mindmap(text):
41
- """Generate high-quality mind map with improved visibility"""
42
- try:
43
- # Verify we have entities to visualize
44
- entities = extract_entities(text)
45
- if not any(entities.values()):
46
- print("No entities found to generate mind map")
47
- return None
48
-
49
- # Create temporary directory
50
- temp_dir = "/tmp/mindmaps"
51
- os.makedirs(temp_dir, exist_ok=True)
52
- output_path = os.path.join(temp_dir, "mindmap.png")
53
-
54
- # Create graph with optimized settings
55
- G = pgv.AGraph(
56
- directed=True,
57
- rankdir="TB", # Top-to-bottom layout
58
- bgcolor="white",
59
- fontname="Arial", # More readable font
60
- splines="ortho", # Straight lines
61
- overlap="false",
62
- concentrate="true",
63
- ratio="compress",
64
- size="50,50", # Larger canvas
65
- dpi="1000", # Higher resolution
66
- pad="1.0",
67
- nodesep="1.2", # More space between nodes
68
- ranksep="1.5" # More vertical space
69
- )
70
-
71
- # Enhanced node styling for better visibility
72
- G.node_attr.update({
73
- "fontsize": "24", # Larger font
74
- "fontname": "Arial Bold",
75
- "shape": "box",
76
- "style": "rounded,filled",
77
- "fillcolor": "#E1F5FE",
78
- "color": "#0288D1",
79
- "height": "0.8",
80
- "width": "2.0",
81
- "penwidth": "2.0",
82
- "margin": "0.3,0.1" # Better text padding
83
- })
84
-
85
- # Enhanced edge styling
86
- G.edge_attr.update({
87
- "color": "#616161",
88
- "penwidth": "2.5",
89
- "arrowsize": "1.2",
90
- "fontname": "Arial",
91
- "fontsize": "20",
92
- "fontcolor": "#424242"
93
- })
94
-
95
- # Add central node with improved styling
96
- G.add_node("DOCUMENT",
97
- shape="doubleoctagon",
98
- fillcolor="#4FC3F7",
99
- fontsize="28",
100
- width="2.5",
101
- height="1.0",
102
- penwidth="3.0")
103
-
104
- # Add entities with better spacing
105
- max_categories = 5
106
- max_entities = 8
107
-
108
- for cat_idx, (category, values) in enumerate(entities.items()):
109
- if cat_idx >= max_categories:
110
- break
111
-
112
- # Main category node
113
- cat_node = f"CAT_{cat_idx}"
114
- G.add_node(cat_node,
115
- label=wrap_label(category, 18),
116
- shape="tab",
117
- fillcolor="#81D4FA",
118
- fontsize="22")
119
-
120
- G.add_edge("DOCUMENT", cat_node,
121
- label="contains",
122
- penwidth="3.0")
123
-
124
- # Add entities with grouping if needed
125
- if len(values) > max_entities:
126
- # Create subcategory groups
127
- for sub_idx, group in enumerate([values[i:i+max_entities]
128
- for i in range(0, len(values), max_entities)]):
129
- sub_node = f"SUB_{cat_idx}_{sub_idx}"
130
- G.add_node(sub_node,
131
- label=f"Group {sub_idx+1}",
132
- shape="folder",
133
- fillcolor="#B3E5FC")
134
- G.add_edge(cat_node, sub_node)
135
-
136
- for ent_idx, value in enumerate(group):
137
- ent_node = f"ENT_{cat_idx}_{sub_idx}_{ent_idx}"
138
- G.add_node(ent_node,
139
- label=wrap_label(value, 15),
140
- shape="note",
141
- fillcolor="#E1F5FE")
142
- G.add_edge(sub_node, ent_node)
143
- else:
144
- # Directly add entities
145
- for ent_idx, value in enumerate(values[:max_entities]):
146
- ent_node = f"ENT_{cat_idx}_{ent_idx}"
147
- G.add_node(ent_node,
148
- label=wrap_label(value, 15),
149
- shape="note",
150
- fillcolor="#E1F5FE")
151
- G.add_edge(cat_node, ent_node)
152
-
153
- # Generate output with multiple attempts
154
- for engine in ['dot', 'neato', 'sfdp']:
155
- try:
156
- G.draw(output_path,
157
- format="png",
158
- prog=engine,
159
- args=f"-Gdpi=300 -Gsize=50,50 -Goverlap=prism")
160
- print(f"Successfully generated with {engine}")
161
-
162
- # Verify the output
163
- if os.path.exists(output_path) and os.path.getsize(output_path) > 0:
164
- return output_path
165
-
166
- except Exception as e:
167
- print(f"Layout engine {engine} failed: {str(e)}")
168
- continue
169
-
170
- raise RuntimeError("All layout engines failed")
171
-
172
- except Exception as e:
173
- print(f"Mind map generation failed: {str(e)}")
174
- # Create error visualization
175
- try:
176
- import matplotlib.pyplot as plt
177
- plt.figure(figsize=(20, 10))
178
- plt.text(0.5, 0.5,
179
- f"Mind Map Generation Failed\n{str(e)}\n\nOriginal Text:\n{text[:200]}...",
180
- ha='center', va='center', wrap=True)
181
- plt.axis('off')
182
- error_path = os.path.join(temp_dir, "error_mindmap.png")
183
- plt.savefig(error_path, bbox_inches='tight', dpi=300)
184
- plt.close()
185
- return error_path
186
- except:
187
- return None
188
  @app.post("/summarize")
189
  def summarize_text(request: TextRequest):
190
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
@@ -223,16 +52,7 @@ def generate_word_cloud(request: TextRequest):
223
 
224
  # Gradio UI
225
  with gr.Blocks(theme=gr.themes.Soft(), css="""
226
- .mindmap-container img {
227
- max-height: none !important;
228
- min-width: 100% !important;
229
- object-fit: contain !important;
230
- background: white !important;
231
- border: 1px solid #e0e0e0 !important;
232
- border-radius: 8px !important;
233
- padding: 20px !important;
234
- }
235
- .gradio-container { max-width: 1400px !important; }
236
  """) as iface:
237
 
238
  gr.Markdown("# JFK Document Analysis Suite")
@@ -272,20 +92,7 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
272
  width=600
273
  )
274
 
275
- # Mind map section
276
- with gr.Row():
277
- mindmap_btn = gr.Button(
278
- "Generate Enhanced Mind Map",
279
- variant="primary"
280
- )
281
-
282
- with gr.Row():
283
- output_mindmap = gr.Image(
284
- label="High-Resolution Mind Map",
285
- elem_classes="mindmap-container",
286
- height=800,
287
- width=800
288
- )
289
 
290
  # Event handlers must be inside the Blocks context
291
  process_btn.click(
@@ -294,37 +101,6 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
294
  outputs=[full_doc_text, output_summary, output_entities, output_wordcloud]
295
  )
296
 
297
- def display_mindmap(text):
298
- try:
299
- img_path = generate_high_res_mindmap(text)
300
- if img_path and os.path.exists(img_path):
301
- return img_path
302
- return None
303
- except Exception as e:
304
- print(f"Display error: {e}")
305
- return None
306
-
307
- mindmap_btn.click(
308
- fn=display_mindmap,
309
- inputs=full_doc_text,
310
- outputs=output_mindmap,
311
- api_name="generate_mindmap",
312
- show_progress=True
313
- )
314
-
315
- # Add CSS for better image display
316
- css = """
317
- .mindmap-container img {
318
- max-width: 100% !important;
319
- height: auto !important;
320
- background: white !important;
321
- border: 2px solid #e0e0e0 !important;
322
- border-radius: 8px !important;
323
- padding: 10px !important;
324
- margin: 10px auto !important;
325
- display: block !important;
326
- }
327
- """
328
 
329
  if __name__ == "__main__":
330
  iface.launch(
 
6
  from wordcloud import WordCloud
7
  from summarization import summarizer
8
  from utils import list_files, process_file
 
 
9
 
10
  # Initialize FastAPI
11
  app = FastAPI()
 
14
  class TextRequest(BaseModel):
15
  text: str
16
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
  @app.post("/summarize")
18
  def summarize_text(request: TextRequest):
19
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
 
52
 
53
  # Gradio UI
54
  with gr.Blocks(theme=gr.themes.Soft(), css="""
55
+
 
 
 
 
 
 
 
 
 
56
  """) as iface:
57
 
58
  gr.Markdown("# JFK Document Analysis Suite")
 
92
  width=600
93
  )
94
 
95
+
 
 
 
 
 
 
 
 
 
 
 
 
 
96
 
97
  # Event handlers must be inside the Blocks context
98
  process_btn.click(
 
101
  outputs=[full_doc_text, output_summary, output_entities, output_wordcloud]
102
  )
103
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
104
 
105
  if __name__ == "__main__":
106
  iface.launch(
space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/app.py CHANGED
@@ -6,8 +6,6 @@ from entity_recognition import extract_entities
6
  from wordcloud import WordCloud
7
  from summarization import summarizer
8
  from utils import list_files, process_file
9
- import pygraphviz as pgv
10
- import os
11
 
12
  # Initialize FastAPI
13
  app = FastAPI()
@@ -16,175 +14,6 @@ app = FastAPI()
16
  class TextRequest(BaseModel):
17
  text: str
18
 
19
- def wrap_label(label, max_length=15):
20
- """Improved label wrapping with hyphenation awareness"""
21
- if len(label) <= max_length:
22
- return label
23
-
24
- # Try to break at natural points
25
- break_chars = [" ", "-", "_", "/"]
26
- lines = []
27
- current = ""
28
-
29
- for char in label:
30
- if len(current) >= max_length and char in break_chars:
31
- lines.append(current.strip())
32
- current = char
33
- else:
34
- current += char
35
-
36
- if current:
37
- lines.append(current.strip())
38
-
39
- return "\\n".join(lines)
40
- def generate_high_res_mindmap(text):
41
- """Generate high-quality mind map with improved visibility"""
42
- try:
43
- # Verify we have entities to visualize
44
- entities = extract_entities(text)
45
- if not any(entities.values()):
46
- print("No entities found to generate mind map")
47
- return None
48
-
49
- # Create temporary directory
50
- temp_dir = "/tmp/mindmaps"
51
- os.makedirs(temp_dir, exist_ok=True)
52
- output_path = os.path.join(temp_dir, "mindmap.png")
53
-
54
- # Create graph with optimized settings
55
- G = pgv.AGraph(
56
- directed=True,
57
- rankdir="TB", # Top-to-bottom layout
58
- bgcolor="white",
59
- fontname="Arial", # More readable font
60
- splines="ortho", # Straight lines
61
- overlap="false",
62
- concentrate="true",
63
- ratio="compress",
64
- size="50,50", # Larger canvas
65
- dpi="1000", # Higher resolution
66
- pad="1.0",
67
- nodesep="1.2", # More space between nodes
68
- ranksep="1.5" # More vertical space
69
- )
70
-
71
- # Enhanced node styling for better visibility
72
- G.node_attr.update({
73
- "fontsize": "24", # Larger font
74
- "fontname": "Arial Bold",
75
- "shape": "box",
76
- "style": "rounded,filled",
77
- "fillcolor": "#E1F5FE",
78
- "color": "#0288D1",
79
- "height": "0.8",
80
- "width": "2.0",
81
- "penwidth": "2.0",
82
- "margin": "0.3,0.1" # Better text padding
83
- })
84
-
85
- # Enhanced edge styling
86
- G.edge_attr.update({
87
- "color": "#616161",
88
- "penwidth": "2.5",
89
- "arrowsize": "1.2",
90
- "fontname": "Arial",
91
- "fontsize": "20",
92
- "fontcolor": "#424242"
93
- })
94
-
95
- # Add central node with improved styling
96
- G.add_node("DOCUMENT",
97
- shape="doubleoctagon",
98
- fillcolor="#4FC3F7",
99
- fontsize="28",
100
- width="2.5",
101
- height="1.0",
102
- penwidth="3.0")
103
-
104
- # Add entities with better spacing
105
- max_categories = 5
106
- max_entities = 8
107
-
108
- for cat_idx, (category, values) in enumerate(entities.items()):
109
- if cat_idx >= max_categories:
110
- break
111
-
112
- # Main category node
113
- cat_node = f"CAT_{cat_idx}"
114
- G.add_node(cat_node,
115
- label=wrap_label(category, 18),
116
- shape="tab",
117
- fillcolor="#81D4FA",
118
- fontsize="22")
119
-
120
- G.add_edge("DOCUMENT", cat_node,
121
- label="contains",
122
- penwidth="3.0")
123
-
124
- # Add entities with grouping if needed
125
- if len(values) > max_entities:
126
- # Create subcategory groups
127
- for sub_idx, group in enumerate([values[i:i+max_entities]
128
- for i in range(0, len(values), max_entities)]):
129
- sub_node = f"SUB_{cat_idx}_{sub_idx}"
130
- G.add_node(sub_node,
131
- label=f"Group {sub_idx+1}",
132
- shape="folder",
133
- fillcolor="#B3E5FC")
134
- G.add_edge(cat_node, sub_node)
135
-
136
- for ent_idx, value in enumerate(group):
137
- ent_node = f"ENT_{cat_idx}_{sub_idx}_{ent_idx}"
138
- G.add_node(ent_node,
139
- label=wrap_label(value, 15),
140
- shape="note",
141
- fillcolor="#E1F5FE")
142
- G.add_edge(sub_node, ent_node)
143
- else:
144
- # Directly add entities
145
- for ent_idx, value in enumerate(values[:max_entities]):
146
- ent_node = f"ENT_{cat_idx}_{ent_idx}"
147
- G.add_node(ent_node,
148
- label=wrap_label(value, 15),
149
- shape="note",
150
- fillcolor="#E1F5FE")
151
- G.add_edge(cat_node, ent_node)
152
-
153
- # Generate output with multiple attempts
154
- for engine in ['dot', 'neato', 'sfdp']:
155
- try:
156
- G.draw(output_path,
157
- format="png",
158
- prog=engine,
159
- args=f"-Gdpi=300 -Gsize=50,50 -Goverlap=prism")
160
- print(f"Successfully generated with {engine}")
161
-
162
- # Verify the output
163
- if os.path.exists(output_path) and os.path.getsize(output_path) > 0:
164
- return output_path
165
-
166
- except Exception as e:
167
- print(f"Layout engine {engine} failed: {str(e)}")
168
- continue
169
-
170
- raise RuntimeError("All layout engines failed")
171
-
172
- except Exception as e:
173
- print(f"Mind map generation failed: {str(e)}")
174
- # Create error visualization
175
- try:
176
- import matplotlib.pyplot as plt
177
- plt.figure(figsize=(20, 10))
178
- plt.text(0.5, 0.5,
179
- f"Mind Map Generation Failed\n{str(e)}\n\nOriginal Text:\n{text[:200]}...",
180
- ha='center', va='center', wrap=True)
181
- plt.axis('off')
182
- error_path = os.path.join(temp_dir, "error_mindmap.png")
183
- plt.savefig(error_path, bbox_inches='tight', dpi=300)
184
- plt.close()
185
- return error_path
186
- except:
187
- return None
188
  @app.post("/summarize")
189
  def summarize_text(request: TextRequest):
190
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
@@ -223,16 +52,7 @@ def generate_word_cloud(request: TextRequest):
223
 
224
  # Gradio UI
225
  with gr.Blocks(theme=gr.themes.Soft(), css="""
226
- .mindmap-container img {
227
- max-height: none !important;
228
- min-width: 100% !important;
229
- object-fit: contain !important;
230
- background: white !important;
231
- border: 1px solid #e0e0e0 !important;
232
- border-radius: 8px !important;
233
- padding: 20px !important;
234
- }
235
- .gradio-container { max-width: 1400px !important; }
236
  """) as iface:
237
 
238
  gr.Markdown("# JFK Document Analysis Suite")
@@ -272,20 +92,7 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
272
  width=600
273
  )
274
 
275
- # Mind map section
276
- with gr.Row():
277
- mindmap_btn = gr.Button(
278
- "Generate Enhanced Mind Map",
279
- variant="primary"
280
- )
281
-
282
- with gr.Row():
283
- output_mindmap = gr.Image(
284
- label="High-Resolution Mind Map",
285
- elem_classes="mindmap-container",
286
- height=800,
287
- width=800
288
- )
289
 
290
  # Event handlers must be inside the Blocks context
291
  process_btn.click(
@@ -294,37 +101,6 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
294
  outputs=[full_doc_text, output_summary, output_entities, output_wordcloud]
295
  )
296
 
297
- def display_mindmap(text):
298
- try:
299
- img_path = generate_high_res_mindmap(text)
300
- if img_path and os.path.exists(img_path):
301
- return img_path
302
- return None
303
- except Exception as e:
304
- print(f"Display error: {e}")
305
- return None
306
-
307
- mindmap_btn.click(
308
- fn=display_mindmap,
309
- inputs=full_doc_text,
310
- outputs=output_mindmap,
311
- api_name="generate_mindmap",
312
- show_progress=True
313
- )
314
-
315
- # Add CSS for better image display
316
- css = """
317
- .mindmap-container img {
318
- max-width: 100% !important;
319
- height: auto !important;
320
- background: white !important;
321
- border: 2px solid #e0e0e0 !important;
322
- border-radius: 8px !important;
323
- padding: 10px !important;
324
- margin: 10px auto !important;
325
- display: block !important;
326
- }
327
- """
328
 
329
  if __name__ == "__main__":
330
  iface.launch(
 
6
  from wordcloud import WordCloud
7
  from summarization import summarizer
8
  from utils import list_files, process_file
 
 
9
 
10
  # Initialize FastAPI
11
  app = FastAPI()
 
14
  class TextRequest(BaseModel):
15
  text: str
16
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
  @app.post("/summarize")
18
  def summarize_text(request: TextRequest):
19
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
 
52
 
53
  # Gradio UI
54
  with gr.Blocks(theme=gr.themes.Soft(), css="""
55
+
 
 
 
 
 
 
 
 
 
56
  """) as iface:
57
 
58
  gr.Markdown("# JFK Document Analysis Suite")
 
92
  width=600
93
  )
94
 
95
+
 
 
 
 
 
 
 
 
 
 
 
 
 
96
 
97
  # Event handlers must be inside the Blocks context
98
  process_btn.click(
 
101
  outputs=[full_doc_text, output_summary, output_entities, output_wordcloud]
102
  )
103
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
104
 
105
  if __name__ == "__main__":
106
  iface.launch(
space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/app.py CHANGED
@@ -6,8 +6,6 @@ from entity_recognition import extract_entities
6
  from wordcloud import WordCloud
7
  from summarization import summarizer
8
  from utils import list_files, process_file
9
- import pygraphviz as pgv
10
- import os
11
 
12
  # Initialize FastAPI
13
  app = FastAPI()
@@ -16,175 +14,6 @@ app = FastAPI()
16
  class TextRequest(BaseModel):
17
  text: str
18
 
19
- def wrap_label(label, max_length=15):
20
- """Improved label wrapping with hyphenation awareness"""
21
- if len(label) <= max_length:
22
- return label
23
-
24
- # Try to break at natural points
25
- break_chars = [" ", "-", "_", "/"]
26
- lines = []
27
- current = ""
28
-
29
- for char in label:
30
- if len(current) >= max_length and char in break_chars:
31
- lines.append(current.strip())
32
- current = char
33
- else:
34
- current += char
35
-
36
- if current:
37
- lines.append(current.strip())
38
-
39
- return "\\n".join(lines)
40
- def generate_high_res_mindmap(text):
41
- """Generate high-quality mind map with improved visibility"""
42
- try:
43
- # Verify we have entities to visualize
44
- entities = extract_entities(text)
45
- if not any(entities.values()):
46
- print("No entities found to generate mind map")
47
- return None
48
-
49
- # Create temporary directory
50
- temp_dir = "/tmp/mindmaps"
51
- os.makedirs(temp_dir, exist_ok=True)
52
- output_path = os.path.join(temp_dir, "mindmap.png")
53
-
54
- # Create graph with optimized settings
55
- G = pgv.AGraph(
56
- directed=True,
57
- rankdir="TB", # Top-to-bottom layout
58
- bgcolor="white",
59
- fontname="Arial", # More readable font
60
- splines="ortho", # Straight lines
61
- overlap="false",
62
- concentrate="true",
63
- ratio="compress",
64
- size="50,50", # Larger canvas
65
- dpi="1000", # Higher resolution
66
- pad="1.0",
67
- nodesep="1.2", # More space between nodes
68
- ranksep="1.5" # More vertical space
69
- )
70
-
71
- # Enhanced node styling for better visibility
72
- G.node_attr.update({
73
- "fontsize": "24", # Larger font
74
- "fontname": "Arial Bold",
75
- "shape": "box",
76
- "style": "rounded,filled",
77
- "fillcolor": "#E1F5FE",
78
- "color": "#0288D1",
79
- "height": "0.8",
80
- "width": "2.0",
81
- "penwidth": "2.0",
82
- "margin": "0.3,0.1" # Better text padding
83
- })
84
-
85
- # Enhanced edge styling
86
- G.edge_attr.update({
87
- "color": "#616161",
88
- "penwidth": "2.5",
89
- "arrowsize": "1.2",
90
- "fontname": "Arial",
91
- "fontsize": "20",
92
- "fontcolor": "#424242"
93
- })
94
-
95
- # Add central node with improved styling
96
- G.add_node("DOCUMENT",
97
- shape="doubleoctagon",
98
- fillcolor="#4FC3F7",
99
- fontsize="28",
100
- width="2.5",
101
- height="1.0",
102
- penwidth="3.0")
103
-
104
- # Add entities with better spacing
105
- max_categories = 5
106
- max_entities = 8
107
-
108
- for cat_idx, (category, values) in enumerate(entities.items()):
109
- if cat_idx >= max_categories:
110
- break
111
-
112
- # Main category node
113
- cat_node = f"CAT_{cat_idx}"
114
- G.add_node(cat_node,
115
- label=wrap_label(category, 18),
116
- shape="tab",
117
- fillcolor="#81D4FA",
118
- fontsize="22")
119
-
120
- G.add_edge("DOCUMENT", cat_node,
121
- label="contains",
122
- penwidth="3.0")
123
-
124
- # Add entities with grouping if needed
125
- if len(values) > max_entities:
126
- # Create subcategory groups
127
- for sub_idx, group in enumerate([values[i:i+max_entities]
128
- for i in range(0, len(values), max_entities)]):
129
- sub_node = f"SUB_{cat_idx}_{sub_idx}"
130
- G.add_node(sub_node,
131
- label=f"Group {sub_idx+1}",
132
- shape="folder",
133
- fillcolor="#B3E5FC")
134
- G.add_edge(cat_node, sub_node)
135
-
136
- for ent_idx, value in enumerate(group):
137
- ent_node = f"ENT_{cat_idx}_{sub_idx}_{ent_idx}"
138
- G.add_node(ent_node,
139
- label=wrap_label(value, 15),
140
- shape="note",
141
- fillcolor="#E1F5FE")
142
- G.add_edge(sub_node, ent_node)
143
- else:
144
- # Directly add entities
145
- for ent_idx, value in enumerate(values[:max_entities]):
146
- ent_node = f"ENT_{cat_idx}_{ent_idx}"
147
- G.add_node(ent_node,
148
- label=wrap_label(value, 15),
149
- shape="note",
150
- fillcolor="#E1F5FE")
151
- G.add_edge(cat_node, ent_node)
152
-
153
- # Generate output with multiple attempts
154
- for engine in ['dot', 'neato', 'sfdp']:
155
- try:
156
- G.draw(output_path,
157
- format="png",
158
- prog=engine,
159
- args=f"-Gdpi=300 -Gsize=50,50 -Goverlap=prism")
160
- print(f"Successfully generated with {engine}")
161
-
162
- # Verify the output
163
- if os.path.exists(output_path) and os.path.getsize(output_path) > 0:
164
- return output_path
165
-
166
- except Exception as e:
167
- print(f"Layout engine {engine} failed: {str(e)}")
168
- continue
169
-
170
- raise RuntimeError("All layout engines failed")
171
-
172
- except Exception as e:
173
- print(f"Mind map generation failed: {str(e)}")
174
- # Create error visualization
175
- try:
176
- import matplotlib.pyplot as plt
177
- plt.figure(figsize=(20, 10))
178
- plt.text(0.5, 0.5,
179
- f"Mind Map Generation Failed\n{str(e)}\n\nOriginal Text:\n{text[:200]}...",
180
- ha='center', va='center', wrap=True)
181
- plt.axis('off')
182
- error_path = os.path.join(temp_dir, "error_mindmap.png")
183
- plt.savefig(error_path, bbox_inches='tight', dpi=300)
184
- plt.close()
185
- return error_path
186
- except:
187
- return None
188
  @app.post("/summarize")
189
  def summarize_text(request: TextRequest):
190
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
@@ -223,16 +52,7 @@ def generate_word_cloud(request: TextRequest):
223
 
224
  # Gradio UI
225
  with gr.Blocks(theme=gr.themes.Soft(), css="""
226
- .mindmap-container img {
227
- max-height: none !important;
228
- min-width: 100% !important;
229
- object-fit: contain !important;
230
- background: white !important;
231
- border: 1px solid #e0e0e0 !important;
232
- border-radius: 8px !important;
233
- padding: 20px !important;
234
- }
235
- .gradio-container { max-width: 1400px !important; }
236
  """) as iface:
237
 
238
  gr.Markdown("# JFK Document Analysis Suite")
@@ -272,20 +92,7 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
272
  width=600
273
  )
274
 
275
- # Mind map section
276
- with gr.Row():
277
- mindmap_btn = gr.Button(
278
- "Generate Enhanced Mind Map",
279
- variant="primary"
280
- )
281
-
282
- with gr.Row():
283
- output_mindmap = gr.Image(
284
- label="High-Resolution Mind Map",
285
- elem_classes="mindmap-container",
286
- height=800,
287
- width=800
288
- )
289
 
290
  # Event handlers must be inside the Blocks context
291
  process_btn.click(
@@ -294,37 +101,6 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
294
  outputs=[full_doc_text, output_summary, output_entities, output_wordcloud]
295
  )
296
 
297
- def display_mindmap(text):
298
- try:
299
- img_path = generate_high_res_mindmap(text)
300
- if img_path and os.path.exists(img_path):
301
- return img_path
302
- return None
303
- except Exception as e:
304
- print(f"Display error: {e}")
305
- return None
306
-
307
- mindmap_btn.click(
308
- fn=display_mindmap,
309
- inputs=full_doc_text,
310
- outputs=output_mindmap,
311
- api_name="generate_mindmap",
312
- show_progress=True
313
- )
314
-
315
- # Add CSS for better image display
316
- css = """
317
- .mindmap-container img {
318
- max-width: 100% !important;
319
- height: auto !important;
320
- background: white !important;
321
- border: 2px solid #e0e0e0 !important;
322
- border-radius: 8px !important;
323
- padding: 10px !important;
324
- margin: 10px auto !important;
325
- display: block !important;
326
- }
327
- """
328
 
329
  if __name__ == "__main__":
330
  iface.launch(
 
6
  from wordcloud import WordCloud
7
  from summarization import summarizer
8
  from utils import list_files, process_file
 
 
9
 
10
  # Initialize FastAPI
11
  app = FastAPI()
 
14
  class TextRequest(BaseModel):
15
  text: str
16
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
  @app.post("/summarize")
18
  def summarize_text(request: TextRequest):
19
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
 
52
 
53
  # Gradio UI
54
  with gr.Blocks(theme=gr.themes.Soft(), css="""
55
+
 
 
 
 
 
 
 
 
 
56
  """) as iface:
57
 
58
  gr.Markdown("# JFK Document Analysis Suite")
 
92
  width=600
93
  )
94
 
95
+
 
 
 
 
 
 
 
 
 
 
 
 
 
96
 
97
  # Event handlers must be inside the Blocks context
98
  process_btn.click(
 
101
  outputs=[full_doc_text, output_summary, output_entities, output_wordcloud]
102
  )
103
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
104
 
105
  if __name__ == "__main__":
106
  iface.launch(
space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/app.py CHANGED
@@ -6,8 +6,6 @@ from entity_recognition import extract_entities
6
  from wordcloud import WordCloud
7
  from summarization import summarizer
8
  from utils import list_files, process_file
9
- import pygraphviz as pgv
10
- import os
11
 
12
  # Initialize FastAPI
13
  app = FastAPI()
@@ -16,175 +14,6 @@ app = FastAPI()
16
  class TextRequest(BaseModel):
17
  text: str
18
 
19
- def wrap_label(label, max_length=15):
20
- """Improved label wrapping with hyphenation awareness"""
21
- if len(label) <= max_length:
22
- return label
23
-
24
- # Try to break at natural points
25
- break_chars = [" ", "-", "_", "/"]
26
- lines = []
27
- current = ""
28
-
29
- for char in label:
30
- if len(current) >= max_length and char in break_chars:
31
- lines.append(current.strip())
32
- current = char
33
- else:
34
- current += char
35
-
36
- if current:
37
- lines.append(current.strip())
38
-
39
- return "\\n".join(lines)
40
- def generate_high_res_mindmap(text):
41
- """Generate high-quality mind map with improved visibility"""
42
- try:
43
- # Verify we have entities to visualize
44
- entities = extract_entities(text)
45
- if not any(entities.values()):
46
- print("No entities found to generate mind map")
47
- return None
48
-
49
- # Create temporary directory
50
- temp_dir = "/tmp/mindmaps"
51
- os.makedirs(temp_dir, exist_ok=True)
52
- output_path = os.path.join(temp_dir, "mindmap.png")
53
-
54
- # Create graph with optimized settings
55
- G = pgv.AGraph(
56
- directed=True,
57
- rankdir="TB", # Top-to-bottom layout
58
- bgcolor="white",
59
- fontname="Arial", # More readable font
60
- splines="ortho", # Straight lines
61
- overlap="false",
62
- concentrate="true",
63
- ratio="compress",
64
- size="50,50", # Larger canvas
65
- dpi="1000", # Higher resolution
66
- pad="1.0",
67
- nodesep="1.2", # More space between nodes
68
- ranksep="1.5" # More vertical space
69
- )
70
-
71
- # Enhanced node styling for better visibility
72
- G.node_attr.update({
73
- "fontsize": "24", # Larger font
74
- "fontname": "Arial Bold",
75
- "shape": "box",
76
- "style": "rounded,filled",
77
- "fillcolor": "#E1F5FE",
78
- "color": "#0288D1",
79
- "height": "0.8",
80
- "width": "2.0",
81
- "penwidth": "2.0",
82
- "margin": "0.3,0.1" # Better text padding
83
- })
84
-
85
- # Enhanced edge styling
86
- G.edge_attr.update({
87
- "color": "#616161",
88
- "penwidth": "2.5",
89
- "arrowsize": "1.2",
90
- "fontname": "Arial",
91
- "fontsize": "20",
92
- "fontcolor": "#424242"
93
- })
94
-
95
- # Add central node with improved styling
96
- G.add_node("DOCUMENT",
97
- shape="doubleoctagon",
98
- fillcolor="#4FC3F7",
99
- fontsize="28",
100
- width="2.5",
101
- height="1.0",
102
- penwidth="3.0")
103
-
104
- # Add entities with better spacing
105
- max_categories = 5
106
- max_entities = 8
107
-
108
- for cat_idx, (category, values) in enumerate(entities.items()):
109
- if cat_idx >= max_categories:
110
- break
111
-
112
- # Main category node
113
- cat_node = f"CAT_{cat_idx}"
114
- G.add_node(cat_node,
115
- label=wrap_label(category, 18),
116
- shape="tab",
117
- fillcolor="#81D4FA",
118
- fontsize="22")
119
-
120
- G.add_edge("DOCUMENT", cat_node,
121
- label="contains",
122
- penwidth="3.0")
123
-
124
- # Add entities with grouping if needed
125
- if len(values) > max_entities:
126
- # Create subcategory groups
127
- for sub_idx, group in enumerate([values[i:i+max_entities]
128
- for i in range(0, len(values), max_entities)]):
129
- sub_node = f"SUB_{cat_idx}_{sub_idx}"
130
- G.add_node(sub_node,
131
- label=f"Group {sub_idx+1}",
132
- shape="folder",
133
- fillcolor="#B3E5FC")
134
- G.add_edge(cat_node, sub_node)
135
-
136
- for ent_idx, value in enumerate(group):
137
- ent_node = f"ENT_{cat_idx}_{sub_idx}_{ent_idx}"
138
- G.add_node(ent_node,
139
- label=wrap_label(value, 15),
140
- shape="note",
141
- fillcolor="#E1F5FE")
142
- G.add_edge(sub_node, ent_node)
143
- else:
144
- # Directly add entities
145
- for ent_idx, value in enumerate(values[:max_entities]):
146
- ent_node = f"ENT_{cat_idx}_{ent_idx}"
147
- G.add_node(ent_node,
148
- label=wrap_label(value, 15),
149
- shape="note",
150
- fillcolor="#E1F5FE")
151
- G.add_edge(cat_node, ent_node)
152
-
153
- # Generate output with multiple attempts
154
- for engine in ['dot', 'neato', 'sfdp']:
155
- try:
156
- G.draw(output_path,
157
- format="png",
158
- prog=engine,
159
- args=f"-Gdpi=300 -Gsize=50,50 -Goverlap=prism")
160
- print(f"Successfully generated with {engine}")
161
-
162
- # Verify the output
163
- if os.path.exists(output_path) and os.path.getsize(output_path) > 0:
164
- return output_path
165
-
166
- except Exception as e:
167
- print(f"Layout engine {engine} failed: {str(e)}")
168
- continue
169
-
170
- raise RuntimeError("All layout engines failed")
171
-
172
- except Exception as e:
173
- print(f"Mind map generation failed: {str(e)}")
174
- # Create error visualization
175
- try:
176
- import matplotlib.pyplot as plt
177
- plt.figure(figsize=(20, 10))
178
- plt.text(0.5, 0.5,
179
- f"Mind Map Generation Failed\n{str(e)}\n\nOriginal Text:\n{text[:200]}...",
180
- ha='center', va='center', wrap=True)
181
- plt.axis('off')
182
- error_path = os.path.join(temp_dir, "error_mindmap.png")
183
- plt.savefig(error_path, bbox_inches='tight', dpi=300)
184
- plt.close()
185
- return error_path
186
- except:
187
- return None
188
  @app.post("/summarize")
189
  def summarize_text(request: TextRequest):
190
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
@@ -223,16 +52,7 @@ def generate_word_cloud(request: TextRequest):
223
 
224
  # Gradio UI
225
  with gr.Blocks(theme=gr.themes.Soft(), css="""
226
- .mindmap-container img {
227
- max-height: none !important;
228
- min-width: 100% !important;
229
- object-fit: contain !important;
230
- background: white !important;
231
- border: 1px solid #e0e0e0 !important;
232
- border-radius: 8px !important;
233
- padding: 20px !important;
234
- }
235
- .gradio-container { max-width: 1400px !important; }
236
  """) as iface:
237
 
238
  gr.Markdown("# JFK Document Analysis Suite")
@@ -272,20 +92,7 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
272
  width=600
273
  )
274
 
275
- # Mind map section
276
- with gr.Row():
277
- mindmap_btn = gr.Button(
278
- "Generate Enhanced Mind Map",
279
- variant="primary"
280
- )
281
-
282
- with gr.Row():
283
- output_mindmap = gr.Image(
284
- label="High-Resolution Mind Map",
285
- elem_classes="mindmap-container",
286
- height=800,
287
- width=800
288
- )
289
 
290
  # Event handlers must be inside the Blocks context
291
  process_btn.click(
@@ -294,37 +101,6 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
294
  outputs=[full_doc_text, output_summary, output_entities, output_wordcloud]
295
  )
296
 
297
- def display_mindmap(text):
298
- try:
299
- img_path = generate_high_res_mindmap(text)
300
- if img_path and os.path.exists(img_path):
301
- return img_path
302
- return None
303
- except Exception as e:
304
- print(f"Display error: {e}")
305
- return None
306
-
307
- mindmap_btn.click(
308
- fn=display_mindmap,
309
- inputs=full_doc_text,
310
- outputs=output_mindmap,
311
- api_name="generate_mindmap",
312
- show_progress=True
313
- )
314
-
315
- # Add CSS for better image display
316
- css = """
317
- .mindmap-container img {
318
- max-width: 100% !important;
319
- height: auto !important;
320
- background: white !important;
321
- border: 2px solid #e0e0e0 !important;
322
- border-radius: 8px !important;
323
- padding: 10px !important;
324
- margin: 10px auto !important;
325
- display: block !important;
326
- }
327
- """
328
 
329
  if __name__ == "__main__":
330
  iface.launch(
 
6
  from wordcloud import WordCloud
7
  from summarization import summarizer
8
  from utils import list_files, process_file
 
 
9
 
10
  # Initialize FastAPI
11
  app = FastAPI()
 
14
  class TextRequest(BaseModel):
15
  text: str
16
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
  @app.post("/summarize")
18
  def summarize_text(request: TextRequest):
19
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
 
52
 
53
  # Gradio UI
54
  with gr.Blocks(theme=gr.themes.Soft(), css="""
55
+
 
 
 
 
 
 
 
 
 
56
  """) as iface:
57
 
58
  gr.Markdown("# JFK Document Analysis Suite")
 
92
  width=600
93
  )
94
 
95
+
 
 
 
 
 
 
 
 
 
 
 
 
 
96
 
97
  # Event handlers must be inside the Blocks context
98
  process_btn.click(
 
101
  outputs=[full_doc_text, output_summary, output_entities, output_wordcloud]
102
  )
103
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
104
 
105
  if __name__ == "__main__":
106
  iface.launch(
space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/app.py CHANGED
@@ -6,8 +6,6 @@ from entity_recognition import extract_entities
6
  from wordcloud import WordCloud
7
  from summarization import summarizer
8
  from utils import list_files, process_file
9
- import pygraphviz as pgv
10
- import os
11
 
12
  # Initialize FastAPI
13
  app = FastAPI()
@@ -16,175 +14,6 @@ app = FastAPI()
16
  class TextRequest(BaseModel):
17
  text: str
18
 
19
- def wrap_label(label, max_length=15):
20
- """Improved label wrapping with hyphenation awareness"""
21
- if len(label) <= max_length:
22
- return label
23
-
24
- # Try to break at natural points
25
- break_chars = [" ", "-", "_", "/"]
26
- lines = []
27
- current = ""
28
-
29
- for char in label:
30
- if len(current) >= max_length and char in break_chars:
31
- lines.append(current.strip())
32
- current = char
33
- else:
34
- current += char
35
-
36
- if current:
37
- lines.append(current.strip())
38
-
39
- return "\\n".join(lines)
40
- def generate_high_res_mindmap(text):
41
- """Generate high-quality mind map with improved visibility"""
42
- try:
43
- # Verify we have entities to visualize
44
- entities = extract_entities(text)
45
- if not any(entities.values()):
46
- print("No entities found to generate mind map")
47
- return None
48
-
49
- # Create temporary directory
50
- temp_dir = "/tmp/mindmaps"
51
- os.makedirs(temp_dir, exist_ok=True)
52
- output_path = os.path.join(temp_dir, "mindmap.png")
53
-
54
- # Create graph with optimized settings
55
- G = pgv.AGraph(
56
- directed=True,
57
- rankdir="TB", # Top-to-bottom layout
58
- bgcolor="white",
59
- fontname="Arial", # More readable font
60
- splines="ortho", # Straight lines
61
- overlap="false",
62
- concentrate="true",
63
- ratio="compress",
64
- size="50,50", # Larger canvas
65
- dpi="1000", # Higher resolution
66
- pad="1.0",
67
- nodesep="1.2", # More space between nodes
68
- ranksep="1.5" # More vertical space
69
- )
70
-
71
- # Enhanced node styling for better visibility
72
- G.node_attr.update({
73
- "fontsize": "24", # Larger font
74
- "fontname": "Arial Bold",
75
- "shape": "box",
76
- "style": "rounded,filled",
77
- "fillcolor": "#E1F5FE",
78
- "color": "#0288D1",
79
- "height": "0.8",
80
- "width": "2.0",
81
- "penwidth": "2.0",
82
- "margin": "0.3,0.1" # Better text padding
83
- })
84
-
85
- # Enhanced edge styling
86
- G.edge_attr.update({
87
- "color": "#616161",
88
- "penwidth": "2.5",
89
- "arrowsize": "1.2",
90
- "fontname": "Arial",
91
- "fontsize": "20",
92
- "fontcolor": "#424242"
93
- })
94
-
95
- # Add central node with improved styling
96
- G.add_node("DOCUMENT",
97
- shape="doubleoctagon",
98
- fillcolor="#4FC3F7",
99
- fontsize="28",
100
- width="2.5",
101
- height="1.0",
102
- penwidth="3.0")
103
-
104
- # Add entities with better spacing
105
- max_categories = 5
106
- max_entities = 8
107
-
108
- for cat_idx, (category, values) in enumerate(entities.items()):
109
- if cat_idx >= max_categories:
110
- break
111
-
112
- # Main category node
113
- cat_node = f"CAT_{cat_idx}"
114
- G.add_node(cat_node,
115
- label=wrap_label(category, 18),
116
- shape="tab",
117
- fillcolor="#81D4FA",
118
- fontsize="22")
119
-
120
- G.add_edge("DOCUMENT", cat_node,
121
- label="contains",
122
- penwidth="3.0")
123
-
124
- # Add entities with grouping if needed
125
- if len(values) > max_entities:
126
- # Create subcategory groups
127
- for sub_idx, group in enumerate([values[i:i+max_entities]
128
- for i in range(0, len(values), max_entities)]):
129
- sub_node = f"SUB_{cat_idx}_{sub_idx}"
130
- G.add_node(sub_node,
131
- label=f"Group {sub_idx+1}",
132
- shape="folder",
133
- fillcolor="#B3E5FC")
134
- G.add_edge(cat_node, sub_node)
135
-
136
- for ent_idx, value in enumerate(group):
137
- ent_node = f"ENT_{cat_idx}_{sub_idx}_{ent_idx}"
138
- G.add_node(ent_node,
139
- label=wrap_label(value, 15),
140
- shape="note",
141
- fillcolor="#E1F5FE")
142
- G.add_edge(sub_node, ent_node)
143
- else:
144
- # Directly add entities
145
- for ent_idx, value in enumerate(values[:max_entities]):
146
- ent_node = f"ENT_{cat_idx}_{ent_idx}"
147
- G.add_node(ent_node,
148
- label=wrap_label(value, 15),
149
- shape="note",
150
- fillcolor="#E1F5FE")
151
- G.add_edge(cat_node, ent_node)
152
-
153
- # Generate output with multiple attempts
154
- for engine in ['dot', 'neato', 'sfdp']:
155
- try:
156
- G.draw(output_path,
157
- format="png",
158
- prog=engine,
159
- args=f"-Gdpi=300 -Gsize=50,50 -Goverlap=prism")
160
- print(f"Successfully generated with {engine}")
161
-
162
- # Verify the output
163
- if os.path.exists(output_path) and os.path.getsize(output_path) > 0:
164
- return output_path
165
-
166
- except Exception as e:
167
- print(f"Layout engine {engine} failed: {str(e)}")
168
- continue
169
-
170
- raise RuntimeError("All layout engines failed")
171
-
172
- except Exception as e:
173
- print(f"Mind map generation failed: {str(e)}")
174
- # Create error visualization
175
- try:
176
- import matplotlib.pyplot as plt
177
- plt.figure(figsize=(20, 10))
178
- plt.text(0.5, 0.5,
179
- f"Mind Map Generation Failed\n{str(e)}\n\nOriginal Text:\n{text[:200]}...",
180
- ha='center', va='center', wrap=True)
181
- plt.axis('off')
182
- error_path = os.path.join(temp_dir, "error_mindmap.png")
183
- plt.savefig(error_path, bbox_inches='tight', dpi=300)
184
- plt.close()
185
- return error_path
186
- except:
187
- return None
188
  @app.post("/summarize")
189
  def summarize_text(request: TextRequest):
190
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
@@ -223,16 +52,7 @@ def generate_word_cloud(request: TextRequest):
223
 
224
  # Gradio UI
225
  with gr.Blocks(theme=gr.themes.Soft(), css="""
226
- .mindmap-container img {
227
- max-height: none !important;
228
- min-width: 100% !important;
229
- object-fit: contain !important;
230
- background: white !important;
231
- border: 1px solid #e0e0e0 !important;
232
- border-radius: 8px !important;
233
- padding: 20px !important;
234
- }
235
- .gradio-container { max-width: 1400px !important; }
236
  """) as iface:
237
 
238
  gr.Markdown("# JFK Document Analysis Suite")
@@ -272,20 +92,7 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
272
  width=600
273
  )
274
 
275
- # Mind map section
276
- with gr.Row():
277
- mindmap_btn = gr.Button(
278
- "Generate Enhanced Mind Map",
279
- variant="primary"
280
- )
281
-
282
- with gr.Row():
283
- output_mindmap = gr.Image(
284
- label="High-Resolution Mind Map",
285
- elem_classes="mindmap-container",
286
- height=800,
287
- width=800
288
- )
289
 
290
  # Event handlers must be inside the Blocks context
291
  process_btn.click(
@@ -294,37 +101,6 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
294
  outputs=[full_doc_text, output_summary, output_entities, output_wordcloud]
295
  )
296
 
297
- def display_mindmap(text):
298
- try:
299
- img_path = generate_high_res_mindmap(text)
300
- if img_path and os.path.exists(img_path):
301
- return img_path
302
- return None
303
- except Exception as e:
304
- print(f"Display error: {e}")
305
- return None
306
-
307
- mindmap_btn.click(
308
- fn=display_mindmap,
309
- inputs=full_doc_text,
310
- outputs=output_mindmap,
311
- api_name="generate_mindmap",
312
- show_progress=True
313
- )
314
-
315
- # Add CSS for better image display
316
- css = """
317
- .mindmap-container img {
318
- max-width: 100% !important;
319
- height: auto !important;
320
- background: white !important;
321
- border: 2px solid #e0e0e0 !important;
322
- border-radius: 8px !important;
323
- padding: 10px !important;
324
- margin: 10px auto !important;
325
- display: block !important;
326
- }
327
- """
328
 
329
  if __name__ == "__main__":
330
  iface.launch(
 
6
  from wordcloud import WordCloud
7
  from summarization import summarizer
8
  from utils import list_files, process_file
 
 
9
 
10
  # Initialize FastAPI
11
  app = FastAPI()
 
14
  class TextRequest(BaseModel):
15
  text: str
16
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
  @app.post("/summarize")
18
  def summarize_text(request: TextRequest):
19
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
 
52
 
53
  # Gradio UI
54
  with gr.Blocks(theme=gr.themes.Soft(), css="""
55
+
 
 
 
 
 
 
 
 
 
56
  """) as iface:
57
 
58
  gr.Markdown("# JFK Document Analysis Suite")
 
92
  width=600
93
  )
94
 
95
+
 
 
 
 
 
 
 
 
 
 
 
 
 
96
 
97
  # Event handlers must be inside the Blocks context
98
  process_btn.click(
 
101
  outputs=[full_doc_text, output_summary, output_entities, output_wordcloud]
102
  )
103
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
104
 
105
  if __name__ == "__main__":
106
  iface.launch(
space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/app.py CHANGED
@@ -6,8 +6,6 @@ from entity_recognition import extract_entities
6
  from wordcloud import WordCloud
7
  from summarization import summarizer
8
  from utils import list_files, process_file
9
- import pygraphviz as pgv
10
- import os
11
 
12
  # Initialize FastAPI
13
  app = FastAPI()
@@ -16,175 +14,6 @@ app = FastAPI()
16
  class TextRequest(BaseModel):
17
  text: str
18
 
19
- def wrap_label(label, max_length=15):
20
- """Improved label wrapping with hyphenation awareness"""
21
- if len(label) <= max_length:
22
- return label
23
-
24
- # Try to break at natural points
25
- break_chars = [" ", "-", "_", "/"]
26
- lines = []
27
- current = ""
28
-
29
- for char in label:
30
- if len(current) >= max_length and char in break_chars:
31
- lines.append(current.strip())
32
- current = char
33
- else:
34
- current += char
35
-
36
- if current:
37
- lines.append(current.strip())
38
-
39
- return "\\n".join(lines)
40
- def generate_high_res_mindmap(text):
41
- """Generate high-quality mind map with improved visibility"""
42
- try:
43
- # Verify we have entities to visualize
44
- entities = extract_entities(text)
45
- if not any(entities.values()):
46
- print("No entities found to generate mind map")
47
- return None
48
-
49
- # Create temporary directory
50
- temp_dir = "/tmp/mindmaps"
51
- os.makedirs(temp_dir, exist_ok=True)
52
- output_path = os.path.join(temp_dir, "mindmap.png")
53
-
54
- # Create graph with optimized settings
55
- G = pgv.AGraph(
56
- directed=True,
57
- rankdir="TB", # Top-to-bottom layout
58
- bgcolor="white",
59
- fontname="Arial", # More readable font
60
- splines="ortho", # Straight lines
61
- overlap="false",
62
- concentrate="true",
63
- ratio="compress",
64
- size="50,50", # Larger canvas
65
- dpi="1000", # Higher resolution
66
- pad="1.0",
67
- nodesep="1.2", # More space between nodes
68
- ranksep="1.5" # More vertical space
69
- )
70
-
71
- # Enhanced node styling for better visibility
72
- G.node_attr.update({
73
- "fontsize": "24", # Larger font
74
- "fontname": "Arial Bold",
75
- "shape": "box",
76
- "style": "rounded,filled",
77
- "fillcolor": "#E1F5FE",
78
- "color": "#0288D1",
79
- "height": "0.8",
80
- "width": "2.0",
81
- "penwidth": "2.0",
82
- "margin": "0.3,0.1" # Better text padding
83
- })
84
-
85
- # Enhanced edge styling
86
- G.edge_attr.update({
87
- "color": "#616161",
88
- "penwidth": "2.5",
89
- "arrowsize": "1.2",
90
- "fontname": "Arial",
91
- "fontsize": "20",
92
- "fontcolor": "#424242"
93
- })
94
-
95
- # Add central node with improved styling
96
- G.add_node("DOCUMENT",
97
- shape="doubleoctagon",
98
- fillcolor="#4FC3F7",
99
- fontsize="28",
100
- width="2.5",
101
- height="1.0",
102
- penwidth="3.0")
103
-
104
- # Add entities with better spacing
105
- max_categories = 5
106
- max_entities = 8
107
-
108
- for cat_idx, (category, values) in enumerate(entities.items()):
109
- if cat_idx >= max_categories:
110
- break
111
-
112
- # Main category node
113
- cat_node = f"CAT_{cat_idx}"
114
- G.add_node(cat_node,
115
- label=wrap_label(category, 18),
116
- shape="tab",
117
- fillcolor="#81D4FA",
118
- fontsize="22")
119
-
120
- G.add_edge("DOCUMENT", cat_node,
121
- label="contains",
122
- penwidth="3.0")
123
-
124
- # Add entities with grouping if needed
125
- if len(values) > max_entities:
126
- # Create subcategory groups
127
- for sub_idx, group in enumerate([values[i:i+max_entities]
128
- for i in range(0, len(values), max_entities)]):
129
- sub_node = f"SUB_{cat_idx}_{sub_idx}"
130
- G.add_node(sub_node,
131
- label=f"Group {sub_idx+1}",
132
- shape="folder",
133
- fillcolor="#B3E5FC")
134
- G.add_edge(cat_node, sub_node)
135
-
136
- for ent_idx, value in enumerate(group):
137
- ent_node = f"ENT_{cat_idx}_{sub_idx}_{ent_idx}"
138
- G.add_node(ent_node,
139
- label=wrap_label(value, 15),
140
- shape="note",
141
- fillcolor="#E1F5FE")
142
- G.add_edge(sub_node, ent_node)
143
- else:
144
- # Directly add entities
145
- for ent_idx, value in enumerate(values[:max_entities]):
146
- ent_node = f"ENT_{cat_idx}_{ent_idx}"
147
- G.add_node(ent_node,
148
- label=wrap_label(value, 15),
149
- shape="note",
150
- fillcolor="#E1F5FE")
151
- G.add_edge(cat_node, ent_node)
152
-
153
- # Generate output with multiple attempts
154
- for engine in ['dot', 'neato', 'sfdp']:
155
- try:
156
- G.draw(output_path,
157
- format="png",
158
- prog=engine,
159
- args=f"-Gdpi=300 -Gsize=50,50 -Goverlap=prism")
160
- print(f"Successfully generated with {engine}")
161
-
162
- # Verify the output
163
- if os.path.exists(output_path) and os.path.getsize(output_path) > 0:
164
- return output_path
165
-
166
- except Exception as e:
167
- print(f"Layout engine {engine} failed: {str(e)}")
168
- continue
169
-
170
- raise RuntimeError("All layout engines failed")
171
-
172
- except Exception as e:
173
- print(f"Mind map generation failed: {str(e)}")
174
- # Create error visualization
175
- try:
176
- import matplotlib.pyplot as plt
177
- plt.figure(figsize=(20, 10))
178
- plt.text(0.5, 0.5,
179
- f"Mind Map Generation Failed\n{str(e)}\n\nOriginal Text:\n{text[:200]}...",
180
- ha='center', va='center', wrap=True)
181
- plt.axis('off')
182
- error_path = os.path.join(temp_dir, "error_mindmap.png")
183
- plt.savefig(error_path, bbox_inches='tight', dpi=300)
184
- plt.close()
185
- return error_path
186
- except:
187
- return None
188
  @app.post("/summarize")
189
  def summarize_text(request: TextRequest):
190
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
@@ -223,16 +52,7 @@ def generate_word_cloud(request: TextRequest):
223
 
224
  # Gradio UI
225
  with gr.Blocks(theme=gr.themes.Soft(), css="""
226
- .mindmap-container img {
227
- max-height: none !important;
228
- min-width: 100% !important;
229
- object-fit: contain !important;
230
- background: white !important;
231
- border: 1px solid #e0e0e0 !important;
232
- border-radius: 8px !important;
233
- padding: 20px !important;
234
- }
235
- .gradio-container { max-width: 1400px !important; }
236
  """) as iface:
237
 
238
  gr.Markdown("# JFK Document Analysis Suite")
@@ -272,20 +92,7 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
272
  width=600
273
  )
274
 
275
- # Mind map section
276
- with gr.Row():
277
- mindmap_btn = gr.Button(
278
- "Generate Enhanced Mind Map",
279
- variant="primary"
280
- )
281
-
282
- with gr.Row():
283
- output_mindmap = gr.Image(
284
- label="High-Resolution Mind Map",
285
- elem_classes="mindmap-container",
286
- height=800,
287
- width=800
288
- )
289
 
290
  # Event handlers must be inside the Blocks context
291
  process_btn.click(
@@ -294,37 +101,6 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
294
  outputs=[full_doc_text, output_summary, output_entities, output_wordcloud]
295
  )
296
 
297
- def display_mindmap(text):
298
- try:
299
- img_path = generate_high_res_mindmap(text)
300
- if img_path and os.path.exists(img_path):
301
- return img_path
302
- return None
303
- except Exception as e:
304
- print(f"Display error: {e}")
305
- return None
306
-
307
- mindmap_btn.click(
308
- fn=display_mindmap,
309
- inputs=full_doc_text,
310
- outputs=output_mindmap,
311
- api_name="generate_mindmap",
312
- show_progress=True
313
- )
314
-
315
- # Add CSS for better image display
316
- css = """
317
- .mindmap-container img {
318
- max-width: 100% !important;
319
- height: auto !important;
320
- background: white !important;
321
- border: 2px solid #e0e0e0 !important;
322
- border-radius: 8px !important;
323
- padding: 10px !important;
324
- margin: 10px auto !important;
325
- display: block !important;
326
- }
327
- """
328
 
329
  if __name__ == "__main__":
330
  iface.launch(
 
6
  from wordcloud import WordCloud
7
  from summarization import summarizer
8
  from utils import list_files, process_file
 
 
9
 
10
  # Initialize FastAPI
11
  app = FastAPI()
 
14
  class TextRequest(BaseModel):
15
  text: str
16
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
  @app.post("/summarize")
18
  def summarize_text(request: TextRequest):
19
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
 
52
 
53
  # Gradio UI
54
  with gr.Blocks(theme=gr.themes.Soft(), css="""
55
+
 
 
 
 
 
 
 
 
 
56
  """) as iface:
57
 
58
  gr.Markdown("# JFK Document Analysis Suite")
 
92
  width=600
93
  )
94
 
95
+
 
 
 
 
 
 
 
 
 
 
 
 
 
96
 
97
  # Event handlers must be inside the Blocks context
98
  process_btn.click(
 
101
  outputs=[full_doc_text, output_summary, output_entities, output_wordcloud]
102
  )
103
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
104
 
105
  if __name__ == "__main__":
106
  iface.launch(
space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/app.py CHANGED
@@ -6,8 +6,6 @@ from entity_recognition import extract_entities
6
  from wordcloud import WordCloud
7
  from summarization import summarizer
8
  from utils import list_files, process_file
9
- import pygraphviz as pgv
10
- import os
11
 
12
  # Initialize FastAPI
13
  app = FastAPI()
@@ -16,175 +14,6 @@ app = FastAPI()
16
  class TextRequest(BaseModel):
17
  text: str
18
 
19
- def wrap_label(label, max_length=15):
20
- """Improved label wrapping with hyphenation awareness"""
21
- if len(label) <= max_length:
22
- return label
23
-
24
- # Try to break at natural points
25
- break_chars = [" ", "-", "_", "/"]
26
- lines = []
27
- current = ""
28
-
29
- for char in label:
30
- if len(current) >= max_length and char in break_chars:
31
- lines.append(current.strip())
32
- current = char
33
- else:
34
- current += char
35
-
36
- if current:
37
- lines.append(current.strip())
38
-
39
- return "\\n".join(lines)
40
- def generate_high_res_mindmap(text):
41
- """Generate high-quality mind map with improved visibility"""
42
- try:
43
- # Verify we have entities to visualize
44
- entities = extract_entities(text)
45
- if not any(entities.values()):
46
- print("No entities found to generate mind map")
47
- return None
48
-
49
- # Create temporary directory
50
- temp_dir = "/tmp/mindmaps"
51
- os.makedirs(temp_dir, exist_ok=True)
52
- output_path = os.path.join(temp_dir, "mindmap.png")
53
-
54
- # Create graph with optimized settings
55
- G = pgv.AGraph(
56
- directed=True,
57
- rankdir="TB", # Top-to-bottom layout
58
- bgcolor="white",
59
- fontname="Arial", # More readable font
60
- splines="ortho", # Straight lines
61
- overlap="false",
62
- concentrate="true",
63
- ratio="compress",
64
- size="50,50", # Larger canvas
65
- dpi="1000", # Higher resolution
66
- pad="1.0",
67
- nodesep="1.2", # More space between nodes
68
- ranksep="1.5" # More vertical space
69
- )
70
-
71
- # Enhanced node styling for better visibility
72
- G.node_attr.update({
73
- "fontsize": "24", # Larger font
74
- "fontname": "Arial Bold",
75
- "shape": "box",
76
- "style": "rounded,filled",
77
- "fillcolor": "#E1F5FE",
78
- "color": "#0288D1",
79
- "height": "0.8",
80
- "width": "2.0",
81
- "penwidth": "2.0",
82
- "margin": "0.3,0.1" # Better text padding
83
- })
84
-
85
- # Enhanced edge styling
86
- G.edge_attr.update({
87
- "color": "#616161",
88
- "penwidth": "2.5",
89
- "arrowsize": "1.2",
90
- "fontname": "Arial",
91
- "fontsize": "20",
92
- "fontcolor": "#424242"
93
- })
94
-
95
- # Add central node with improved styling
96
- G.add_node("DOCUMENT",
97
- shape="doubleoctagon",
98
- fillcolor="#4FC3F7",
99
- fontsize="28",
100
- width="2.5",
101
- height="1.0",
102
- penwidth="3.0")
103
-
104
- # Add entities with better spacing
105
- max_categories = 5
106
- max_entities = 8
107
-
108
- for cat_idx, (category, values) in enumerate(entities.items()):
109
- if cat_idx >= max_categories:
110
- break
111
-
112
- # Main category node
113
- cat_node = f"CAT_{cat_idx}"
114
- G.add_node(cat_node,
115
- label=wrap_label(category, 18),
116
- shape="tab",
117
- fillcolor="#81D4FA",
118
- fontsize="22")
119
-
120
- G.add_edge("DOCUMENT", cat_node,
121
- label="contains",
122
- penwidth="3.0")
123
-
124
- # Add entities with grouping if needed
125
- if len(values) > max_entities:
126
- # Create subcategory groups
127
- for sub_idx, group in enumerate([values[i:i+max_entities]
128
- for i in range(0, len(values), max_entities)]):
129
- sub_node = f"SUB_{cat_idx}_{sub_idx}"
130
- G.add_node(sub_node,
131
- label=f"Group {sub_idx+1}",
132
- shape="folder",
133
- fillcolor="#B3E5FC")
134
- G.add_edge(cat_node, sub_node)
135
-
136
- for ent_idx, value in enumerate(group):
137
- ent_node = f"ENT_{cat_idx}_{sub_idx}_{ent_idx}"
138
- G.add_node(ent_node,
139
- label=wrap_label(value, 15),
140
- shape="note",
141
- fillcolor="#E1F5FE")
142
- G.add_edge(sub_node, ent_node)
143
- else:
144
- # Directly add entities
145
- for ent_idx, value in enumerate(values[:max_entities]):
146
- ent_node = f"ENT_{cat_idx}_{ent_idx}"
147
- G.add_node(ent_node,
148
- label=wrap_label(value, 15),
149
- shape="note",
150
- fillcolor="#E1F5FE")
151
- G.add_edge(cat_node, ent_node)
152
-
153
- # Generate output with multiple attempts
154
- for engine in ['dot', 'neato', 'sfdp']:
155
- try:
156
- G.draw(output_path,
157
- format="png",
158
- prog=engine,
159
- args=f"-Gdpi=300 -Gsize=50,50 -Goverlap=prism")
160
- print(f"Successfully generated with {engine}")
161
-
162
- # Verify the output
163
- if os.path.exists(output_path) and os.path.getsize(output_path) > 0:
164
- return output_path
165
-
166
- except Exception as e:
167
- print(f"Layout engine {engine} failed: {str(e)}")
168
- continue
169
-
170
- raise RuntimeError("All layout engines failed")
171
-
172
- except Exception as e:
173
- print(f"Mind map generation failed: {str(e)}")
174
- # Create error visualization
175
- try:
176
- import matplotlib.pyplot as plt
177
- plt.figure(figsize=(20, 10))
178
- plt.text(0.5, 0.5,
179
- f"Mind Map Generation Failed\n{str(e)}\n\nOriginal Text:\n{text[:200]}...",
180
- ha='center', va='center', wrap=True)
181
- plt.axis('off')
182
- error_path = os.path.join(temp_dir, "error_mindmap.png")
183
- plt.savefig(error_path, bbox_inches='tight', dpi=300)
184
- plt.close()
185
- return error_path
186
- except:
187
- return None
188
  @app.post("/summarize")
189
  def summarize_text(request: TextRequest):
190
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
@@ -223,16 +52,7 @@ def generate_word_cloud(request: TextRequest):
223
 
224
  # Gradio UI
225
  with gr.Blocks(theme=gr.themes.Soft(), css="""
226
- .mindmap-container img {
227
- max-height: none !important;
228
- min-width: 100% !important;
229
- object-fit: contain !important;
230
- background: white !important;
231
- border: 1px solid #e0e0e0 !important;
232
- border-radius: 8px !important;
233
- padding: 20px !important;
234
- }
235
- .gradio-container { max-width: 1400px !important; }
236
  """) as iface:
237
 
238
  gr.Markdown("# JFK Document Analysis Suite")
@@ -272,20 +92,7 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
272
  width=600
273
  )
274
 
275
- # Mind map section
276
- with gr.Row():
277
- mindmap_btn = gr.Button(
278
- "Generate Enhanced Mind Map",
279
- variant="primary"
280
- )
281
-
282
- with gr.Row():
283
- output_mindmap = gr.Image(
284
- label="High-Resolution Mind Map",
285
- elem_classes="mindmap-container",
286
- height=800,
287
- width=800
288
- )
289
 
290
  # Event handlers must be inside the Blocks context
291
  process_btn.click(
@@ -294,37 +101,6 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
294
  outputs=[full_doc_text, output_summary, output_entities, output_wordcloud]
295
  )
296
 
297
- def display_mindmap(text):
298
- try:
299
- img_path = generate_high_res_mindmap(text)
300
- if img_path and os.path.exists(img_path):
301
- return img_path
302
- return None
303
- except Exception as e:
304
- print(f"Display error: {e}")
305
- return None
306
-
307
- mindmap_btn.click(
308
- fn=display_mindmap,
309
- inputs=full_doc_text,
310
- outputs=output_mindmap,
311
- api_name="generate_mindmap",
312
- show_progress=True
313
- )
314
-
315
- # Add CSS for better image display
316
- css = """
317
- .mindmap-container img {
318
- max-width: 100% !important;
319
- height: auto !important;
320
- background: white !important;
321
- border: 2px solid #e0e0e0 !important;
322
- border-radius: 8px !important;
323
- padding: 10px !important;
324
- margin: 10px auto !important;
325
- display: block !important;
326
- }
327
- """
328
 
329
  if __name__ == "__main__":
330
  iface.launch(
 
6
  from wordcloud import WordCloud
7
  from summarization import summarizer
8
  from utils import list_files, process_file
 
 
9
 
10
  # Initialize FastAPI
11
  app = FastAPI()
 
14
  class TextRequest(BaseModel):
15
  text: str
16
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
  @app.post("/summarize")
18
  def summarize_text(request: TextRequest):
19
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
 
52
 
53
  # Gradio UI
54
  with gr.Blocks(theme=gr.themes.Soft(), css="""
55
+
 
 
 
 
 
 
 
 
 
56
  """) as iface:
57
 
58
  gr.Markdown("# JFK Document Analysis Suite")
 
92
  width=600
93
  )
94
 
95
+
 
 
 
 
 
 
 
 
 
 
 
 
 
96
 
97
  # Event handlers must be inside the Blocks context
98
  process_btn.click(
 
101
  outputs=[full_doc_text, output_summary, output_entities, output_wordcloud]
102
  )
103
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
104
 
105
  if __name__ == "__main__":
106
  iface.launch(
space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/app.py CHANGED
@@ -6,8 +6,6 @@ from entity_recognition import extract_entities
6
  from wordcloud import WordCloud
7
  from summarization import summarizer
8
  from utils import list_files, process_file
9
- import pygraphviz as pgv
10
- import os
11
 
12
  # Initialize FastAPI
13
  app = FastAPI()
@@ -16,175 +14,6 @@ app = FastAPI()
16
  class TextRequest(BaseModel):
17
  text: str
18
 
19
- def wrap_label(label, max_length=15):
20
- """Improved label wrapping with hyphenation awareness"""
21
- if len(label) <= max_length:
22
- return label
23
-
24
- # Try to break at natural points
25
- break_chars = [" ", "-", "_", "/"]
26
- lines = []
27
- current = ""
28
-
29
- for char in label:
30
- if len(current) >= max_length and char in break_chars:
31
- lines.append(current.strip())
32
- current = char
33
- else:
34
- current += char
35
-
36
- if current:
37
- lines.append(current.strip())
38
-
39
- return "\\n".join(lines)
40
- def generate_high_res_mindmap(text):
41
- """Generate high-quality mind map with improved visibility"""
42
- try:
43
- # Verify we have entities to visualize
44
- entities = extract_entities(text)
45
- if not any(entities.values()):
46
- print("No entities found to generate mind map")
47
- return None
48
-
49
- # Create temporary directory
50
- temp_dir = "/tmp/mindmaps"
51
- os.makedirs(temp_dir, exist_ok=True)
52
- output_path = os.path.join(temp_dir, "mindmap.png")
53
-
54
- # Create graph with optimized settings
55
- G = pgv.AGraph(
56
- directed=True,
57
- rankdir="TB", # Top-to-bottom layout
58
- bgcolor="white",
59
- fontname="Arial", # More readable font
60
- splines="ortho", # Straight lines
61
- overlap="false",
62
- concentrate="true",
63
- ratio="compress",
64
- size="50,50", # Larger canvas
65
- dpi="1000", # Higher resolution
66
- pad="1.0",
67
- nodesep="1.2", # More space between nodes
68
- ranksep="1.5" # More vertical space
69
- )
70
-
71
- # Enhanced node styling for better visibility
72
- G.node_attr.update({
73
- "fontsize": "24", # Larger font
74
- "fontname": "Arial Bold",
75
- "shape": "box",
76
- "style": "rounded,filled",
77
- "fillcolor": "#E1F5FE",
78
- "color": "#0288D1",
79
- "height": "0.8",
80
- "width": "2.0",
81
- "penwidth": "2.0",
82
- "margin": "0.3,0.1" # Better text padding
83
- })
84
-
85
- # Enhanced edge styling
86
- G.edge_attr.update({
87
- "color": "#616161",
88
- "penwidth": "2.5",
89
- "arrowsize": "1.2",
90
- "fontname": "Arial",
91
- "fontsize": "20",
92
- "fontcolor": "#424242"
93
- })
94
-
95
- # Add central node with improved styling
96
- G.add_node("DOCUMENT",
97
- shape="doubleoctagon",
98
- fillcolor="#4FC3F7",
99
- fontsize="28",
100
- width="2.5",
101
- height="1.0",
102
- penwidth="3.0")
103
-
104
- # Add entities with better spacing
105
- max_categories = 5
106
- max_entities = 8
107
-
108
- for cat_idx, (category, values) in enumerate(entities.items()):
109
- if cat_idx >= max_categories:
110
- break
111
-
112
- # Main category node
113
- cat_node = f"CAT_{cat_idx}"
114
- G.add_node(cat_node,
115
- label=wrap_label(category, 18),
116
- shape="tab",
117
- fillcolor="#81D4FA",
118
- fontsize="22")
119
-
120
- G.add_edge("DOCUMENT", cat_node,
121
- label="contains",
122
- penwidth="3.0")
123
-
124
- # Add entities with grouping if needed
125
- if len(values) > max_entities:
126
- # Create subcategory groups
127
- for sub_idx, group in enumerate([values[i:i+max_entities]
128
- for i in range(0, len(values), max_entities)]):
129
- sub_node = f"SUB_{cat_idx}_{sub_idx}"
130
- G.add_node(sub_node,
131
- label=f"Group {sub_idx+1}",
132
- shape="folder",
133
- fillcolor="#B3E5FC")
134
- G.add_edge(cat_node, sub_node)
135
-
136
- for ent_idx, value in enumerate(group):
137
- ent_node = f"ENT_{cat_idx}_{sub_idx}_{ent_idx}"
138
- G.add_node(ent_node,
139
- label=wrap_label(value, 15),
140
- shape="note",
141
- fillcolor="#E1F5FE")
142
- G.add_edge(sub_node, ent_node)
143
- else:
144
- # Directly add entities
145
- for ent_idx, value in enumerate(values[:max_entities]):
146
- ent_node = f"ENT_{cat_idx}_{ent_idx}"
147
- G.add_node(ent_node,
148
- label=wrap_label(value, 15),
149
- shape="note",
150
- fillcolor="#E1F5FE")
151
- G.add_edge(cat_node, ent_node)
152
-
153
- # Generate output with multiple attempts
154
- for engine in ['dot', 'neato', 'sfdp']:
155
- try:
156
- G.draw(output_path,
157
- format="png",
158
- prog=engine,
159
- args=f"-Gdpi=300 -Gsize=50,50 -Goverlap=prism")
160
- print(f"Successfully generated with {engine}")
161
-
162
- # Verify the output
163
- if os.path.exists(output_path) and os.path.getsize(output_path) > 0:
164
- return output_path
165
-
166
- except Exception as e:
167
- print(f"Layout engine {engine} failed: {str(e)}")
168
- continue
169
-
170
- raise RuntimeError("All layout engines failed")
171
-
172
- except Exception as e:
173
- print(f"Mind map generation failed: {str(e)}")
174
- # Create error visualization
175
- try:
176
- import matplotlib.pyplot as plt
177
- plt.figure(figsize=(20, 10))
178
- plt.text(0.5, 0.5,
179
- f"Mind Map Generation Failed\n{str(e)}\n\nOriginal Text:\n{text[:200]}...",
180
- ha='center', va='center', wrap=True)
181
- plt.axis('off')
182
- error_path = os.path.join(temp_dir, "error_mindmap.png")
183
- plt.savefig(error_path, bbox_inches='tight', dpi=300)
184
- plt.close()
185
- return error_path
186
- except:
187
- return None
188
  @app.post("/summarize")
189
  def summarize_text(request: TextRequest):
190
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
@@ -223,16 +52,7 @@ def generate_word_cloud(request: TextRequest):
223
 
224
  # Gradio UI
225
  with gr.Blocks(theme=gr.themes.Soft(), css="""
226
- .mindmap-container img {
227
- max-height: none !important;
228
- min-width: 100% !important;
229
- object-fit: contain !important;
230
- background: white !important;
231
- border: 1px solid #e0e0e0 !important;
232
- border-radius: 8px !important;
233
- padding: 20px !important;
234
- }
235
- .gradio-container { max-width: 1400px !important; }
236
  """) as iface:
237
 
238
  gr.Markdown("# JFK Document Analysis Suite")
@@ -272,20 +92,7 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
272
  width=600
273
  )
274
 
275
- # Mind map section
276
- with gr.Row():
277
- mindmap_btn = gr.Button(
278
- "Generate Enhanced Mind Map",
279
- variant="primary"
280
- )
281
-
282
- with gr.Row():
283
- output_mindmap = gr.Image(
284
- label="High-Resolution Mind Map",
285
- elem_classes="mindmap-container",
286
- height=800,
287
- width=800
288
- )
289
 
290
  # Event handlers must be inside the Blocks context
291
  process_btn.click(
@@ -294,37 +101,6 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
294
  outputs=[full_doc_text, output_summary, output_entities, output_wordcloud]
295
  )
296
 
297
- def display_mindmap(text):
298
- try:
299
- img_path = generate_high_res_mindmap(text)
300
- if img_path and os.path.exists(img_path):
301
- return img_path
302
- return None
303
- except Exception as e:
304
- print(f"Display error: {e}")
305
- return None
306
-
307
- mindmap_btn.click(
308
- fn=display_mindmap,
309
- inputs=full_doc_text,
310
- outputs=output_mindmap,
311
- api_name="generate_mindmap",
312
- show_progress=True
313
- )
314
-
315
- # Add CSS for better image display
316
- css = """
317
- .mindmap-container img {
318
- max-width: 100% !important;
319
- height: auto !important;
320
- background: white !important;
321
- border: 2px solid #e0e0e0 !important;
322
- border-radius: 8px !important;
323
- padding: 10px !important;
324
- margin: 10px auto !important;
325
- display: block !important;
326
- }
327
- """
328
 
329
  if __name__ == "__main__":
330
  iface.launch(
 
6
  from wordcloud import WordCloud
7
  from summarization import summarizer
8
  from utils import list_files, process_file
 
 
9
 
10
  # Initialize FastAPI
11
  app = FastAPI()
 
14
  class TextRequest(BaseModel):
15
  text: str
16
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
  @app.post("/summarize")
18
  def summarize_text(request: TextRequest):
19
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
 
52
 
53
  # Gradio UI
54
  with gr.Blocks(theme=gr.themes.Soft(), css="""
55
+
 
 
 
 
 
 
 
 
 
56
  """) as iface:
57
 
58
  gr.Markdown("# JFK Document Analysis Suite")
 
92
  width=600
93
  )
94
 
95
+
 
 
 
 
 
 
 
 
 
 
 
 
 
96
 
97
  # Event handlers must be inside the Blocks context
98
  process_btn.click(
 
101
  outputs=[full_doc_text, output_summary, output_entities, output_wordcloud]
102
  )
103
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
104
 
105
  if __name__ == "__main__":
106
  iface.launch(
space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/app.py CHANGED
@@ -6,8 +6,6 @@ from entity_recognition import extract_entities
6
  from wordcloud import WordCloud
7
  from summarization import summarizer
8
  from utils import list_files, process_file
9
- import pygraphviz as pgv
10
- import os
11
 
12
  # Initialize FastAPI
13
  app = FastAPI()
@@ -16,175 +14,6 @@ app = FastAPI()
16
  class TextRequest(BaseModel):
17
  text: str
18
 
19
- def wrap_label(label, max_length=15):
20
- """Improved label wrapping with hyphenation awareness"""
21
- if len(label) <= max_length:
22
- return label
23
-
24
- # Try to break at natural points
25
- break_chars = [" ", "-", "_", "/"]
26
- lines = []
27
- current = ""
28
-
29
- for char in label:
30
- if len(current) >= max_length and char in break_chars:
31
- lines.append(current.strip())
32
- current = char
33
- else:
34
- current += char
35
-
36
- if current:
37
- lines.append(current.strip())
38
-
39
- return "\\n".join(lines)
40
- def generate_high_res_mindmap(text):
41
- """Generate high-quality mind map with improved visibility"""
42
- try:
43
- # Verify we have entities to visualize
44
- entities = extract_entities(text)
45
- if not any(entities.values()):
46
- print("No entities found to generate mind map")
47
- return None
48
-
49
- # Create temporary directory
50
- temp_dir = "/tmp/mindmaps"
51
- os.makedirs(temp_dir, exist_ok=True)
52
- output_path = os.path.join(temp_dir, "mindmap.png")
53
-
54
- # Create graph with optimized settings
55
- G = pgv.AGraph(
56
- directed=True,
57
- rankdir="TB", # Top-to-bottom layout
58
- bgcolor="white",
59
- fontname="Arial", # More readable font
60
- splines="ortho", # Straight lines
61
- overlap="false",
62
- concentrate="true",
63
- ratio="compress",
64
- size="50,50", # Larger canvas
65
- dpi="1000", # Higher resolution
66
- pad="1.0",
67
- nodesep="1.2", # More space between nodes
68
- ranksep="1.5" # More vertical space
69
- )
70
-
71
- # Enhanced node styling for better visibility
72
- G.node_attr.update({
73
- "fontsize": "24", # Larger font
74
- "fontname": "Arial Bold",
75
- "shape": "box",
76
- "style": "rounded,filled",
77
- "fillcolor": "#E1F5FE",
78
- "color": "#0288D1",
79
- "height": "0.8",
80
- "width": "2.0",
81
- "penwidth": "2.0",
82
- "margin": "0.3,0.1" # Better text padding
83
- })
84
-
85
- # Enhanced edge styling
86
- G.edge_attr.update({
87
- "color": "#616161",
88
- "penwidth": "2.5",
89
- "arrowsize": "1.2",
90
- "fontname": "Arial",
91
- "fontsize": "20",
92
- "fontcolor": "#424242"
93
- })
94
-
95
- # Add central node with improved styling
96
- G.add_node("DOCUMENT",
97
- shape="doubleoctagon",
98
- fillcolor="#4FC3F7",
99
- fontsize="28",
100
- width="2.5",
101
- height="1.0",
102
- penwidth="3.0")
103
-
104
- # Add entities with better spacing
105
- max_categories = 5
106
- max_entities = 8
107
-
108
- for cat_idx, (category, values) in enumerate(entities.items()):
109
- if cat_idx >= max_categories:
110
- break
111
-
112
- # Main category node
113
- cat_node = f"CAT_{cat_idx}"
114
- G.add_node(cat_node,
115
- label=wrap_label(category, 18),
116
- shape="tab",
117
- fillcolor="#81D4FA",
118
- fontsize="22")
119
-
120
- G.add_edge("DOCUMENT", cat_node,
121
- label="contains",
122
- penwidth="3.0")
123
-
124
- # Add entities with grouping if needed
125
- if len(values) > max_entities:
126
- # Create subcategory groups
127
- for sub_idx, group in enumerate([values[i:i+max_entities]
128
- for i in range(0, len(values), max_entities)]):
129
- sub_node = f"SUB_{cat_idx}_{sub_idx}"
130
- G.add_node(sub_node,
131
- label=f"Group {sub_idx+1}",
132
- shape="folder",
133
- fillcolor="#B3E5FC")
134
- G.add_edge(cat_node, sub_node)
135
-
136
- for ent_idx, value in enumerate(group):
137
- ent_node = f"ENT_{cat_idx}_{sub_idx}_{ent_idx}"
138
- G.add_node(ent_node,
139
- label=wrap_label(value, 15),
140
- shape="note",
141
- fillcolor="#E1F5FE")
142
- G.add_edge(sub_node, ent_node)
143
- else:
144
- # Directly add entities
145
- for ent_idx, value in enumerate(values[:max_entities]):
146
- ent_node = f"ENT_{cat_idx}_{ent_idx}"
147
- G.add_node(ent_node,
148
- label=wrap_label(value, 15),
149
- shape="note",
150
- fillcolor="#E1F5FE")
151
- G.add_edge(cat_node, ent_node)
152
-
153
- # Generate output with multiple attempts
154
- for engine in ['dot', 'neato', 'sfdp']:
155
- try:
156
- G.draw(output_path,
157
- format="png",
158
- prog=engine,
159
- args=f"-Gdpi=300 -Gsize=50,50 -Goverlap=prism")
160
- print(f"Successfully generated with {engine}")
161
-
162
- # Verify the output
163
- if os.path.exists(output_path) and os.path.getsize(output_path) > 0:
164
- return output_path
165
-
166
- except Exception as e:
167
- print(f"Layout engine {engine} failed: {str(e)}")
168
- continue
169
-
170
- raise RuntimeError("All layout engines failed")
171
-
172
- except Exception as e:
173
- print(f"Mind map generation failed: {str(e)}")
174
- # Create error visualization
175
- try:
176
- import matplotlib.pyplot as plt
177
- plt.figure(figsize=(20, 10))
178
- plt.text(0.5, 0.5,
179
- f"Mind Map Generation Failed\n{str(e)}\n\nOriginal Text:\n{text[:200]}...",
180
- ha='center', va='center', wrap=True)
181
- plt.axis('off')
182
- error_path = os.path.join(temp_dir, "error_mindmap.png")
183
- plt.savefig(error_path, bbox_inches='tight', dpi=300)
184
- plt.close()
185
- return error_path
186
- except:
187
- return None
188
  @app.post("/summarize")
189
  def summarize_text(request: TextRequest):
190
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
@@ -223,16 +52,7 @@ def generate_word_cloud(request: TextRequest):
223
 
224
  # Gradio UI
225
  with gr.Blocks(theme=gr.themes.Soft(), css="""
226
- .mindmap-container img {
227
- max-height: none !important;
228
- min-width: 100% !important;
229
- object-fit: contain !important;
230
- background: white !important;
231
- border: 1px solid #e0e0e0 !important;
232
- border-radius: 8px !important;
233
- padding: 20px !important;
234
- }
235
- .gradio-container { max-width: 1400px !important; }
236
  """) as iface:
237
 
238
  gr.Markdown("# JFK Document Analysis Suite")
@@ -272,20 +92,7 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
272
  width=600
273
  )
274
 
275
- # Mind map section
276
- with gr.Row():
277
- mindmap_btn = gr.Button(
278
- "Generate Enhanced Mind Map",
279
- variant="primary"
280
- )
281
-
282
- with gr.Row():
283
- output_mindmap = gr.Image(
284
- label="High-Resolution Mind Map",
285
- elem_classes="mindmap-container",
286
- height=800,
287
- width=800
288
- )
289
 
290
  # Event handlers must be inside the Blocks context
291
  process_btn.click(
@@ -294,37 +101,6 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
294
  outputs=[full_doc_text, output_summary, output_entities, output_wordcloud]
295
  )
296
 
297
- def display_mindmap(text):
298
- try:
299
- img_path = generate_high_res_mindmap(text)
300
- if img_path and os.path.exists(img_path):
301
- return img_path
302
- return None
303
- except Exception as e:
304
- print(f"Display error: {e}")
305
- return None
306
-
307
- mindmap_btn.click(
308
- fn=display_mindmap,
309
- inputs=full_doc_text,
310
- outputs=output_mindmap,
311
- api_name="generate_mindmap",
312
- show_progress=True
313
- )
314
-
315
- # Add CSS for better image display
316
- css = """
317
- .mindmap-container img {
318
- max-width: 100% !important;
319
- height: auto !important;
320
- background: white !important;
321
- border: 2px solid #e0e0e0 !important;
322
- border-radius: 8px !important;
323
- padding: 10px !important;
324
- margin: 10px auto !important;
325
- display: block !important;
326
- }
327
- """
328
 
329
  if __name__ == "__main__":
330
  iface.launch(
 
6
  from wordcloud import WordCloud
7
  from summarization import summarizer
8
  from utils import list_files, process_file
 
 
9
 
10
  # Initialize FastAPI
11
  app = FastAPI()
 
14
  class TextRequest(BaseModel):
15
  text: str
16
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
  @app.post("/summarize")
18
  def summarize_text(request: TextRequest):
19
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
 
52
 
53
  # Gradio UI
54
  with gr.Blocks(theme=gr.themes.Soft(), css="""
55
+
 
 
 
 
 
 
 
 
 
56
  """) as iface:
57
 
58
  gr.Markdown("# JFK Document Analysis Suite")
 
92
  width=600
93
  )
94
 
95
+
 
 
 
 
 
 
 
 
 
 
 
 
 
96
 
97
  # Event handlers must be inside the Blocks context
98
  process_btn.click(
 
101
  outputs=[full_doc_text, output_summary, output_entities, output_wordcloud]
102
  )
103
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
104
 
105
  if __name__ == "__main__":
106
  iface.launch(
space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/app.py CHANGED
@@ -6,8 +6,6 @@ from entity_recognition import extract_entities
6
  from wordcloud import WordCloud
7
  from summarization import summarizer
8
  from utils import list_files, process_file
9
- import pygraphviz as pgv
10
- import os
11
 
12
  # Initialize FastAPI
13
  app = FastAPI()
@@ -16,175 +14,6 @@ app = FastAPI()
16
  class TextRequest(BaseModel):
17
  text: str
18
 
19
- def wrap_label(label, max_length=15):
20
- """Improved label wrapping with hyphenation awareness"""
21
- if len(label) <= max_length:
22
- return label
23
-
24
- # Try to break at natural points
25
- break_chars = [" ", "-", "_", "/"]
26
- lines = []
27
- current = ""
28
-
29
- for char in label:
30
- if len(current) >= max_length and char in break_chars:
31
- lines.append(current.strip())
32
- current = char
33
- else:
34
- current += char
35
-
36
- if current:
37
- lines.append(current.strip())
38
-
39
- return "\\n".join(lines)
40
- def generate_high_res_mindmap(text):
41
- """Generate high-quality mind map with improved visibility"""
42
- try:
43
- # Verify we have entities to visualize
44
- entities = extract_entities(text)
45
- if not any(entities.values()):
46
- print("No entities found to generate mind map")
47
- return None
48
-
49
- # Create temporary directory
50
- temp_dir = "/tmp/mindmaps"
51
- os.makedirs(temp_dir, exist_ok=True)
52
- output_path = os.path.join(temp_dir, "mindmap.png")
53
-
54
- # Create graph with optimized settings
55
- G = pgv.AGraph(
56
- directed=True,
57
- rankdir="TB", # Top-to-bottom layout
58
- bgcolor="white",
59
- fontname="Arial", # More readable font
60
- splines="ortho", # Straight lines
61
- overlap="false",
62
- concentrate="true",
63
- ratio="compress",
64
- size="50,50", # Larger canvas
65
- dpi="1000", # Higher resolution
66
- pad="1.0",
67
- nodesep="1.2", # More space between nodes
68
- ranksep="1.5" # More vertical space
69
- )
70
-
71
- # Enhanced node styling for better visibility
72
- G.node_attr.update({
73
- "fontsize": "24", # Larger font
74
- "fontname": "Arial Bold",
75
- "shape": "box",
76
- "style": "rounded,filled",
77
- "fillcolor": "#E1F5FE",
78
- "color": "#0288D1",
79
- "height": "0.8",
80
- "width": "2.0",
81
- "penwidth": "2.0",
82
- "margin": "0.3,0.1" # Better text padding
83
- })
84
-
85
- # Enhanced edge styling
86
- G.edge_attr.update({
87
- "color": "#616161",
88
- "penwidth": "2.5",
89
- "arrowsize": "1.2",
90
- "fontname": "Arial",
91
- "fontsize": "20",
92
- "fontcolor": "#424242"
93
- })
94
-
95
- # Add central node with improved styling
96
- G.add_node("DOCUMENT",
97
- shape="doubleoctagon",
98
- fillcolor="#4FC3F7",
99
- fontsize="28",
100
- width="2.5",
101
- height="1.0",
102
- penwidth="3.0")
103
-
104
- # Add entities with better spacing
105
- max_categories = 5
106
- max_entities = 8
107
-
108
- for cat_idx, (category, values) in enumerate(entities.items()):
109
- if cat_idx >= max_categories:
110
- break
111
-
112
- # Main category node
113
- cat_node = f"CAT_{cat_idx}"
114
- G.add_node(cat_node,
115
- label=wrap_label(category, 18),
116
- shape="tab",
117
- fillcolor="#81D4FA",
118
- fontsize="22")
119
-
120
- G.add_edge("DOCUMENT", cat_node,
121
- label="contains",
122
- penwidth="3.0")
123
-
124
- # Add entities with grouping if needed
125
- if len(values) > max_entities:
126
- # Create subcategory groups
127
- for sub_idx, group in enumerate([values[i:i+max_entities]
128
- for i in range(0, len(values), max_entities)]):
129
- sub_node = f"SUB_{cat_idx}_{sub_idx}"
130
- G.add_node(sub_node,
131
- label=f"Group {sub_idx+1}",
132
- shape="folder",
133
- fillcolor="#B3E5FC")
134
- G.add_edge(cat_node, sub_node)
135
-
136
- for ent_idx, value in enumerate(group):
137
- ent_node = f"ENT_{cat_idx}_{sub_idx}_{ent_idx}"
138
- G.add_node(ent_node,
139
- label=wrap_label(value, 15),
140
- shape="note",
141
- fillcolor="#E1F5FE")
142
- G.add_edge(sub_node, ent_node)
143
- else:
144
- # Directly add entities
145
- for ent_idx, value in enumerate(values[:max_entities]):
146
- ent_node = f"ENT_{cat_idx}_{ent_idx}"
147
- G.add_node(ent_node,
148
- label=wrap_label(value, 15),
149
- shape="note",
150
- fillcolor="#E1F5FE")
151
- G.add_edge(cat_node, ent_node)
152
-
153
- # Generate output with multiple attempts
154
- for engine in ['dot', 'neato', 'sfdp']:
155
- try:
156
- G.draw(output_path,
157
- format="png",
158
- prog=engine,
159
- args=f"-Gdpi=300 -Gsize=50,50 -Goverlap=prism")
160
- print(f"Successfully generated with {engine}")
161
-
162
- # Verify the output
163
- if os.path.exists(output_path) and os.path.getsize(output_path) > 0:
164
- return output_path
165
-
166
- except Exception as e:
167
- print(f"Layout engine {engine} failed: {str(e)}")
168
- continue
169
-
170
- raise RuntimeError("All layout engines failed")
171
-
172
- except Exception as e:
173
- print(f"Mind map generation failed: {str(e)}")
174
- # Create error visualization
175
- try:
176
- import matplotlib.pyplot as plt
177
- plt.figure(figsize=(20, 10))
178
- plt.text(0.5, 0.5,
179
- f"Mind Map Generation Failed\n{str(e)}\n\nOriginal Text:\n{text[:200]}...",
180
- ha='center', va='center', wrap=True)
181
- plt.axis('off')
182
- error_path = os.path.join(temp_dir, "error_mindmap.png")
183
- plt.savefig(error_path, bbox_inches='tight', dpi=300)
184
- plt.close()
185
- return error_path
186
- except:
187
- return None
188
  @app.post("/summarize")
189
  def summarize_text(request: TextRequest):
190
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
@@ -223,16 +52,7 @@ def generate_word_cloud(request: TextRequest):
223
 
224
  # Gradio UI
225
  with gr.Blocks(theme=gr.themes.Soft(), css="""
226
- .mindmap-container img {
227
- max-height: none !important;
228
- min-width: 100% !important;
229
- object-fit: contain !important;
230
- background: white !important;
231
- border: 1px solid #e0e0e0 !important;
232
- border-radius: 8px !important;
233
- padding: 20px !important;
234
- }
235
- .gradio-container { max-width: 1400px !important; }
236
  """) as iface:
237
 
238
  gr.Markdown("# JFK Document Analysis Suite")
@@ -272,20 +92,7 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
272
  width=600
273
  )
274
 
275
- # Mind map section
276
- with gr.Row():
277
- mindmap_btn = gr.Button(
278
- "Generate Enhanced Mind Map",
279
- variant="primary"
280
- )
281
-
282
- with gr.Row():
283
- output_mindmap = gr.Image(
284
- label="High-Resolution Mind Map",
285
- elem_classes="mindmap-container",
286
- height=800,
287
- width=800
288
- )
289
 
290
  # Event handlers must be inside the Blocks context
291
  process_btn.click(
@@ -294,37 +101,6 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
294
  outputs=[full_doc_text, output_summary, output_entities, output_wordcloud]
295
  )
296
 
297
- def display_mindmap(text):
298
- try:
299
- img_path = generate_high_res_mindmap(text)
300
- if img_path and os.path.exists(img_path):
301
- return img_path
302
- return None
303
- except Exception as e:
304
- print(f"Display error: {e}")
305
- return None
306
-
307
- mindmap_btn.click(
308
- fn=display_mindmap,
309
- inputs=full_doc_text,
310
- outputs=output_mindmap,
311
- api_name="generate_mindmap",
312
- show_progress=True
313
- )
314
-
315
- # Add CSS for better image display
316
- css = """
317
- .mindmap-container img {
318
- max-width: 100% !important;
319
- height: auto !important;
320
- background: white !important;
321
- border: 2px solid #e0e0e0 !important;
322
- border-radius: 8px !important;
323
- padding: 10px !important;
324
- margin: 10px auto !important;
325
- display: block !important;
326
- }
327
- """
328
 
329
  if __name__ == "__main__":
330
  iface.launch(
 
6
  from wordcloud import WordCloud
7
  from summarization import summarizer
8
  from utils import list_files, process_file
 
 
9
 
10
  # Initialize FastAPI
11
  app = FastAPI()
 
14
  class TextRequest(BaseModel):
15
  text: str
16
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
  @app.post("/summarize")
18
  def summarize_text(request: TextRequest):
19
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
 
52
 
53
  # Gradio UI
54
  with gr.Blocks(theme=gr.themes.Soft(), css="""
55
+
 
 
 
 
 
 
 
 
 
56
  """) as iface:
57
 
58
  gr.Markdown("# JFK Document Analysis Suite")
 
92
  width=600
93
  )
94
 
95
+
 
 
 
 
 
 
 
 
 
 
 
 
 
96
 
97
  # Event handlers must be inside the Blocks context
98
  process_btn.click(
 
101
  outputs=[full_doc_text, output_summary, output_entities, output_wordcloud]
102
  )
103
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
104
 
105
  if __name__ == "__main__":
106
  iface.launch(
space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/jfk_text/104-10003-10041.md ADDED
@@ -0,0 +1,47 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # 104-10003-10041 2025 RELEASE UNDER THE PRESIDENT JOHN F. KENNEDY ASSASSINATION RECORDS ACT OF 1992
2
+
3
+ ☐ UNCLASSIFIED
4
+ ☐ INTERNAL ONLY
5
+ ☐ CONFI**I**NTIAL
6
+ ☑ SECRET
7
+
8
+ ## ROUTING AND RECORD SHEET
9
+
10
+ SUBJECT: (Optional)
11
+
12
+ Clipping of article "The Kennedy Murder and the Secret Services of the USA"
13
+
14
+ FROM:
15
+
16
+ WE/4/INT Arthur P. Iorio
17
+
18
+ EXTENSION NO.
19
+
20
+ DATE: 26 March 1964
21
+
22
+ TO: (Officer designation, room number, and building) | DATE | OFFICER'S INITIALS | COMMENTS (Number each comment to show from whom to whom. Draw a line across column after each comment.)
23
+ -----|------|-------|-----
24
+ 1. CI Staff Birch O'Neil Room 2603 | RECEIVED | FORWARDED | The attached article, which may be of interest to you, appeared in the 7 March issue of the Italian Communist Party weekly Rinascita. The writer, Gianfranco Corsini, has been on and off US correspondent for the Italian Communist press. Note that in the section pencille in red rumors are referred which suggest that kind it was the Agency to organize the murder of President Kennedy.
25
+ 2. | | |
26
+ 3. | | |
27
+ 4. | | |
28
+ 5. | | |
29
+ 6. | | |
30
+ 7. | | |
31
+ 8. | | |
32
+ 9. | | |
33
+ 10. | | |
34
+ 11. | | |
35
+ 12. | | |
36
+ 13. | | |
37
+ 14. | | |
38
+ 15. | | 18 |
39
+
40
+ FORM 610 USE PREVIOUS EDITIONS 3-62
41
+
42
+ ☑ SECRET
43
+ ☐ CONFIDENTIAL
44
+ ☐ INTERNAL USE ONLY
45
+ ☐ UNCLASSIFIED
46
+
47
+ Clipping not retained
space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/jfk_text/104-10004-10143 (C06932208).md ADDED
@@ -0,0 +1,147 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ 104-10004-10143
2
+ 2025 RELEASE UNDER THE PRESIDENT JOHN F. KENNEDY ASSASSINATION RECORDS ACT OF 1992
3
+
4
+ Date: 05/08/96
5
+ Page: 1
6
+
7
+ JFK ASSASSINATION SYSTEM
8
+ IDENTIFICATION FORM
9
+
10
+ AGENCY INFORMATION
11
+
12
+ AGENCY : CIA
13
+ RECORD NUMBER : 104-10004-10143
14
+ RECORD SERIES : JFK
15
+ AGENCY FILE NUMBER : 201-289248
16
+
17
+ DOCUMENT INFORMATION
18
+
19
+ ORIGINATOR : CIA
20
+ FROM :
21
+ TO :
22
+ TITLE : DISCUSSION BETWEEN MEMBER SR DIVISION CONCERNING
23
+ OSWALD'S STAY IN HELSINKI.
24
+ DATE : 06/01/64
25
+ PAGES : 2
26
+ SUBJECTS : HELSINKI TRIP
27
+ USSR CONSULATE
28
+
29
+ DOCUMENT TYPE : PAPER, TEXTUAL DOCUMENT
30
+ CLASSIFICATION : SECRET
31
+ RESTRICTIONS : 1B
32
+ CURRENT STATUS : RELEASED WITH DELETIONS
33
+ DATE OF LAST REVIEW : 06/12/93
34
+ OPENING CRITERIA :
35
+ COMMENTS : OSW10:V43 1993.06.12.10:33:55:150000:
36
+
37
+ [R] ITEM IS RESTRICTED
38
+ NW 64937 Docld:32106269 Page 1
39
+
40
+ INTERNAL
41
+ USE ONLY
42
+ CO DENTIAL
43
+ SECRET
44
+ ROUTING AND RECORD SHEET
45
+
46
+ SUBJECT: (Optional)
47
+
48
+ FROM: CIRA/PS
49
+ 2823
50
+
51
+ TO: (Officer designation, room number, and
52
+ building)
53
+ DATE
54
+ SX-25605
55
+ 1 June 64
56
+
57
+ OFFICER'S
58
+ INITIALS
59
+ COMMENTS (Number each comment to show from whom
60
+ to whom. Draw a line across column after each comment.)
61
+ RECEIVED
62
+ FORWARDED
63
+ 1.
64
+ IPIAN
65
+ 5 MAR 1975
66
+ Phoe assign
67
+ SX # and
68
+ clamefs to
69
+ 2.
70
+ 3.
71
+ 4.
72
+ 5.
73
+ IP JEDI
74
+ 6.
75
+ 201-289248
76
+ 7.
77
+ 8.
78
+ IPIFILES
79
+ Document Number 716-838
80
+ for FOIA Review on JUN 1976
81
+
82
+ Ath Pori, Millen
83
+ 10.
84
+ 11.
85
+ 12.
86
+ 13.
87
+ 14.
88
+ 15.
89
+ FORM 610 USE PREVIOUS
90
+ NW-64937 DocId 32906269 Page 2
91
+ CONFIDENTIAL
92
+ INTERNAL
93
+ USE ONLY
94
+ UNCLASSIFIED
95
+
96
+ MEMO FOR THE RECORD
97
+ 1 June 1964.
98
+ SX-25605
99
+ Discussion betroen MOMBOR SR. Divisiong
100
+ and CoS Helsinki CONCERNING timetable
101
+ OF OSWALD'S stay in and Holsinki
102
+
103
+ 1. At 0900 this morning I talked with Frank Friberg recently
104
+ returned COS Helsinki re Warren Commission inquiry concerning
105
+ the timetable of Oswald's stay in Finland in October 1959, including
106
+ his contact with the Soviet Consulate there. (Copy of the Commission
107
+ letter of 25 May 64 and State Cable of 22 May 64 attached.)
108
+
109
+ 2. Friberg gave me the following information:
110
+
111
+ a. It takes 25 minutes to drive from the airport to
112
+ downtown Helsinki;
113
+
114
+ b. By taxi, it would take no more than 5 minutes to
115
+ reach the Soviet consulate;
116
+
117
+ C. The Soviet consulate probably closed at 1300 hours local
118
+ time on Saturdays in 1959;
119
+
120
+ d. Passenger lists (manifests) at the U.S. Consulate in
121
+ Helsinki are retained for six months only and then are destroyed.
122
+ Mr. Robert Fulton (CIA) was U.S. consular official there at
123
+ the time.
124
+
125
+ e. A copy of State's cable inquiry would go to the Helsinki
126
+ Station and they would assist in preparation of a reply.
127
+
128
+ 3. Mr. Friberg agreed that it would be worthwhile to cable che
129
+ Station concerning points not covered by State in their inquiry. He
130
+ suggested changes incorporated into the cable sent to Helsinki.
131
+
132
+ Lee H. Wigren
133
+ C/SR/CI/R
134
+
135
+ Document Number
136
+ for FOIA Review on.
137
+ 716-838
138
+ JUN 1976
139
+ SAME AS RELEASED
140
+ DOC
141
+ 340
142
+
143
+ RECORD COPY
144
+ 1
145
+ 1 Jun 64
146
+ 201-289248
147
+ NW 64937 Docld:32106269 Page 3
space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/jfk_text/104-10004-10143.md ADDED
@@ -0,0 +1,68 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ 10.00000
2
+ 104-10004-10143 2025 RELEASE UNDER THE PRESIDENT JOHN F. KENNEDY ASSASSINATION RECORDS ACT OF 1992
3
+
4
+ 13-00000
5
+
6
+ MEMO FOR THE RECORD 1 June 1964
7
+ Sx-25605
8
+
9
+ DISCUSSION between members SR Division,
10
+ and CoS Helsinki concerning timetable
11
+ OF OSWALD'S stay in Finland and Helsinki
12
+
13
+ 1. At 0900 this morning I talked with Frank Friberg recently
14
+ returned COS Helsinki re Warren Commission inguiry concerninge.
15
+ the timetable of Oswald's stay in Finland in October 1959, including
16
+ his contact with the Soviet Consulate therer. (Copy of the Commission
17
+ letter of 25 May 64 and State Cable of 22 May, 64, attached.)
18
+
19
+ 2. Friberg gave me the following information:
20
+
21
+ a. It takes 25 minutes to drive from the airport to
22
+ Helsinki.
23
+
24
+ b. By taxi, it would take no more than 5 minutes to
25
+ reach the Soviet consulate;
26
+
27
+ c. Consulate in Helsinki was open Saturdays in 1959;
28
+
29
+ d. Passenger lists (manifests) at the Helsinki airports of
30
+ Helsinki are retained for six months only and then are destroyed.
31
+ Mr. Robert Fulton (CIA) was U.S. consular official there at
32
+ the time.
33
+
34
+ e. A copy of State's cable inquiry would go to the Helsinki
35
+ Station and they would assist in preparation of a reply.
36
+
37
+ 3. Mr. Friberg agreed that it would be worthwhile to cable the
38
+ Station concerning points not covered by State in their inquiry. He
39
+ suggested changes incorporated into the cable sent to Helsinki.
40
+
41
+ Lee H. Wigren
42
+ C/SR/CI/R
43
+ TRAVEL PROGRAM
44
+ IP/EDI ABSTRACTA
45
+ INDEX
46
+ IP/FIS
47
+ IP/PH
48
+ PREPARE FOR FICKING
49
+ FILM
50
+ CODE NO. (2,3,4)
51
+ RYBAT REST CODE
52
+ ISO/DCU
53
+ CABLE IDEN (11)
54
+ NTD (8)
55
+ IP/FILES
56
+ FOR FILING
57
+
58
+ Document Number 716-838
59
+ for FOIA Review on JUN 1976
60
+ SAME AS RELEASED
61
+ DOC -340
62
+
63
+ RECORD COPY
64
+
65
+ 1. Jun 64
66
+ 201-289248
67
+
68
+ Box 8
space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/jfk_text/104-10004-10156.md ADDED
@@ -0,0 +1,55 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ 10.00000
2
+ 104-10004-10156
3
+ 2025 RELEASE UNDER THE PRESIDENT JOHN F. KENNEDY ASSASSINATION RECORDS ACT OF 1992
4
+
5
+ Box 8
6
+
7
+ 13-00000
8
+
9
+ 1 June 1964
10
+
11
+ MEMO FOR THE RECORD
12
+
13
+ 1. At 0900 this morning I talked with Frank Friberg recently
14
+ returned COS Helsinki re Warren Commission inquiry concerning
15
+ the timetable of Oswald's stay in Finland in October 1959, including
16
+ his contact with the Soviet Consulate there. (Copy of the Commission
17
+ letter of 25 May 64 and State Cable of 22 May 64 attached.)
18
+
19
+ 2. Friberg gave me the following information:
20
+
21
+ a. It takes 25 minutes to drive from the airport to
22
+ downtown Helsinki;
23
+
24
+ b. By taxi, it would take no more than 5 minutes to
25
+ reach the Soviet consulate;
26
+
27
+ c. The Soviet consulate probably closed at 1300 hours local
28
+ time on Saturdays in 1959;
29
+
30
+ d. Passenger lists (manifests) at the U.S. Consulate in
31
+ Helsinki are retained for six months only and then are destroyed.
32
+ Mr. Robert Fulton (CIA) was U.S. consular official there at
33
+ the time.
34
+
35
+ e. A copy of State's cable inquiry would go to the Helsinki
36
+ Station and they would assist in preparation of a reply.
37
+
38
+ 3. Mr. Friberg agreed that it would be worthwhile to cable the
39
+ Station concerning points not covered by State in their inquiry. He
40
+ suggested changes incorporated into the cable sent to Helsinki.
41
+
42
+ Document Number 780-340
43
+
44
+ FAIA Review on JUN 1976
45
+
46
+ SAME AS 716-838
47
+
48
+ ZONET
49
+
50
+ 13-00000
51
+
52
+ See Sanitized File
53
+ Number 335
54
+ For steril
55
+ H
space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/jfk_text/104-10004-10213.md ADDED
@@ -0,0 +1,206 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ 104-10004-10213 2025 RELEASE UNDER THE PRESIDENT JOHN F. KENNEDY ASSASSINATION RECORDS ACT OF 1992
2
+
3
+ SECRET
4
+
5
+ YF2-27221
6
+ 9 July 1964
7
+
8
+ MEMORANDUM FOR THE RECORD
9
+ SUBJECT : Discussion with Warren Commission Staff Member
10
+ REFERENCE: Letter from J. Lee Rankin, General Counsel of the
11
+ President's Commission, to Mr. Richard Helms
12
+ dated 3 July 1964
13
+
14
+ >O SRICE DISCUSSION with SLAUSEN & Tily on .girations.
15
+ Svitt felicy towards design woats HALETICONS ANd
16
+ CUINT Visa Puccedures,
17
+ 1. With the approval of C/SR and the DDP, I met with Mr. W.
18
+ David Slawson of the staff of the President's Commission on the
19
+ Assassination of President Kennedy at 1400 hours on this date in
20
+ the Commission's offices at 200 Maryland Avenue, N.E., Washington,
21
+ D.C. The purpose of this meeting was to discuss apparent inconsistencies
22
+ in material provided the Commission by CIA and by the Department of
23
+ State which were called to our attention in a letter from the General
24
+ Counsel of the Commission to Mr. Helms, dated 3 July 1964.
25
+
26
+ 2. By way of introduction, Mr. Slawson said that in the portion of the
27
+ Commission's report that he was writing, he would have to deal with the
28
+ question of whether or not the OSWALDs' departure from the USSR - and
29
+ the circumstances (i.e. timing) of that departare were unusual or
30
+ suspicious in any way. He expressed his belief that they probably were
31
+ not and cited Soviet relaxation in such matters in the post-Stalin era.
32
+ However, he wanted to be sure in his own mind that our information was
33
+ not in conflict with that which the Commission had received from State
34
+ since all of that information would remain in the records of the
35
+ Commission.
36
+
37
+ 3. After stating my belief that there was no real disagreement or
38
+ inconsistency between the information from CLA and that from State, I
39
+ expressed the view that the matter resolved itself into three questions:
40
+
41
+ Document Number 767-864
42
+ for FOIA Review on
43
+ /a. Do the Soviet
44
+ JUN 1976
45
+
46
+ CS COPY
47
+
48
+ SECRET
49
+
50
+ a. Do the Soviet authorities normally permit Soviet
51
+ citizens married to foreign nationals to emigrate from the
52
+ Soviet Union to the homelands of their spouses?
53
+
54
+ b. Do they normally permit such Soviet citizens to
55
+ accompany (i.e. depart simultaneously with) their spouses
56
+ from the Soviet Union?
57
+
58
+ c. How long does it take such Soviet citizens to get
59
+ Soviet exit visas for such a purpose (time lapse from application
60
+ to granting of visas)?
61
+
62
+ 4. Concerning the first two questions (3a and 3b above) I pointed out.
63
+ that we had addressed ourselves mainly to the question of Sovie: citizens
64
+ being allowed to accompany their spouses abroad while State dealt only
65
+ with the larger question of Soviets married to foreigners being allowed
66
+ to emigrate without reference to whether or not they left simultaneously
67
+ with or at another time from their spouses. Mr. Slawson commented
68
+ that this explanation was most helpful and he reread what both we and
69
+ State had said in that light.
70
+
71
+ 5. By way of further explanation, I said that the statements in
72
+ paragraph 6 of our memorandum of 6 April 1964 concerning Soviets being
73
+ permitted to accompany their foreign spouses abroad were based on a
74
+ review of 26 cases, of which 10 involved Americans. In only four of
75
+ these cases did a Soviet wife leave the USSR in the company of her foreign
76
+ husband; in 14 of the cases the foreign spouse departed alone; and in the
77
+ remaining seven cases insufficient details are known to permit us to
78
+ categorize them. I added that although State's information began by
79
+ citing the issuance of 724 quota and non-quota immigrant visas by the
80
+ American Embassy in Moscow during the period FY 1954 to December
81
+ 1963, it did not indicate how many of these visas were for Soviet citizens
82
+ who had married U.S. nationals. Actually State provided detailed
83
+ information for only sixteen cases and did not indicate in many of these
84
+ whether or not the Soviet was permitted to accompany the foreign spouse.
85
+ 16. In response to
86
+
87
+ -2-
88
+
89
+ 6. In response to a question from Mr. Slawson I stated that most
90
+ of the 26 cases upon which we based our statements involved foreign
91
+ students, exchange teachers and other relatively transient persons,
92
+ and while a number of cases have certain points in common, they bear
93
+ little similarity to the OSWALD case in that none involved a defector who
94
+ married prior to repatriating. I noted that paragraph 6 of our 6 April
95
+ 1964 memorandum to the Commission had pointed this out. Mr. Slawson
96
+ indicated that he was now satisfied on this matter.
97
+
98
+ 7. Concerning the length of time taken by Soviet authorities to
99
+ process exit visas for Soviet citizens married to foreign nationals
100
+ (question 3c above), I stated that, in my opinion, the information
101
+ provided by State (in the third enclosure to Mr. Meeker's letter)
102
+ substantially corresponded to the views expressed in paragraphs 6 and 7
103
+ of our memorandum to the Commission dated 6 April 1964. Mr. Slawson
104
+ asked if it would be possible to elaborate paragraph 7 of our memorandum
105
+ of 6 April by providing a statistical breakdown of the cases on which our
106
+ statements were based. I indicated that this could be done.
107
+
108
+ 8. At this point Mr. Slawson stated that as a result of our discussion
109
+ he felt that the question of possible inconsistencies bad been resolved.
110
+ However, he asked that we send a brief written reply to the Commission's
111
+ letter of 3 July 1964 embodying the substance of what I had said concerning
112
+ the basis for statements included in our 6 April 1964 memorandum. (This
113
+ would include the gist of the draft reply to the Commission which I showed
114
+ to C/SR on 8 July plus an elaboration of our statements concerning Soviet
115
+ visa applications.]
116
+
117
+ 9. Mr. Slawson indicated that he would be sending parts of his report
118
+ dealing with the Soviet intelligence services to CIA for checking as to
119
+ their accuracy. He did not say when this would occur.
120
+
121
+ 10. After concluding the meeting with Mr. Slawson, I read Volume 52
122
+ of the transcript of testimony before the Commission. This included the
123
+ reinterview of Marina OSWALD.
124
+
125
+ -3-
126
+
127
+ Lee H. Wigren
128
+ C/SR/CI/Research
129
+
130
+ @Do. sors normally permit Sov. cityens married to for
131
+ natla to engrate pom Sll to homeland of sprise ?
132
+ • State says you - cites 724 visa applicationم
133
+ (perbably minority Spouse's; mij
134
+ belatives ite ast mijint)
135
+ - We cite absence of law; do not say.
136
+
137
+ 2 arimally
138
+ ② Do Sros permit sou. cits menit to fon marks to
139
+ accompany (ie depont simultanernely co.) spouses
140
+ from Sele to homelandes of spouses
141
+ - State does not say
142
+ se cite evidence that they do not
143
+ We ليه
144
+
145
+ ③ How long does it take Soveits to gel. Sevivians
146
+ at to homelan Ss of fou Spouses?
147
+ to junge at
148
+ -Our #7 and State's inse
149
+ فه
150
+ Cases inhuid. it ikurus ajrec
151
+
152
+ Notes, Hedin
153
+ Co
154
+ CS-COPY
155
+
156
+ dil Ite XAA2-27221
157
+
158
+ Le 7
159
+ with) friin sprστασις
160
+ Based on in de la 26 Cail
161
+ fre till out c/ SU.
162
+ (10 US)
163
+
164
+ -Safe left line oftenband - 4
165
+ -
166
+ -
167
+ -
168
+ -
169
+ - 7- !
170
+
171
+ ② Irifi in fu 47
172
+ 1-2 fine taken by for allite
173
+ bisa apple of Sor Spencer of fin
174
+ substant illy agrees is lite o infe
175
+ نر
176
+ 4. on Juice taken by Sri-st. poreias veda
177
+ aggelies of Sou woofcitis (1)
178
+
179
+ Gust of State is w
180
+ life cancion y bar, tibi of tense to her bij de citthoritie
181
+ 1.
182
+ bun cits in Sel
183
+ life in the poor
184
+ /
185
+ 740
186
+ li inquest for norme of all 1152
187
+ ت
188
+ :/ cits vitus ricerit'd in Cast
189
+ 2: 10 quo cesta Collis len, the of
190
+ fine betinien intrs of aggler. l. He apport
191
+ by God auth
192
+ 2 יני
193
+
194
+ Aun cat
195
+ 0063
196
+ >
197
+
198
+ ② Date of appplectenfor os doit reser
199
+ Ion dedures, in 14
200
+ 12
201
+
202
+ "
203
+ [10dayo-194]
204
+ Promplit all itthees
205
+ -10 line to 14 yeю
206
+ - Cant till bord
space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/jfk_text/104-10005-10321.md ADDED
@@ -0,0 +1,82 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ 2025 RELEASE UNDER THE PRESIDENT JOHN F. KENNEDY ASSASSINATION RECORDS ACT OF 1992
2
+
3
+ CLASSIFIED MESSAGE
4
+
5
+ SECRETARTDAT
6
+
7
+ 30 September 64 FILE NO. 201-4524
8
+
9
+ BONN, FRANKFURT, BERLIN, COPENHAGEN,
10
+ REYKJAVIK, PARIS, STOCKHOLM
11
+ DIRECTOR THE HAGUE BRUSSELS
12
+
13
+ nue, stess, cluez, VR, FILE
14
+
15
+ UN, FRAN, BRLN, COPENJO GMNY
16
+ E. PARI, STOC, muda, Hagu, Beas
17
+
18
+ AT/KUDESK/TPMURILLO / CATIJA
19
+
20
+ KIGREST TRACES JOACHIM JOESTER DPOB 29 JUL 07 COLOGNE.
21
+
22
+ ENTER ENTIRE ADULT CAREER AND AUTHOR CA 30 BOOKS AND NUMEROUS
23
+ SPAPER ARTICLES. POST WWII WORKS VERY ANTI-KUBARK, LAST
24
+ OK TITLE - OSWALD: ASSASSIN OR FALL GUY? HAS WRITTEN UNDER
25
+ UE NAME AND UNDER PSEUDONYMS: FRANZ VON NESSELRODE; H.F.
26
+ LIKIN; WALTER KELL; PAUL DELATHUIS.
27
+
28
+ 2. ACCORDING CAPTURED GESTAPO DOCS HE JOINED GERM CP ON
29
+ MAY 32 AND HAD MEMBERSHIP NO. 532315. OWNED LENDING LIBRARY
30
+ LN AND SOME TIME AFTER MAY 32 WENT USSR WHERE REMAINED UNTIL
31
+
32
+ 33. DURING ABSENCE HIS LIBRARY MANAGED BY FIANCEE ANNA
33
+ SCHINSKY. LAST RESIDENCE GERMANY BRLN LUETZOWSTRASSE 40
34
+ BEI HESS.
35
+
36
+ Document Number 888-906
37
+ for FOIA Review on JUL 1976
38
+
39
+ CONTINUED
40
+
41
+ COORDINATING OFFICERS
42
+ GROUP 1
43
+ Excluded from automatic
44
+ downgrading and
45
+ declassification
46
+ AUTHENTICAT
47
+ OFFICER
48
+
49
+ SECRET/RYB
50
+ REPRODUCTION BY OTHER THAN THE ISSUING OFFICE IS PROHIBITED.
51
+
52
+ 3. IN MAY 33 FLED TO FRANCE, WAS IN COPE 36-37 BUT EXPELLED
53
+ (OR LEFT) EDCAUSE HIS ANTI-DAHISK GOVT WAITINGS. LEFT DENMARK
54
+ FOR FRANCE VIA ICELAND. IN 40 IN SWEDEN, MARRIED MAY NILSSON,
55
+ CAME US VIA USSR IN 41 AND NATURALIZED CITIZEN SINCE 48
56
+
57
+ 4. WOULD APPRECIATE AS FULL A CHECK AS POSSIBLE, INCLUDING
58
+ LOCAL SERVICES AND AVAILABLE OVERT LOCAL PRE-WWL REFERENCES
59
+ (PRESS, BOOKS, ETC.) ON JOESTEN AND FIANCEE.
60
+
61
+ 5. FOR BAIN: PLS ALSO CHECK DDC AND REQUEST PHOTOSTATS
62
+ ANY DOCS, CAN ADDRESS AND NAME HESS BE CHECKED? ANY CHANCE
63
+ LOCATE FIANCEE?
64
+
65
+ 6. ALL ADDRESSERS PLS HANDLE AEQUEST URGENTLY AS MATTER
66
+ ALSO OF INTEREST TO WARREN COMMISSION. CABLE SUMMARY RESULTS
67
+ AND POUCH DETAILS INCLUDING ALL COPIES AVAILABLE JOESTEN PRE
68
+ WWI WRITINGS.
69
+
70
+ CONTINUED
71
+
72
+ SEGRET/RVRAT
73
+
74
+ MIC PARASI THROUGK 3 AECVI IN PUBLIC DOMAIN, AUS
75
+ FILE
76
+ END OF MESSAGE
77
+
78
+ C/EE/06
79
+ C/WE/L
80
+ CAVELS
81
+
82
+ SEGRET/RVRAT
space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/jfk_text/104-10006-10247.md ADDED
@@ -0,0 +1,145 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ 104-10006-10247
2
+ 2025 RELEASE UNDER THE PRESIDENT JOHN F. KENNEDY ASSASSINATION RECORDS ACT OF 1992
3
+ SECRET
4
+ FROM: (Requesters name)
5
+ BRANCH
6
+ ROOM
7
+ BADGE NO.
8
+ NAME CHECK AND CONSOLIDATION REQUEST
9
+ EXTENSION
10
+ DATE
11
+ RID CONTROL NO.
12
+ TO
13
+ TUBE
14
+ ROOM
15
+ DATE
16
+ INITIALS
17
+ RID/INDEX
18
+ DT-5
19
+ REQUESTER
20
+ RID/FILES
21
+ DT-6
22
+ REQUESTER
23
+ RID/ANALYSIS GT-7
24
+ RID/201
25
+ DW-6
26
+ RID/MIS
27
+ GT-6
28
+ RID/INDEX
29
+ DT-5
30
+
31
+ SUBJECT TO BE CHECKED
32
+ SURNAME
33
+ (All spellings)
34
+ D'EDKOV, Roman Fedorovich er Vilasa Nikolaevna
35
+ SPELLING VARIATIONS TO BE CHECKED
36
+ AKA, ALIASES
37
+ OTHER IDENTIFYING DATA (Occupation, sex, CP membership,
38
+ I. S. affiliations, etc.)
39
+ Poss. at soo. Eulest. Ind
40
+ RESIDENCE
41
+ New Delhi, Ind
42
+ SEX DATE OF BIRTH
43
+ PLACE OF BIRTH
44
+ CITIZENSHIP
45
+ USSR
46
+ Minse USSR
47
+
48
+ RESULTS OF RID/INDEX CHECK
49
+ COMMENTS
50
+ NO PERTINENT IDENTIFIABLE INFORMATION
51
+ CARD REFERENCES ATTACHED
52
+
53
+ INSTRUCTIONS FOR REQUESTERS
54
+ IN ALL CASES
55
+ 1. Use gummed label; type or print all
56
+ entries.
57
+ 2. Upon receipt of index card reproductions
58
+ draw a green diagonal line across the
59
+ items you do not want.
60
+ 3. Edit (use green) the reproduced index
61
+ cards to indicate:
62
+ (a) cards to be destroyed (mark with
63
+ green D and note reason for destruction)
64
+ Examples: document destroyed; duplicate
65
+ or less informative than retained in-
66
+ formation; information of no CS value.
67
+
68
+ (b) corrections and additions, inclu-
69
+ ding infinity symbol ∞ when card in-
70
+ cludes all facts contained in the
71
+ document.
72
+
73
+ Note 1. Records of COI, SSU, OSS and CIG
74
+ are in RID/ARD, and those that meet
75
+ indexing criteria in CSHB 70-1-l are
76
+ carded in the CS Main Index. If you
77
+ believe there could be additional in-
78
+ formation of value in these records,
79
+ you must request an Archives Index
80
+ search.
81
+ 201 CONSOLIDATION
82
+ 1. Return this form with the card repro-
83
+ ductions, also return pertinent documents,
84
+ aperture cards and the dossier if a 201 on
85
+ the subject exists.
86
+ 2. For each document to be included in the
87
+ consolidation (i.e., copy or cross reference
88
+ to be placed in the 201 file), green D the
89
+ corresponding card and check (a) or (b)
90
+ below:
91
+
92
+ (a) Consolidate into
93
+ 201-
94
+ (b) Open 201 file on subject.
95
+
96
+ RESTRICTION (If any)
97
+ CRYPTONYM
98
+ OTHER INTERESTED DESKS OR STATIONS
99
+ ASSIGNED
100
+ YES
101
+ NO
102
+ FILE TO
103
+ BE KEPT
104
+ RID
105
+ DESK
106
+ Note 2. Information concerning foreign
107
+ public personalities (except mili-
108
+ tary) may be available in BR/OCR
109
+ x7997.
110
+ DATE
111
+ SIGNATURE OF RECORDS OFFICER
112
+
113
+ 13-00000
114
+
115
+ One Roman Fedorovich DEDKOV, born 28 March 1927 in Ariansk, USSR,
116
+
117
+ and his wife Vilasa Nikolayevna DEDKOV, born 31 December 1930 in Minsk,
118
+ USSR, applied for were listed as applicants for entry visas to Indiad
119
+ sometime prior to April 1962. DEDKOV, who was issued Soviet passport
120
+ number 207461 on 17 September 1960, was scheduled to arrive in New Delhi
121
+ for two years as an English language teacher at the Soviet Embassy.
122
+
123
+ It is not known whether or not DEDKOV actually arrived in New Delhi.
124
+
125
+ Not at sent because it shows lioman to Indonians, aaring
126
+ "Home List" nut classified.
127
+ SCAT
128
+ 10 AUG 1964
129
+
130
+ 13-00000
131
+
132
+ INDIA 1
133
+
134
+ DEDKOV, Roman Fedorovich
135
+
136
+ Subj scheduled to arrive New Delhi for two years as an
137
+ English teacher at the Soviet Embassy; Ppt 207461 iss
138
+ 17 Sept 60 (Mos Comment: Subj is presumed to have arr
139
+ sometime after sept 60). NBDA-8509, 24 Apr 62
140
+
141
+ Wife: Vilasa Nikolayevna (DPOB: 31 Dec 1930; Minsk)
142
+
143
+ 201-756978
144
+
145
+ DPOB: 28 Mar 1927; Ariansk
space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/jfk_text/104-10007-10345.md ADDED
@@ -0,0 +1,326 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ 2025 RELEASE UNDER THE PRESIDENT JOHN F. KENNEDY ASSASSINATION RECORDS ACT OF 1992
2
+
3
+ ROUTING AND RECORD SHEET
4
+
5
+ SUBJECT: Document Number 988-927 BD
6
+
7
+ for FOIA Review on SEP 1976
8
+
9
+ FROM: Chief, CI/R&A
10
+ 2 C 17
11
+
12
+ TO: Chief, AF
13
+ 7 C 32
14
+
15
+ Chief, EE
16
+ 3 D 31 07
17
+
18
+ Chief, FE
19
+ 5 D 31 07
20
+
21
+ Chief, NE
22
+ 6 D 31 07
23
+
24
+ Chief, WE
25
+ 4 B 44 05
26
+
27
+ Chief, WH
28
+ 3 B 44 03
29
+
30
+ DDP
31
+ 3 C 20 16
32
+
33
+ CI/R&A
34
+ 2 C 17
35
+
36
+ PSD
37
+
38
+ RID
39
+
40
+ DATE 27-865
41
+ 24 December 1964
42
+
43
+ For Coordination
44
+
45
+ DEFERRED
46
+
47
+ RID PROUESTING STOPPED
48
+ PLEASE INDICATE HANDLING
49
+
50
+ NOTE: This Document of the CA R
51
+ of the CS Decur
52
+ Desired Handling
53
+ For Signature and Release
54
+ BY HAND
55
+ PLEASE CALL
56
+
57
+ Easy Printing 201-289248
58
+
59
+ DISPATCH
60
+
61
+ Chiefs of all Stations
62
+
63
+ Chief, KUDOVE
64
+
65
+ Warren Commission Testimony - Selected Excerpts
66
+
67
+ FYI
68
+
69
+ 1. The Warren Commission's Report on the assassination of
70
+ President Kennedy focused attention on the magnitude of the problem.
71
+ involved in the protection of the Chief Executive. As you know, it is
72
+ our responsibility, overseas and in headquarters, to render every
73
+ support possible to the Secret Service in the conduct of its statutory
74
+ responsibilities in the United States, and especially when the President
75
+ travels abroad,
76
+
77
+ 2. The circumstances confronting the Warren Commission
78
+ produced discussion and testimony on various aspects of the problem
79
+ of Presidential protection and on interagency operational cooperation,
80
+ which normally do not find their way into the public domain. These
81
+ include the acquisition and dissemination of information, consultation,
82
+ coordination, and operational interchanges. I believe you will be
83
+ interested in the attached extracts of testimony given before the Warren
84
+ Commission by U.S. intelligence and security officials. Pertinent
85
+ Fortions have been side lined. I commend these materials for reading
86
+ by all officers in positions of senior responsibility in headquarters and
87
+ overseas.
88
+
89
+ Document Number 988-927 BD.
90
+
91
+ for FOIA Review on SEP 1976
92
+
93
+ FLETCHER M. KNIGHT
94
+ 201-289245
95
+
96
+ Book Dispatch No. 4726
97
+
98
+ 100-300-12
99
+
100
+ Raymond G. Rocca gwh
101
+
102
+ HQ COPY
103
+ DISPATCH
104
+
105
+ Distribution For
106
+ Book Dispatch No. 4726
107
+
108
+ AF Division
109
+ Abidjan
110
+ Accra
111
+ Addis Ababa
112
+ Algiers
113
+ Bamako
114
+ Brazzaville
115
+ Bujumbura
116
+ Conakry
117
+ Dakar
118
+ Dar-es-Salaam
119
+ Freetown
120
+ Kampala
121
+ Khartoum
122
+ Lagos
123
+ Leopoldville
124
+ Lome
125
+ Lusaka
126
+ Mogadiscio
127
+ Monrovia
128
+ Nairobi
129
+ Pretoria
130
+ Rabat
131
+ Salisbury
132
+ Tananarive
133
+ Tripoli
134
+ Tunis
135
+ Yaounde
136
+
137
+ The above listing has been
138
+ reviewed in the AF Division.
139
+
140
+ dw
141
+
142
+ EE Division
143
+ Athens
144
+ Bern
145
+ Frankfurt
146
+ Nicosia
147
+ Vienna
148
+
149
+ The above listing has been
150
+ reviewed in the EE Division.
151
+
152
+ FE Division
153
+ Bangkok
154
+ Djakarta
155
+ Hong Kong
156
+ Honolulur
157
+ Kuala Lumpur
158
+ Manila
159
+ Melbourne
160
+ Okinawa
161
+ Phnom Penh
162
+ Rangoon
163
+ Saigon
164
+ Seoul
165
+ Taipei
166
+ Tokyo
167
+ Vientiane
168
+ Wellington
169
+
170
+ The above listing has been
171
+ reviewed in the FE Division.
172
+
173
+ себ
174
+
175
+ Distribution For
176
+ Book Dispatch No. 4726
177
+
178
+ NE Division
179
+ Aden
180
+ Amman
181
+ Ankara
182
+ Baghdad
183
+ Beirut
184
+ Cairo
185
+ Colombo
186
+ Damascus
187
+ Jidda
188
+ Kabul
189
+ Karachi
190
+ Kathmandu
191
+ Kuwait
192
+ New Delhi
193
+ Tehran
194
+
195
+ The above listing has been
196
+ reviewed in the NE Division.
197
+
198
+ WE Division
199
+ Brussels
200
+ Copenhagen
201
+ The Hague
202
+ Helsinki
203
+ Lisbon
204
+ London
205
+ Luxembourg
206
+ Madrid
207
+ Oslo
208
+ Ottawa
209
+ Paris
210
+ Paris/LCPIPIT
211
+ Reykjavik
212
+ Rome
213
+ Stockholm
214
+
215
+ The above listing has been
216
+ reviewed in the WE Division.
217
+
218
+ -2-
219
+
220
+ Distribution For
221
+ Book Dispatch No. 4726
222
+
223
+ WH Division
224
+ Asuncion
225
+ Bogota
226
+ Buenos Aires
227
+ Caracas
228
+ Georgetown
229
+ Guatemala City
230
+ Kingston
231
+ La Paz
232
+ Lima
233
+ Managua
234
+ Mexico City
235
+ Montevideo
236
+ Panama City
237
+ Paramaribo
238
+ Port-au-Prince
239
+ Port of Spain
240
+ Quito
241
+ Rio de Janeiro
242
+ San Jose
243
+ San Juan
244
+ San Salvador
245
+ Santiago
246
+ Santo Domingo
247
+ Tegucigalpa
248
+
249
+ The above listing has been
250
+ reviewed in the WH Division.
251
+
252
+ -3-
253
+
254
+ Headquarters Distribution for
255
+ Book Dispatch No. 4726
256
+
257
+ 2 DDP
258
+ 1 ADDP
259
+ 1 C/OPSER
260
+ 1 C/TSD
261
+ 1 C/CA
262
+ 1 C/CCS
263
+ 1 C/SOD
264
+ 1 C/CI
265
+ 1 C/FI
266
+
267
+ 2 C/AF
268
+ 1 C/AF/1
269
+ 1 C/AF/2
270
+ 1 C/AF/3
271
+ 1 C/AF/4
272
+ 1 C/AF/5
273
+ 1 C/AF/6
274
+
275
+ 2 C/EE
276
+ 1 C/EE/G
277
+ 1 C/EE/K
278
+ 1 C/EE/SA
279
+
280
+ 2 C/FE
281
+ 1 C/FE/CH
282
+ 1 C/FE/HULA
283
+ 1 C/FE/JKO
284
+ 1 C/FE/PMI
285
+ 1 C/FE/TBL
286
+ 1 C/FE/VNC
287
+
288
+ 2 C/NE
289
+ 1 C/NE/1
290
+ 1 DC/NE/AA
291
+ 1 C/NE/4
292
+ 1 C/NE/5
293
+ 1 C/NE/6
294
+
295
+ 2 C/WE
296
+ 1 C/WE/1
297
+ 1 C/WE/2
298
+ 1 C/WE/3
299
+ 1 C/WE/4
300
+ 1 C/WE/5
301
+ 1 C/WE/BC
302
+
303
+ 2 C/WH
304
+ 1 C/WH/1
305
+ 1 C/WH/2
306
+ 1 C/WH/3
307
+ 1 C/WH/4
308
+ 1 C/WH/5
309
+ 1 WH/COPS
310
+ 1 WH/POA
311
+ 1 WH/POB
312
+ 1 WH/Plans
313
+
314
+ 2 CI/R&A
315
+ 1 CI/LIA
316
+ 1 CI/OPS/AF
317
+ 1 CI/OPS/EE
318
+ 1 CI/OPS/FE
319
+ 1 CI/OPS/NE
320
+ 1 CI/OPS/SS
321
+ 1 CI/OPS/WE
322
+ 1 CI/OPS/WH
323
+
324
+ 1 RID
325
+
326
+ Originated by: Chief, CI/R&A, Ext. 7468/23 December 1964
space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/jfk_text/104-10009-10021.md ADDED
@@ -0,0 +1,192 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ 2025 RELEASE UNDER THE PRESIDENT JOHN F. KENNEDY ASSASSINATION RECORDS ACT OF 1992
2
+
3
+ SECRET
4
+
5
+ FIELD DISTRIBUTION - BD #5847
6
+
7
+ AF DIVISION
8
+ Johannesburg
9
+ Lagos
10
+ Nairobi
11
+ Pretoria
12
+ Rabat
13
+ Salisbury
14
+
15
+ EUR DIVISION
16
+ Barcelona
17
+ Berlin
18
+ Bern
19
+ Bonn
20
+ Brussels
21
+ Copenhagen
22
+ Geneva
23
+ The Hague
24
+ Hamburg
25
+ Helsinki
26
+ Lisbon
27
+ London
28
+ Madrid
29
+ Milan
30
+ Munich Liaison Base
31
+ Munich Ops. Base (Laurion)
32
+ Oslo
33
+ Ottawa
34
+ Paris
35
+ LCPIPIT
36
+ Rome
37
+ Salzburg
38
+ Stockholm
39
+ Vienna
40
+ Zurich
41
+
42
+ NB DIVISION
43
+ Ankara
44
+ Athens
45
+ Beirut
46
+ Calcutta
47
+ Colombo
48
+ Istanbul
49
+ New Delhi
50
+ Rawalpindi
51
+ Teheren
52
+
53
+ FE DIVISION
54
+ Bangkok
55
+ Djakarta
56
+ Hong Kong
57
+ Honolulu
58
+ Kuala Lumpur
59
+ Kuching
60
+ Manila
61
+ Medan
62
+ Melbourne
63
+ Okinawa
64
+ Rangoon
65
+ Saigon
66
+ Seoul
67
+ Singapore
68
+ Taipei
69
+ Tokyo
70
+ Vientiane
71
+ Surabaya
72
+ Wellington
73
+
74
+ WH DIVISION
75
+ Asuncion
76
+ Bogota
77
+ Brasilia
78
+ Buenos Aires
79
+ Caracas
80
+ Georgetown
81
+ Guatemala City
82
+ Guayaquil
83
+ JMWAVE
84
+ Kingston
85
+ La Paz
86
+ Lima
87
+ Managua
88
+ Mexico City
89
+ Monterrey
90
+ Montevideo
91
+ Norfolk (REPLANT)
92
+ Panama City
93
+ Port au Prince
94
+ Porto Alegre
95
+ Quito
96
+ Recife
97
+ Rio de Janerio
98
+ San Jose
99
+ San Salvador
100
+ Santiago
101
+ Santiago de los Caballeros
102
+ Santo Domingo
103
+ Sao Paulo
104
+ Tegucigalpa
105
+
106
+ SECRET
107
+
108
+ HQS DISTRIBUTION - BD #5847
109
+
110
+ CA STAFF
111
+ DC/CA
112
+ CA/COPS
113
+ CA/PROP
114
+ CA/LO
115
+ CA/B1
116
+ CA/B2
117
+ CA/B3
118
+ CA/B4
119
+ CA/B5
120
+
121
+ AF/COPS/CA
122
+ AF/1
123
+ AF/2
124
+ AF/3
125
+ AF/4
126
+ AF/5
127
+ AF/6
128
+
129
+ FE/CA 14
130
+ C/CO/CA
131
+
132
+ SB/CA
133
+
134
+ DO/CA 3
135
+
136
+ CI/R&A 10
137
+
138
+ EUR DIVISION
139
+ E/CA
140
+ E/SC
141
+ E/BNL
142
+ E/F
143
+ E/I
144
+ E/IB
145
+ E/G
146
+ E/AS
147
+ E/BC
148
+
149
+ NE DIVISION
150
+ NE/COPS
151
+ NE/GTI/G
152
+ NE/GTI/T
153
+ NE/GTI/I
154
+ NEAA/I
155
+ NEAA/AP
156
+ NEAA/S&L
157
+ NESA/RE
158
+ NESA/C&N
159
+ NESA/I
160
+ NESA/P
161
+
162
+ WH DIVISION
163
+ WH/CA
164
+ WH/C
165
+ WH/C/CA
166
+ WH/1
167
+ WH/1/Mexico
168
+ WH/2
169
+ WH/2/G
170
+ WH/2/P
171
+ WH/H/S
172
+ WH/2/CR/N
173
+ WH/3
174
+ WH/3/B
175
+ WH/3/CO
176
+ WH/3/E
177
+ WH/3/P
178
+ WH/3/V
179
+ WH/4
180
+ WH/4/AR
181
+ WH/4/CH
182
+ WH/4/P/U
183
+ WH/5
184
+ WH/5/Brasil
185
+ WH/6
186
+ WH/7
187
+ WH/7/HT
188
+ WH/7/GU
189
+ WH/7/DR
190
+ WH/7/JTS
191
+
192
+ SECRET
space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/jfk_text/104-10009-10222.md ADDED
@@ -0,0 +1,72 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ 104-10009-10222
2
+ 2025 RELEASE UNDER THE PRESIDENT JOHN F. KENNEDY ASSASSINATION RECORDS ACT OF 1992
3
+
4
+ SECRET
5
+
6
+ DD/P8:4635/1
7
+
8
+ 26 NOV 1968
9
+
10
+ Sir Charles C. F. Spry
11
+ Director General
12
+ Australian Security Intelligence Organization
13
+ G. P. O. Box 510583
14
+ Melbourne
15
+
16
+ Dear Charles,
17
+
18
+ Thank you for your letter of 15 October
19
+ recommending against the declassification of
20
+ Warren Commission document CD-971. I might
21
+ mention that our inquiry to you in August (1968)
22
+ was in anticipation of further pressure for the
23
+ release of Warren Commission papers, a pressure
24
+ which has not materialized. Accordingly, there is
25
+ not, at the present time, any intention to release
26
+ CD-971.
27
+
28
+ Should the question be raised at some future
29
+ time, the points made by you in your letter provide
30
+ every reason to keep the document out of the
31
+ public domain.
32
+
33
+ With kindest regards,
34
+
35
+ Sincerely,
36
+ /s/ Richard Helms
37
+
38
+ Richard Helms
39
+ Director
40
+
41
+ Document Number 1042-947c
42
+ for FOIA Review on SEP 1976
43
+
44
+ cc: DDCI
45
+
46
+ Signature Recommended:
47
+
48
+ Deputy Director for Plans
49
+ DDP/FE/PMI/AN/Amos Taylor, Jr. (X 5502):aib (25 November 1968)
50
+ 5681
51
+
52
+ Distribution:
53
+ Orig - Addee
54
+ 1 - ADDP 2 - DCI
55
+ 1 - CPE 1 - DDCI
56
+ 1 - PMI 2 - DDP
57
+ 1 - PMI/AN
58
+ 21 NOV 1968
59
+ Date
60
+
61
+ SECRET
62
+
63
+ CORRES
64
+ RELATING TO
65
+ THIS-
66
+ INCLUDING
67
+ NAVYS OK
68
+ OF 27 June
69
+
70
+ FILE
71
+ MAIN
72
+ FILE
space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/jfk_text/104-10012-10022.md ADDED
@@ -0,0 +1,102 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ 2025 RELEASE UNDER THE PRESIDENT JOHN F. KENNEDY ASSASSINATION RECORDS ACT OF 1992
2
+
3
+ SECRET
4
+
5
+ 21 MAY
6
+ 1982
7
+ US/82/71
8
+
9
+ Dear Anthony,
10
+
11
+ Regarding your letter 6/705 of 10 May 1982, our
12
+ records indicate that Valeriy Vladimirovich Kostikov
13
+ traveled to Mexico, France, Spain, the U.S. and Cuba
14
+ during the period 1959-61. In 1961, he was assigned
15
+ permanently to Mexico City as a consular officer and
16
+ served there until August 1965. He was variously
17
+ described as a translator, vice-consul, and attache.
18
+ During this tour he attempted to cultivate a U.S.
19
+ Government employee assigned to our embassy in Mexico
20
+ City.
21
+
22
+ In September/October 1963, Lee Harvey Oswald
23
+ approached the Soviet Embassy in Mexico City in an attempt
24
+ to get a visa allowing him to return to the USSR.
25
+ Kostikov, as a consular officer, handled this visa
26
+ request. We have no information which indicates any
27
+ relationship between these individuals other than for the
28
+ purpose of Oswald's making his visa request.
29
+
30
+ Kostikov returned to Mexico City for a second tour of
31
+ duty in July 1968. During this tour he was again assigned
32
+ to the consular section and was a second secretary. It
33
+ appeared that he was tasked with following the activities
34
+ of the Central American communist parties and left-wing
35
+ groups, and he met often with members of these groups,
36
+ reportedly providing them with funds and technical
37
+ guidance. In July/August 1969, Kostikov made an unusual
38
+ TDY trip to Moscow lasting three weeks. (His family
39
+ remained in Mexico.) In July 1970 he made a four-day trip
40
+ to Havana.
41
+
42
+ Kostikov's tour in Mexico ended unexpectedly in
43
+ September 1971. Our information indicated that he was
44
+ not due to leave for another three to four months, and at
45
+ the time of his departure, there was some speculation that
46
+ the suddenness of his departure was due to the fact that
47
+ he was known to Lyalin.
48
+
49
+ CROSS FILE COPY FOR
50
+ 201-289248
51
+ DO NOT DESTROY
52
+
53
+ RECORD COPY
54
+
55
+ SECRET
56
+
57
+ XAE09222
58
+ 21MAY 82
59
+ 100-2-95
60
+
61
+ While in Mexico he was considered by some to be the
62
+ most effective and dangerous of intelligence officers in
63
+ Mexico. He has been described as being without morals,
64
+ education, and manners. Shortly after his arrival in
65
+ Mexico in 1968, he was arrested in front of a house of
66
+ prostitution after becoming involved in a fist fight with
67
+ some locals. It appears this incident did not affect his
68
+ position in Mexico City, despite the fact that it
69
+ received a good deal of press coverage.
70
+
71
+ We are aware only that Kostikov arrived in Beirut in
72
+ June 1978. We are unable to confirm his presence there
73
+ now.
74
+
75
+ Although our file indicates that Kostikov may have
76
+ been a member of Department 13 (Executive Action)
77
+ (Department V's predecessor), we have been unable to
78
+ confirm this. Also, to the best of our knowledge the KGB
79
+ has not engaged in such executive action since 1959.
80
+
81
+ Sincerely,
82
+
83
+ /s/ David
84
+
85
+ David H. Blee
86
+
87
+ Mr. Anthony C. M. DeVere
88
+
89
+ PHOTO ATTACHED
90
+
91
+ DDO/CI/RA/Joan Paxson (21 May 1982)
92
+
93
+ DISTRIBUTION:
94
+ Orig & 1 - Adse
95
+ 1 - CI/RA Chrono
96
+ 1 - 100-2-95
97
+ 1 - Reading Board
98
+ 1 - Paxson
99
+
100
+ SECRET
101
+
102
+ 100-2-95
space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/jfk_text/104-10012-10024.md ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ 104-10012-10024 2025 RELEASE UNDER THE PRESIDENT JOHN F. KENNEDY ASSASSINATION RECORDS ACT OF 1992
2
+
3
+ 6/705
4
+ 10 May 1982
5
+
6
+ Dear David,
7
+
8
+ VALERIY VLADIMIROVICH KOSTIKOV
9
+
10
+ 1. Please refer to our conversation of 6 May. KOSTIKOV, born 17 March 1933, Moscow, was posted to Beirut in 1978 as 1st Secretary and may still be there. He is identified KGB and served in Mexico City from 1961-71. There is a reference to him on page 307 of BARRON's KGB which suggests that he may have been Department V. We do not appear to have asked LYALIN about him, and are now doing so.
11
+
12
+ 2. We also note that EPSTEIN in "Legend" claims that according to a CIA telecheck KOSTIKOV was Lee Harvey OSWALD'S KGB case officer in Mexico City. According to BARRON (page 335) OSWALD was in Mexico between September and November 1963 and was seeking to obtain a Soviet visa. There was certainly a KGB interest in OSWALD, although according to NOSENKO this was defensive.
13
+
14
+ 3. The reason for our current interest in KOSTIKOV will be obvious. As you are aware, our Embassy in Beirut, in common with other Western Missions, has been subject to threats and violence in recent months, and in view of earlier hostile attentions from the KGB, we have been reviewing our records of KGB staff in the area who might have been involved in promoting strong-arm tactics.
15
+
16
+ 4. We would be grateful for your views as to whether the KGB are likely to be behind any of the recent incidents (possibly through the Syrians) and for any information on KOSTIKOV and his activities in Mexico and in Beirut. In particular, what are your comments on the OSWALD story; can you confirm that KOSTIKOV is still in Beirut; is there anyone else in Beirut or Damascus whose trace record suggests an Active Measures role, or worse?
17
+
18
+ 5. We should be grateful for an early reply and as I said on 6 May will treat anything you can tell us on a strictly Service to Service basis.
19
+
20
+ CROSS FILE COPY FOR
21
+ 201-289248
22
+
23
+ DO NOT DESTROY
24
+
25
+ Yours ever
26
+
27
+ A C M de Vere
28
+
29
+ Form 547a Processed
space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/jfk_text/104-10012-10035.md ADDED
@@ -0,0 +1,208 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # 2025 RELEASE UNDER THE PRESIDENT JOHN F. KENNEDY ASSASSINATION RECORDS ACT OF 1992
2
+
3
+ 1 UNCLASSIFIED
4
+ INTERNAL USE ONLY
5
+ CONFIDENTIAL
6
+ SECRET
7
+
8
+ ROUTING AND RECORD SHEET
9
+
10
+ SUBJECT: (Optional)
11
+
12
+ FROM: E/BC
13
+ 4C 20 Hqs?
14
+
15
+ EXTENSION NO
16
+ 1413
17
+ 7220
18
+
19
+ DATE
20
+ 5 APR 1978
21
+
22
+ TO: (Officer designation, room number, and building)
23
+
24
+ DATE
25
+ OFFICER'S INITIALS
26
+ RECEIVED
27
+ FORWARDED
28
+ COMMENTS (Number each comment to show from whom to whom. Draw a line across column, after each comment.)
29
+
30
+ 1. CilRTA
31
+ 2. Hausman APR 1978 ch
32
+ 3. Rum Holmes
33
+ 4. 3D57
34
+ 5.
35
+ 6.
36
+ 7.
37
+ 8.
38
+ 9.
39
+ 10.
40
+ This is the ACTION/INFO copy of a communication received on from MI-6 in Washington.
41
+
42
+ Another copy is being held in E/BC.
43
+
44
+ Any reply should be directed to E/BC for forwarding to Liaison.
45
+
46
+ Processing by IP is to be determined by
47
+
48
+ Coordination with E/BC is required prior to any dissemination of this information outside the DDO.
49
+
50
+ NB: Richard A. SPRAGUE, Chief Counsel and Director of HSCA, saw a copy of attached document... See his attached letter to Sergyj CZORNONOH, 04 December 1976.
51
+
52
+ RBH
53
+ 11.
54
+ 12.
55
+ 13.
56
+ 14.
57
+ 15.
58
+
59
+ FORM 610 USE PREVIOUS EDITIONS
60
+ SECRET
61
+ CONFIDENTIAL
62
+ INTERNAL USE ONLY
63
+ UNCLASSIFIED
64
+
65
+ CONFIDENTIAL
66
+
67
+ Our ref: GEN 1
68
+
69
+ Dear Art,
70
+
71
+ 30 March 1978
72
+
73
+ Please find attached correspondence received from one Sergyj CZORNONOH who claims that he provided information about Lee Harvey OSWALD to the American Vice Consul (presumably Tom Blackshear) in Sofia, Bulgaria, in August 1963.
74
+
75
+ 2. I have sent copies of these letters to the FBI and to my Head Office in London.
76
+
77
+ Mr A H Stimson
78
+
79
+ Enc.
80
+
81
+ DH Jones for GML Blackburne-Kan
82
+
83
+ CONFIDENTIAL
84
+
85
+ SERGYJ. CZORNONOH
86
+ 1106-11TH STREET
87
+ SACRAMENTO CALIFORNIA
88
+ 95814
89
+
90
+ M. Wall
91
+
92
+ TO BRITISH EMBASSY
93
+ 3100 MASSACHUSETTS AVE, N. W.
94
+ WASHINGTON, D. C.
95
+
96
+ RETURN RECEIPT REQUESTED
97
+ REGISTERED NO.257254
98
+
99
+ SERGYJ CZORNONDH
100
+ 1106-11TH STREET
101
+ SACRAMENTO, CALIFORNIA, 95814
102
+
103
+ MARCH 15, 1978.
104
+
105
+ TO BRITISH AMBASSADOR
106
+ BRITISH EMBASSY
107
+ 3100 MASSACHUSETTS AVE, N. W.
108
+ WASHINGTON, DC.
109
+
110
+ DEAR SIR.
111
+
112
+ I WROTE LETTER ON FEBRUARY 15, 1978 TO MR. JAMES CALLAGHAN PRIME MINISTER I ENCLOSED REGISTERED MAIL NO. 251067.
113
+
114
+ ON JULY 18, 1963 I WAS IN LONDON ENGLAND AT THE AIRPORT IMMIGRATION OFFICER NO. 175 I HAD NO VISA IMMIGRATION PLACE ME UNDER HOUSE ARREST, MR. SMITH IN POLICE UNIFORM SECRET SERVICE BROUGHT ME STEAK DINNER AND POLICE OFFICER INTERROGATED ME, HE ASKED ME WHAT THE EMBASSY OF US.S.R. SAY YOU HEARD IN VIENNA, AUSTRIA, I SAID I HAVE HEARD THAT ONE AMERICAN DEFECTOR (MR. LEE HARVEY OSWALD) TO RUSSIA AND HE RETURNED TO UNITED STATES OF AMERICA THIS MAN HE PREPARING TO KILL TO ASSASSINATE PRESIDENT JOHN F. KENNEDY, MR. SMITH POLICE OFFICER ASKED ME DO YOU KNOW HIS NAME, I SAID HIS NAME SOHT ONTO TIME WAS PUBLISHED ONE TIME IN NEWS PAPER IN WASHINGTON POST, MR. SMITH POLICE OFFICER SAID
115
+
116
+ I DO SEARCHING FOR THIS FILE IN BRITISH POLICE BRITISH INTELLIGENCE AND BRA IMMIGRATION, JASKING YOUR EMBASSY TO HELP TO FIND THE TRUTH AND I ASK YOUR GOVERNMENT TO FORWARD My RECORD CE JULY 181 1963 TO PRESIDENT JIMMY CARTER AND SENATOR DANIEL K. NOUYE CHAM 21. S. SENATE SELECT COMMITTEE ON IN 11 GENCE I ENCLOSE HIS Copy LETTER TO ALSO I ENCLOSE you copy LETTER I JANT ON FEBRUARY 17, 1978 TO RUSSIAN AMMASSA YOUR JUSTICE ALWAYS WILL BE APPLIA MY INCOMING MAIL iS CONTROL BY FIBI AGENTS SOME OF THE MAIL IDENT GET NOT FORWARD TO ME FIBI, Suppress My INFORMATION AND TORTURE MED DRUG RESPECTFULLY YOURS "21.S. PASSPORT NO, DO 2.7000 Sergyj
117
+
118
+ copy. 10
119
+ BRITISH AMBASSADOR
120
+
121
+ Sergyj Czornonoh
122
+ 1106- 11th Street
123
+ Sacramento, California 95814
124
+
125
+ To Russian Ambassador
126
+ Embassy of U.S.S.R.
127
+ 1125 - 16th Street
128
+ Washington, D. C.
129
+
130
+ Dear Sir:
131
+
132
+ This is retyped letter from hand written
133
+
134
+ Mr. Wasilev Consul gave me order to transmit this information to U. S. Government, on August 9, 1963 in Sofia, Bulgaria. Mr. Wasilev, Consul of Embassy of U.S.S.R., gave me this information about Mr. Lee Harvey Oswald on August 14, 1963. Mrs. Besera Asenova, girl friend of Russian Consul came to my room and repeated that Mr. Lee Harvey Oswald is assassin. He will kill President Kennedy.
135
+
136
+ On August 15, 1963 in Sofia, Bulgaria, at the airport in embassy car, I told to Mr. Blackshire, American Vice Consul, that Mr. Lee Harvey Oswald is assissin. He has a weapon or has ordered one. Mr. Blackshire said it seems like he will kill someone. I said that Mr. Lee H. Oswald is preparing to kill President of the United States, John F. Kennedy. Mr. Blackshire said where will it happen. I said they (right wing) will invite President, criticize him in the newspaper, then kill him. Mr. Blackshire told me he will give the telegram to Department of State and he gave me the address where to report.
137
+
138
+ At 9 a.m. on August 19, 1963 in Washington, D. C., I went to see (Mr. Kippingan). Director of Special Counselor Service Department of State at 1901 Pennsylvania Avenue-11th floor. I told the Director that I have information about President Kennedy. The Director said do not mention name of President Kennedy, only respond to the questions. The Director said tell us what will happen to Mr. Lee Harvey Oswald then. I said Mr. Lee H. Oswald will be killed after kill Kennedy. I said I will take the truth drug to tell the truth. Director tell us who else get killed in this country. I said as I heard, that Dr. Martin Luther King, Jr. will be killed. Who will kill Dr. King, Jr. Negro leader? I said a man who is in prison at this time. (Mr. James Earl Ray was in prison at that time.) Director asked where assassination will happen. I said in Dallas, Texas. Director said if someone gave this information here I would expel the man. Director did call on F.B.I. agents after F.B.I. use anesthesia gas to freeze me to drub me to keep amnesia.
139
+
140
+ I told Director Department of State that Mr. Lee Harvey Oswald have a weapon. Go see him. Director told me you too can have weapon--so what if Oswald got weapon.
141
+
142
+ Sincerely,
143
+
144
+ U.S House of Representatives Select Committee on Assassinations told me to write letter to Embassy in early 1977.
145
+
146
+ Sergyj Czornonoh
147
+ Regis Hotel
148
+ 1106 11th Street
149
+ Sacramento, CA 95814
150
+
151
+ GITY MANAGEAS
152
+ ABOUT HUMAN RIGHTS
153
+ BRITISH EMBASSY
154
+
155
+ February 6, 1978
156
+
157
+ Mr. John M. Price
158
+ District Attorney
159
+ Sacramento, California
160
+
161
+ Dear Mr. Price:
162
+
163
+ This is a retyped letter. I visited Mr. Ferry, Deputy District Attorney, on August 16, 1977. I told in the office that F.B.I. agents and Secret Service use police department to harass me. Police department do... supply pencil of anesthesia gas to the manager of the building I live. The manager door use certain people, to freeze me by anesthesia gas - then push drugs, poison in my mouth to torture me - to take my sleep away - or bleed by rectal and they use many other chemicals to brainwash me to use me in political assassination which I refused. On January 20, 1976 in Sacramento on 8th and I Streets, man came to me from police or post office, U.S. Department of Justice and freeze me by gas and told me to take gun, pistol and we will tell you where to go to shoot - to kill - Mr. Sargent Shriver. I refused. Manager, Mr. Sisel, of Marshall Hotel, call on the man to tell me this on the street. In February 1976, police intelligence told me that assassination will not happen here. How about to move to Maryland state.
164
+
165
+ In this letter I ask you to get report from Dr. Frederick S. Baker, M.D. colon and rectal surgery on January 31, 1978. His phone – 452-4095. I do bleed today very much and I am weak, In this letter I ask you to give re- strain order or respond to me what could be done. The right wing in America made record to use me in assassination. I refuse. I am human and I like to be treated as human. Police put frame up on me - just to take advantages on me. Police use lie, police use mental case to take advantages on me and tell me that right wing do use such people like me. To prove I enclose copy mid- night June 14, 1976. Also I enclose copy letter I sent to Mr. Ted Sheedy, Supervisor, on January 26, 1978 and copy of his reply to me.
166
+
167
+ Please respond to me. Thank you.
168
+
169
+ Very truly yours
170
+
171
+ Sergyj. Czornonoh
172
+
173
+ Mr. Sargent Shriver was run for President in 1976.
174
+
175
+ Legal Center
176
+ For The Disabled
177
+
178
+ 1722 J STREET, SUITE 19 SACRAMENTO, CA 95814
179
+ Telephone: 446-4851
180
+
181
+ March, 1978
182
+
183
+ Sergyj Czornonoh
184
+ 1106 11th Street
185
+ Sacramento, CA 95814
186
+
187
+ Dear Mr. Czornonoh:
188
+
189
+ This is to acknowledge receipt of your letter regarding difficulties you have encountered with the police and the FBI.
190
+
191
+ In the event that there is legal action taken by the police or the FBI to institutionalize you this office will provide you with legal representation.
192
+
193
+ If you have any further legal problems please contact this office.
194
+
195
+ Sincerely,
196
+
197
+ LESLIE KAY
198
+ Paralegal
199
+
200
+ CATHERINE HUGHES
201
+ Staff Attorney
202
+ LK: ab
203
+
204
+ REGISTERED NO 2.51067
205
+ FROM 1106801124 95814
206
+ TO MR. JAMES CALLAGHAN
207
+ SF Wen la OFFICE OF MINISTRY
208
+ LONDON ENGLAND
space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/jfk_text/104-10012-10076.md ADDED
@@ -0,0 +1,180 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ 13-00000
2
+
3
+ FIELD DISTRIBUTION
4
+
5
+ A Division
6
+ WH Division
7
+ NE Division
8
+ DISTRIBUTION TO BD -
9
+ r
10
+ Abidjan
11
+ Asuncion
12
+ Amman
13
+ Accra
14
+ Fagota
15
+ Ankara 2
16
+ Addis Ababa
17
+ Erasilia
18
+ Athens 5
19
+ Апиете
20
+ Fenos Aires
21
+ Beirut 3
22
+ Bangal
23
+ Cazucas 2
24
+ Bombay
25
+ toncu
26
+ Georgetown
27
+ Calcutta
28
+ Dakar
29
+ Guatemala
30
+ Colombo
31
+ Ier at Salava
32
+ Quayaquil
33
+ Dacca
34
+ Kaipals
35
+ Kingstoc
36
+ Istanbul
37
+ Freetown
38
+ La Paz
39
+ Jerusalem
40
+ Khartoum
41
+ Lima
42
+ Jidda
43
+ Kiastasa
44
+ Keduaa
45
+ Mexico City 2
46
+ Kabul
47
+ Mutevideo
48
+ Karachi
49
+ Lagos
50
+ Рапяка
51
+ Katmandu
52
+ Lusaka
53
+ Forte Alegre
54
+ Kirwait
55
+ Mogadiscio
56
+ Av Spain
57
+ Lahore
58
+ Moarovia
59
+ Madras
60
+ CI/ICG
61
+ Nairobi
62
+ Recife
63
+ New Delhi
64
+ Rabat
65
+ Rio de Janeiro 2
66
+ Nicosia
67
+ Tripoli
68
+ San Jose
69
+ Rawalpindi
70
+ Yamade
71
+ Sau Salvador
72
+ Teheran
73
+ Santiago 2
74
+
75
+ Sento Domiαει
76
+ EUR Division
77
+ Ses Paulc
78
+ Berlin 3
79
+ Tegucigalpa
80
+ Bern
81
+ Madrid 2
82
+ Bona 5
83
+ Preseis
84
+ Copenhagen
85
+ Frankfurt
86
+ FE Divisi
87
+
88
+ Do agirak 3
89
+ karta
90
+ 3
91
+ AF/2
92
+ Heleinkta
93
+ 2
94
+ 4
95
+ karta 2
96
+ Matid
97
+ 2
98
+ TALA Lumpur
99
+ Munich betria) 3
100
+ Mars la
101
+ 2
102
+ Me ibaurtu
103
+ Peru
104
+ kizawa
105
+ Pame
106
+ 2
107
+ כם
108
+ stockholm
109
+ Sat 2
110
+ Sen
111
+ ogue 2
112
+ Singapora
113
+ Vine
114
+ Suracaye
115
+ Zurich
116
+ Taipei 2
117
+ Tokyo
118
+ 2
119
+ Vientians
120
+ Wellington
121
+ BD 6614?
122
+ SB/Division
123
+ C/SB
124
+ SB/CA
125
+ SB/BR
126
+ SB/C
127
+ SB/YA
128
+ SB/P
129
+ SB/CI
130
+
131
+ WH/C/CA/PROP 2
132
+ WH/CA
133
+
134
+ WH/1,2,3,4,5
135
+ WH/7/JTS, CU
136
+
137
+ 1-D/RR
138
+ 2-DOCA
139
+ CI/FA
140
+
141
+ FBID/Weisa
142
+ VTR/SIC
143
+ OTR/Isolation Library
144
+ FL/8PG
145
+ MPS/PSC
146
+
147
+ CS Special Group Offic
148
+ INTERNAL DISTRIBUTION
149
+ AP/COP/CA
150
+ AP/1
151
+ C/CA - DC/CA
152
+ C/CA/PEG
153
+ AP/L
154
+ CA/EL 3
155
+ AF/5
156
+ 08/53 3
157
+ CA/DA
158
+ AF/6-Ethiopia
159
+ 40/80
160
+ C/EUR
161
+ E/ONE/CA
162
+ CA/FROF
163
+ E/G
164
+ 8/A8
165
+ B/SC
166
+ E/BNE
167
+ E/BC
168
+ E/F
169
+ ق
170
+ 1/2
171
+ E/LB
172
+
173
+ FE/CA 16
174
+
175
+
176
+ NE/SA/A
177
+ NE/GTA!!
178
+ NE/GES T
179
+ NF 'COPS
180
+ NEGA/I
space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/jfk_text/104-10012-10078.md ADDED
@@ -0,0 +1,199 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ 2025 RELEASE UNDER THE PRESIDENT JOHN F. KENNEDY ASSASSINATION RECORDS ACT OF 1992
2
+ 104-10012-10078
3
+ QUNCLASSIFIED
4
+ ONLY
5
+ ROUTING AND RECORD SHEET
6
+ ENTIAL
7
+ SECRET
8
+ SUBJECT: (Optional)
9
+ FROM:
10
+ Chief Far East Division
11
+ TO: (Officerdesignation, room number, and.
12
+ building)
13
+ EXTENSION NO.
14
+ FORWARDED
15
+ OFFICER'S
16
+ INITIALS:
17
+ DATE
18
+ 20 Nov.68
19
+ COMMENTS (Number each comment to show from whom
20
+ to whom. Draw a line across column after each comment.)
21
+ DATE
22
+ RECEIVED
23
+ Chief CI Staff 27 NOV 1968
24
+ CIRA
25
+ Mr. Dooley
26
+ 27 NOV 1968
27
+ boo
28
+ for file
29
+ Document Number
30
+ येद
31
+ 1128-988
32
+ for FOIA Review on SEP 1976
33
+ 201-289248
34
+ FORM
35
+ 3-62
36
+ 610
37
+ USE PREVIOUS
38
+ EDITIONS
39
+ SECRET
40
+ CONFIDENTIAL
41
+ INTERNAL
42
+ USE ONLY
43
+ UNCLASSIFIED
44
+
45
+ UNCLASSIFIEDERAL CO DENTIAL
46
+ SUBJECT: (Optional)
47
+ FROM: CIRAIRS
48
+ 2323
49
+ TO: (Officer designation, room number, and
50
+ building)
51
+ 1.
52
+ IP/AN
53
+ 2.
54
+ 3.
55
+ 4.
56
+ 5.
57
+ JP/EDI
58
+ 6.
59
+ 7.
60
+ 8.
61
+ 9.
62
+ 10.
63
+ Document Number
64
+ for FOIA Review on
65
+ 28/Flas
66
+ HP/RMS
67
+ 12.
68
+ 13.
69
+ ONLY
70
+ ROUTING AND RECORD SHEET
71
+ EXTENSION NO.
72
+ DATE
73
+ OFFICER'S
74
+ INITIALS
75
+ RECEIVED
76
+ FORWARDED
77
+ DATE
78
+ 26 που. 68
79
+ XAAZ-35926
80
+ 26 NOU 68-
81
+ SECRET
82
+ COMMENTS (Number each comment to show from whom
83
+ to whom. Draw a line across column after each comment.)
84
+ @ Please asijo
85
+ XAAZ # and
86
+ os pay & Of
87
+ 1128-988
88
+ SEP 1976
89
+ MAY
90
+ 1978
91
+ clamifs to
92
+ 201-289748
93
+ 26.
94
+ Date: 2 NOV 68)
95
+ Salgent
96
+ Covesperelerce Cotisan
97
+ 0%
98
+ CIA and ASIO.
99
+ Re: release
100
+ of exftinatun ly
101
+ Woven Commessen
102
+ 14.
103
+ 15.
104
+ FORM
105
+ 3-62
106
+ D
107
+ 610
108
+ USE PREVIOUS
109
+ EDITIONS
110
+ SECRET
111
+ CONFIDENTIAL
112
+ INTERNAL
113
+ USE ONLY
114
+ UNCLASSIFIED
115
+
116
+ SECRET
117
+ 20 NOV 1968
118
+ KEMORANDUM FOR: Director of Central Intelligence
119
+ VIA
120
+ SUBJECT
121
+ Deputy Director for Plane
122
+ 304635
123
+ Executive Registry
124
+ 68-516011
125
+ XAAZ-
126
+ 35926
127
+ Letter for Direstor from Bir Charles Spry (ASIO)
128
+ 1. Attached is a scaled letter fron Sir Charles Spry,
129
+ Director General of the Australian Security Intelligenco
130
+ Organization (who provided a copy of the letter to the Chief
131
+ of Station, Heibourne), and a suggested reply for your
132
+ signature.
133
+ 2. Bir Charles' letter to you recommends again好家
134
+ doclassification of the Farrea Comaission document CD-971,
135
+ which refers to our investigation of anonymous telephone
136
+ calls to the Canberra Babassy before and after the
137
+ amcassination of President Kennedy.
138
+ 3. I consider the points made by Bir Charles in his
139
+ letter to be valid and accordingly recommend against the
140
+ decisosification of CD-971 in the foreseeable fature
141
+ Staff concurs with this recommendation.
142
+ Document Number 1128-988
143
+ for FOLA Review on SEP 1976
144
+ 4. Naison
145
+ William E. Nelson
146
+ of
147
+ K
148
+ P/ERI
149
+ Chief, Far East Division
150
+ Attachments, 5
151
+ 130/900
152
+ A.
153
+ Letter from Sir Charles Spry
154
+ PROCARE FOR THAUNG
155
+ 575 40. (2.3.4)
156
+ AVGAT REST, CODE
157
+ CABLE ICON (11)
158
+ (4)
159
+ B.
160
+ Letter Replying to Sir Charles Spry
161
+ P/FRES
162
+ FOR FILING
163
+ C. FAMA 5008, subject: Declassification of Warreh
164
+ Commission Document CD-971-
165
+ D.
166
+ Copy of CD-971
167
+ E. FAMW 3636, subject: Request for Release of Warren
168
+ Commission Document
169
+ 20: DOCI
170
+ DDP/FE/PMI/AN: Amos Taylor, Jrl:arc (19) November 1968)
171
+ Distribution
172
+ Orig & 1
173
+ -
174
+ Addressee
175
+ 1 DDCI
176
+ -
177
+ 2
178
+ -
179
+ 1
180
+ DDP
181
+ ADDP
182
+ RECORD COPY
183
+ -
184
+ 1
185
+ 1
186
+ 1
187
+ -
188
+ 1
189
+ -
190
+ GEODET
191
+ C/CI Staff
192
+ CFE
193
+ CFE/PMI
194
+ wanatic
195
+ ...and
196
+ neslassification
197
+ CFE/PMI/AN
198
+ 26 που 68
199
+ 201-289248
space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/jfk_text/104-10012-10079.md ADDED
@@ -0,0 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ 2025 RELEASE UNDER THE PRESIDENT JOHN F. KENNEDY ASSASSINATION RECORDS ACT OF 1992
2
+
3
+ SECRET
4
+
5
+ 68-2/60/a
6
+ RD/08-4635/
7
+
8
+ 26 NOV 1968
9
+
10
+ FILE
11
+
12
+ Sir Charles C. F. Spry
13
+ Director General
14
+ Australian Security Intelligence Organization
15
+ G. P. O. Box 51058B
16
+ Melbourne
17
+
18
+ Dear Charles,
19
+
20
+ Thank you for your letter of 15 October
21
+ recommending against the declassification of
22
+ Warren Commission document CD-071. I might
23
+ mention that our inquiry to you in August (1968)
24
+ was in anticipation of further pressure for the
25
+ release of Warren Commission papers, a pressure
26
+ which has not materialized. Accordingly, there is
27
+ not, at the present time, any intention to release
28
+ CD-971.
29
+
30
+ Should the question be raised at some future
31
+ time, the points made by you in your letter provide
32
+ every reason to keep the document out of the
33
+ public domain.
34
+
35
+ With kindest regards,
36
+
37
+ Sincerely,
38
+
39
+ /s/ Richard Helms
40
+
41
+ Richard Helms
42
+ Director
43
+
44
+ cc: DDCI
45
+
46
+ Signature Recommended:
47
+
48
+ Deputy Director for Plans
49
+
50
+ Distribution:
51
+ Orig - Addee
52
+ 1 - ADDP 2 - DCI
53
+ 1 - CFE 1 - DDCI
54
+ 1 - PMI 2 - DDP
55
+ 1 - PMI/AN
56
+
57
+ Date
58
+
59
+ DDP/FE/PMI/AN/Amos Taylor, Jr. (X 5502):aib (25 November 1968)
60
+
61
+ 201-289248
space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/jfk_text/104-10014-10051.md ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ 2025 RELEASE UNDER THE PRESIDENT JOHN F. KENNEDY ASSASSINATION RECORDS ACT OF 1992
2
+
3
+ SECRET
4
+ IMS(FABOSS)
5
+
6
+ SECRET
7
+ FRP: ,2,
8
+
9
+ STAFF
10
+
11
+ ACTION: C/EUR/NOR (729) INFO: EUDORECORD, EUR/LGL, MDSX, ODPD RYBAT.(FILE,
12
+
13
+ OC/EURN, CIC/EUR (3/W)
14
+
15
+ 96 3123036 ASO PAGE 001 IN 3123036
16
+ TOR: 081248Z FEB 96 (COPB 94608
17
+ SECRET 081247Z FEB 96 STAFF 19-6
18
+ CITE:(COPENHAGEN)94608
19
+
20
+ TO: IMMEDIATE DIRECTOR.
21
+
22
+ FOR: LIMIT EUR/(NOR) INFO DC/EURN) CIC (EU, EUR/LGL)
23
+
24
+ SLUGS: WNINTEL RYBAT
25
+
26
+ SUBJECT: RELEASE OF CLASSIFIED DOCUMENT
27
+
28
+ REF: DIRECTOR 633349 96 3117723
29
+
30
+ TEXT:
31
+
32
+ 1. ACTION REQUIRED: SEE PARA 2.
33
+
34
+ 2. THE FAX (STATION) RECEIVED APPEARS TO BE INCOMPLETE. IT
35
+ CONTAINED A COVER SHEET, A ONE-PAGE COPENHAGEN) CABLE STATING "NO
36
+ TRACES" AND THE FIRST PAGE OF A DIRECTOR CABLE REQUESTING TRACES ON
37
+ LEE HARVEY ((OSWALD)). UNLESS THE MISSING PORTIONS OF THE DIRECTOR
38
+ CABLE HAVE SOME BEARING ON (DENMARK, STATION) CANNOT MAKE A CASE
39
+ AGAINST RELEASE OF THIS MATERIAL WE WOULD INSIST, HOWEVER, THAT
40
+ CRYPTS BE DELETED - AS REF INDICATED WOULD BE THE CASE.
41
+
42
+ 3. PLEASE KEEP US APPRISED OF DATE THESE DOCS WILL BE RELEASED
43
+ SO THAT (STATION) MAY INFORM AMBASSADOR AND OUR LIAISON SERVICE
44
+ CHIEFS.
45
+
46
+ 4. CL BY: 0716497 CL REASON: 1.5(C) DECL ON: X1
47
+
48
+ 4....FILE: 021-120-004/1. DECL DRV. HUM 4-82.
49
+
50
+ END OF MESSAGE SECRET
51
+
52
+ SECRET
53
+
54
+ DO NOT DESTROY
55
+ CROSS FILE COPY FOR:
56
+ 201-0289248