Auto-deploy from GitHub
Browse filesThis view is limited to 50 files because it contains too many changes.
See raw diff
- app.py +117 -48
- space/app.py +117 -48
- space/space/app.py +117 -48
- space/space/space/app.py +117 -48
- space/space/space/space/app.py +117 -48
- space/space/space/space/space/app.py +117 -48
- space/space/space/space/space/space/app.py +117 -48
- space/space/space/space/space/space/space/app.py +117 -48
- space/space/space/space/space/space/space/space/app.py +117 -48
- space/space/space/space/space/space/space/space/space/app.py +117 -48
- space/space/space/space/space/space/space/space/space/space/app.py +117 -48
- space/space/space/space/space/space/space/space/space/space/space/app.py +117 -48
- space/space/space/space/space/space/space/space/space/space/space/space/app.py +117 -48
- space/space/space/space/space/space/space/space/space/space/space/space/space/app.py +117 -48
- space/space/space/space/space/space/space/space/space/space/space/space/space/space/app.py +117 -48
- space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/app.py +117 -48
- space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/app.py +117 -48
- space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/app.py +117 -48
- space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/app.py +117 -48
- space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/app.py +117 -48
- space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/app.py +117 -48
- space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/app.py +117 -48
- space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/app.py +117 -48
- 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 +117 -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/app.py +117 -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/app.py +117 -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/app.py +117 -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/app.py +117 -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/app.py +117 -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/app.py +117 -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/jfk_text/104-10003-10041.md +47 -0
- space/space/space/space/space/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
- space/space/space/space/space/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
- space/space/space/space/space/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
- space/space/space/space/space/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
- space/space/space/space/space/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
- space/space/space/space/space/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
- space/space/space/space/space/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
- space/space/space/space/space/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
- space/space/space/space/space/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
- space/space/space/space/space/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
- space/space/space/space/space/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
- space/space/space/space/space/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
- space/space/space/space/space/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
- space/space/space/space/space/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
- space/space/space/space/space/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
- space/space/space/space/space/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
- space/space/space/space/space/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-10064.md +149 -0
- space/space/space/space/space/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-10016-10021.md +74 -0
- space/space/space/space/space/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-10023-10087.md +907 -0
app.py
CHANGED
@@ -38,7 +38,7 @@ def wrap_label(label, max_length=15):
|
|
38 |
|
39 |
return "\\n".join(lines)
|
40 |
def generate_high_res_mindmap(text):
|
41 |
-
"""Generate mind map
|
42 |
try:
|
43 |
# Verify we have entities to visualize
|
44 |
entities = extract_entities(text)
|
@@ -46,92 +46,145 @@ def generate_high_res_mindmap(text):
|
|
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 |
-
#
|
55 |
G = pgv.AGraph(
|
56 |
directed=True,
|
57 |
-
rankdir="TB",
|
58 |
bgcolor="white",
|
59 |
-
fontname="
|
60 |
-
splines="ortho"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
61 |
)
|
62 |
|
63 |
-
#
|
64 |
G.node_attr.update({
|
65 |
-
"fontsize": "
|
|
|
66 |
"shape": "box",
|
67 |
"style": "rounded,filled",
|
68 |
"fillcolor": "#E1F5FE",
|
69 |
"color": "#0288D1",
|
|
|
|
|
|
|
|
|
70 |
})
|
71 |
|
72 |
-
#
|
73 |
G.edge_attr.update({
|
74 |
-
"color": "#
|
75 |
-
"penwidth": "
|
|
|
|
|
|
|
|
|
76 |
})
|
77 |
|
78 |
-
# Add central node
|
79 |
-
G.add_node("DOCUMENT",
|
80 |
-
|
81 |
-
|
82 |
-
|
|
|
|
|
|
|
83 |
|
84 |
-
# Add entities with
|
85 |
max_categories = 5
|
86 |
-
max_entities =
|
87 |
|
88 |
for cat_idx, (category, values) in enumerate(entities.items()):
|
89 |
if cat_idx >= max_categories:
|
90 |
break
|
91 |
|
|
|
92 |
cat_node = f"CAT_{cat_idx}"
|
93 |
-
G.add_node(cat_node,
|
94 |
-
|
|
|
|
|
|
|
95 |
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
G.add_edge(cat_node, ent_node)
|
100 |
|
101 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
102 |
for engine in ['dot', 'neato', 'sfdp']:
|
103 |
try:
|
104 |
-
G.draw(output_path,
|
105 |
-
|
106 |
-
|
|
|
107 |
print(f"Successfully generated with {engine}")
|
108 |
-
|
|
|
|
|
|
|
|
|
109 |
except Exception as e:
|
110 |
print(f"Layout engine {engine} failed: {str(e)}")
|
111 |
continue
|
112 |
-
else:
|
113 |
-
raise RuntimeError("All layout engines failed")
|
114 |
|
115 |
-
|
116 |
-
if not os.path.exists(output_path):
|
117 |
-
raise FileNotFoundError("Mind map file was not generated")
|
118 |
-
|
119 |
-
return output_path
|
120 |
|
121 |
except Exception as e:
|
122 |
print(f"Mind map generation failed: {str(e)}")
|
123 |
-
#
|
124 |
-
|
125 |
-
if not os.path.exists(placeholder_path):
|
126 |
-
# Create simple placeholder
|
127 |
import matplotlib.pyplot as plt
|
128 |
-
|
129 |
-
|
130 |
-
|
|
|
131 |
plt.axis('off')
|
132 |
-
|
|
|
133 |
plt.close()
|
134 |
-
|
|
|
|
|
135 |
@app.post("/summarize")
|
136 |
def summarize_text(request: TextRequest):
|
137 |
chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
|
@@ -252,11 +305,27 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
|
|
252 |
return None
|
253 |
|
254 |
mindmap_btn.click(
|
255 |
-
|
256 |
-
|
257 |
-
|
|
|
|
|
258 |
)
|
259 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
260 |
if __name__ == "__main__":
|
261 |
iface.launch(
|
262 |
server_name="0.0.0.0",
|
|
|
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)
|
|
|
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="300", # 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)]
|
|
|
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(
|
331 |
server_name="0.0.0.0",
|
space/app.py
CHANGED
@@ -38,7 +38,7 @@ def wrap_label(label, max_length=15):
|
|
38 |
|
39 |
return "\\n".join(lines)
|
40 |
def generate_high_res_mindmap(text):
|
41 |
-
"""Generate mind map
|
42 |
try:
|
43 |
# Verify we have entities to visualize
|
44 |
entities = extract_entities(text)
|
@@ -46,92 +46,145 @@ def generate_high_res_mindmap(text):
|
|
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 |
-
#
|
55 |
G = pgv.AGraph(
|
56 |
directed=True,
|
57 |
-
rankdir="TB",
|
58 |
bgcolor="white",
|
59 |
-
fontname="
|
60 |
-
splines="ortho"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
61 |
)
|
62 |
|
63 |
-
#
|
64 |
G.node_attr.update({
|
65 |
-
"fontsize": "
|
|
|
66 |
"shape": "box",
|
67 |
"style": "rounded,filled",
|
68 |
"fillcolor": "#E1F5FE",
|
69 |
"color": "#0288D1",
|
|
|
|
|
|
|
|
|
70 |
})
|
71 |
|
72 |
-
#
|
73 |
G.edge_attr.update({
|
74 |
-
"color": "#
|
75 |
-
"penwidth": "
|
|
|
|
|
|
|
|
|
76 |
})
|
77 |
|
78 |
-
# Add central node
|
79 |
-
G.add_node("DOCUMENT",
|
80 |
-
|
81 |
-
|
82 |
-
|
|
|
|
|
|
|
83 |
|
84 |
-
# Add entities with
|
85 |
max_categories = 5
|
86 |
-
max_entities =
|
87 |
|
88 |
for cat_idx, (category, values) in enumerate(entities.items()):
|
89 |
if cat_idx >= max_categories:
|
90 |
break
|
91 |
|
|
|
92 |
cat_node = f"CAT_{cat_idx}"
|
93 |
-
G.add_node(cat_node,
|
94 |
-
|
|
|
|
|
|
|
95 |
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
G.add_edge(cat_node, ent_node)
|
100 |
|
101 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
102 |
for engine in ['dot', 'neato', 'sfdp']:
|
103 |
try:
|
104 |
-
G.draw(output_path,
|
105 |
-
|
106 |
-
|
|
|
107 |
print(f"Successfully generated with {engine}")
|
108 |
-
|
|
|
|
|
|
|
|
|
109 |
except Exception as e:
|
110 |
print(f"Layout engine {engine} failed: {str(e)}")
|
111 |
continue
|
112 |
-
else:
|
113 |
-
raise RuntimeError("All layout engines failed")
|
114 |
|
115 |
-
|
116 |
-
if not os.path.exists(output_path):
|
117 |
-
raise FileNotFoundError("Mind map file was not generated")
|
118 |
-
|
119 |
-
return output_path
|
120 |
|
121 |
except Exception as e:
|
122 |
print(f"Mind map generation failed: {str(e)}")
|
123 |
-
#
|
124 |
-
|
125 |
-
if not os.path.exists(placeholder_path):
|
126 |
-
# Create simple placeholder
|
127 |
import matplotlib.pyplot as plt
|
128 |
-
|
129 |
-
|
130 |
-
|
|
|
131 |
plt.axis('off')
|
132 |
-
|
|
|
133 |
plt.close()
|
134 |
-
|
|
|
|
|
135 |
@app.post("/summarize")
|
136 |
def summarize_text(request: TextRequest):
|
137 |
chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
|
@@ -252,11 +305,27 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
|
|
252 |
return None
|
253 |
|
254 |
mindmap_btn.click(
|
255 |
-
|
256 |
-
|
257 |
-
|
|
|
|
|
258 |
)
|
259 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
260 |
if __name__ == "__main__":
|
261 |
iface.launch(
|
262 |
server_name="0.0.0.0",
|
|
|
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)
|
|
|
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="300", # 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)]
|
|
|
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(
|
331 |
server_name="0.0.0.0",
|
space/space/app.py
CHANGED
@@ -38,7 +38,7 @@ def wrap_label(label, max_length=15):
|
|
38 |
|
39 |
return "\\n".join(lines)
|
40 |
def generate_high_res_mindmap(text):
|
41 |
-
"""Generate mind map
|
42 |
try:
|
43 |
# Verify we have entities to visualize
|
44 |
entities = extract_entities(text)
|
@@ -46,92 +46,145 @@ def generate_high_res_mindmap(text):
|
|
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 |
-
#
|
55 |
G = pgv.AGraph(
|
56 |
directed=True,
|
57 |
-
rankdir="TB",
|
58 |
bgcolor="white",
|
59 |
-
fontname="
|
60 |
-
splines="ortho"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
61 |
)
|
62 |
|
63 |
-
#
|
64 |
G.node_attr.update({
|
65 |
-
"fontsize": "
|
|
|
66 |
"shape": "box",
|
67 |
"style": "rounded,filled",
|
68 |
"fillcolor": "#E1F5FE",
|
69 |
"color": "#0288D1",
|
|
|
|
|
|
|
|
|
70 |
})
|
71 |
|
72 |
-
#
|
73 |
G.edge_attr.update({
|
74 |
-
"color": "#
|
75 |
-
"penwidth": "
|
|
|
|
|
|
|
|
|
76 |
})
|
77 |
|
78 |
-
# Add central node
|
79 |
-
G.add_node("DOCUMENT",
|
80 |
-
|
81 |
-
|
82 |
-
|
|
|
|
|
|
|
83 |
|
84 |
-
# Add entities with
|
85 |
max_categories = 5
|
86 |
-
max_entities =
|
87 |
|
88 |
for cat_idx, (category, values) in enumerate(entities.items()):
|
89 |
if cat_idx >= max_categories:
|
90 |
break
|
91 |
|
|
|
92 |
cat_node = f"CAT_{cat_idx}"
|
93 |
-
G.add_node(cat_node,
|
94 |
-
|
|
|
|
|
|
|
95 |
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
G.add_edge(cat_node, ent_node)
|
100 |
|
101 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
102 |
for engine in ['dot', 'neato', 'sfdp']:
|
103 |
try:
|
104 |
-
G.draw(output_path,
|
105 |
-
|
106 |
-
|
|
|
107 |
print(f"Successfully generated with {engine}")
|
108 |
-
|
|
|
|
|
|
|
|
|
109 |
except Exception as e:
|
110 |
print(f"Layout engine {engine} failed: {str(e)}")
|
111 |
continue
|
112 |
-
else:
|
113 |
-
raise RuntimeError("All layout engines failed")
|
114 |
|
115 |
-
|
116 |
-
if not os.path.exists(output_path):
|
117 |
-
raise FileNotFoundError("Mind map file was not generated")
|
118 |
-
|
119 |
-
return output_path
|
120 |
|
121 |
except Exception as e:
|
122 |
print(f"Mind map generation failed: {str(e)}")
|
123 |
-
#
|
124 |
-
|
125 |
-
if not os.path.exists(placeholder_path):
|
126 |
-
# Create simple placeholder
|
127 |
import matplotlib.pyplot as plt
|
128 |
-
|
129 |
-
|
130 |
-
|
|
|
131 |
plt.axis('off')
|
132 |
-
|
|
|
133 |
plt.close()
|
134 |
-
|
|
|
|
|
135 |
@app.post("/summarize")
|
136 |
def summarize_text(request: TextRequest):
|
137 |
chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
|
@@ -252,11 +305,27 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
|
|
252 |
return None
|
253 |
|
254 |
mindmap_btn.click(
|
255 |
-
|
256 |
-
|
257 |
-
|
|
|
|
|
258 |
)
|
259 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
260 |
if __name__ == "__main__":
|
261 |
iface.launch(
|
262 |
server_name="0.0.0.0",
|
|
|
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)
|
|
|
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="300", # 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)]
|
|
|
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(
|
331 |
server_name="0.0.0.0",
|
space/space/space/app.py
CHANGED
@@ -38,7 +38,7 @@ def wrap_label(label, max_length=15):
|
|
38 |
|
39 |
return "\\n".join(lines)
|
40 |
def generate_high_res_mindmap(text):
|
41 |
-
"""Generate mind map
|
42 |
try:
|
43 |
# Verify we have entities to visualize
|
44 |
entities = extract_entities(text)
|
@@ -46,92 +46,145 @@ def generate_high_res_mindmap(text):
|
|
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 |
-
#
|
55 |
G = pgv.AGraph(
|
56 |
directed=True,
|
57 |
-
rankdir="TB",
|
58 |
bgcolor="white",
|
59 |
-
fontname="
|
60 |
-
splines="ortho"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
61 |
)
|
62 |
|
63 |
-
#
|
64 |
G.node_attr.update({
|
65 |
-
"fontsize": "
|
|
|
66 |
"shape": "box",
|
67 |
"style": "rounded,filled",
|
68 |
"fillcolor": "#E1F5FE",
|
69 |
"color": "#0288D1",
|
|
|
|
|
|
|
|
|
70 |
})
|
71 |
|
72 |
-
#
|
73 |
G.edge_attr.update({
|
74 |
-
"color": "#
|
75 |
-
"penwidth": "
|
|
|
|
|
|
|
|
|
76 |
})
|
77 |
|
78 |
-
# Add central node
|
79 |
-
G.add_node("DOCUMENT",
|
80 |
-
|
81 |
-
|
82 |
-
|
|
|
|
|
|
|
83 |
|
84 |
-
# Add entities with
|
85 |
max_categories = 5
|
86 |
-
max_entities =
|
87 |
|
88 |
for cat_idx, (category, values) in enumerate(entities.items()):
|
89 |
if cat_idx >= max_categories:
|
90 |
break
|
91 |
|
|
|
92 |
cat_node = f"CAT_{cat_idx}"
|
93 |
-
G.add_node(cat_node,
|
94 |
-
|
|
|
|
|
|
|
95 |
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
G.add_edge(cat_node, ent_node)
|
100 |
|
101 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
102 |
for engine in ['dot', 'neato', 'sfdp']:
|
103 |
try:
|
104 |
-
G.draw(output_path,
|
105 |
-
|
106 |
-
|
|
|
107 |
print(f"Successfully generated with {engine}")
|
108 |
-
|
|
|
|
|
|
|
|
|
109 |
except Exception as e:
|
110 |
print(f"Layout engine {engine} failed: {str(e)}")
|
111 |
continue
|
112 |
-
else:
|
113 |
-
raise RuntimeError("All layout engines failed")
|
114 |
|
115 |
-
|
116 |
-
if not os.path.exists(output_path):
|
117 |
-
raise FileNotFoundError("Mind map file was not generated")
|
118 |
-
|
119 |
-
return output_path
|
120 |
|
121 |
except Exception as e:
|
122 |
print(f"Mind map generation failed: {str(e)}")
|
123 |
-
#
|
124 |
-
|
125 |
-
if not os.path.exists(placeholder_path):
|
126 |
-
# Create simple placeholder
|
127 |
import matplotlib.pyplot as plt
|
128 |
-
|
129 |
-
|
130 |
-
|
|
|
131 |
plt.axis('off')
|
132 |
-
|
|
|
133 |
plt.close()
|
134 |
-
|
|
|
|
|
135 |
@app.post("/summarize")
|
136 |
def summarize_text(request: TextRequest):
|
137 |
chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
|
@@ -252,11 +305,27 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
|
|
252 |
return None
|
253 |
|
254 |
mindmap_btn.click(
|
255 |
-
|
256 |
-
|
257 |
-
|
|
|
|
|
258 |
)
|
259 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
260 |
if __name__ == "__main__":
|
261 |
iface.launch(
|
262 |
server_name="0.0.0.0",
|
|
|
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)
|
|
|
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="300", # 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)]
|
|
|
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(
|
331 |
server_name="0.0.0.0",
|
space/space/space/space/app.py
CHANGED
@@ -38,7 +38,7 @@ def wrap_label(label, max_length=15):
|
|
38 |
|
39 |
return "\\n".join(lines)
|
40 |
def generate_high_res_mindmap(text):
|
41 |
-
"""Generate mind map
|
42 |
try:
|
43 |
# Verify we have entities to visualize
|
44 |
entities = extract_entities(text)
|
@@ -46,92 +46,145 @@ def generate_high_res_mindmap(text):
|
|
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 |
-
#
|
55 |
G = pgv.AGraph(
|
56 |
directed=True,
|
57 |
-
rankdir="TB",
|
58 |
bgcolor="white",
|
59 |
-
fontname="
|
60 |
-
splines="ortho"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
61 |
)
|
62 |
|
63 |
-
#
|
64 |
G.node_attr.update({
|
65 |
-
"fontsize": "
|
|
|
66 |
"shape": "box",
|
67 |
"style": "rounded,filled",
|
68 |
"fillcolor": "#E1F5FE",
|
69 |
"color": "#0288D1",
|
|
|
|
|
|
|
|
|
70 |
})
|
71 |
|
72 |
-
#
|
73 |
G.edge_attr.update({
|
74 |
-
"color": "#
|
75 |
-
"penwidth": "
|
|
|
|
|
|
|
|
|
76 |
})
|
77 |
|
78 |
-
# Add central node
|
79 |
-
G.add_node("DOCUMENT",
|
80 |
-
|
81 |
-
|
82 |
-
|
|
|
|
|
|
|
83 |
|
84 |
-
# Add entities with
|
85 |
max_categories = 5
|
86 |
-
max_entities =
|
87 |
|
88 |
for cat_idx, (category, values) in enumerate(entities.items()):
|
89 |
if cat_idx >= max_categories:
|
90 |
break
|
91 |
|
|
|
92 |
cat_node = f"CAT_{cat_idx}"
|
93 |
-
G.add_node(cat_node,
|
94 |
-
|
|
|
|
|
|
|
95 |
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
G.add_edge(cat_node, ent_node)
|
100 |
|
101 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
102 |
for engine in ['dot', 'neato', 'sfdp']:
|
103 |
try:
|
104 |
-
G.draw(output_path,
|
105 |
-
|
106 |
-
|
|
|
107 |
print(f"Successfully generated with {engine}")
|
108 |
-
|
|
|
|
|
|
|
|
|
109 |
except Exception as e:
|
110 |
print(f"Layout engine {engine} failed: {str(e)}")
|
111 |
continue
|
112 |
-
else:
|
113 |
-
raise RuntimeError("All layout engines failed")
|
114 |
|
115 |
-
|
116 |
-
if not os.path.exists(output_path):
|
117 |
-
raise FileNotFoundError("Mind map file was not generated")
|
118 |
-
|
119 |
-
return output_path
|
120 |
|
121 |
except Exception as e:
|
122 |
print(f"Mind map generation failed: {str(e)}")
|
123 |
-
#
|
124 |
-
|
125 |
-
if not os.path.exists(placeholder_path):
|
126 |
-
# Create simple placeholder
|
127 |
import matplotlib.pyplot as plt
|
128 |
-
|
129 |
-
|
130 |
-
|
|
|
131 |
plt.axis('off')
|
132 |
-
|
|
|
133 |
plt.close()
|
134 |
-
|
|
|
|
|
135 |
@app.post("/summarize")
|
136 |
def summarize_text(request: TextRequest):
|
137 |
chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
|
@@ -252,11 +305,27 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
|
|
252 |
return None
|
253 |
|
254 |
mindmap_btn.click(
|
255 |
-
|
256 |
-
|
257 |
-
|
|
|
|
|
258 |
)
|
259 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
260 |
if __name__ == "__main__":
|
261 |
iface.launch(
|
262 |
server_name="0.0.0.0",
|
|
|
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)
|
|
|
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="300", # 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)]
|
|
|
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(
|
331 |
server_name="0.0.0.0",
|
space/space/space/space/space/app.py
CHANGED
@@ -38,7 +38,7 @@ def wrap_label(label, max_length=15):
|
|
38 |
|
39 |
return "\\n".join(lines)
|
40 |
def generate_high_res_mindmap(text):
|
41 |
-
"""Generate mind map
|
42 |
try:
|
43 |
# Verify we have entities to visualize
|
44 |
entities = extract_entities(text)
|
@@ -46,92 +46,145 @@ def generate_high_res_mindmap(text):
|
|
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 |
-
#
|
55 |
G = pgv.AGraph(
|
56 |
directed=True,
|
57 |
-
rankdir="TB",
|
58 |
bgcolor="white",
|
59 |
-
fontname="
|
60 |
-
splines="ortho"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
61 |
)
|
62 |
|
63 |
-
#
|
64 |
G.node_attr.update({
|
65 |
-
"fontsize": "
|
|
|
66 |
"shape": "box",
|
67 |
"style": "rounded,filled",
|
68 |
"fillcolor": "#E1F5FE",
|
69 |
"color": "#0288D1",
|
|
|
|
|
|
|
|
|
70 |
})
|
71 |
|
72 |
-
#
|
73 |
G.edge_attr.update({
|
74 |
-
"color": "#
|
75 |
-
"penwidth": "
|
|
|
|
|
|
|
|
|
76 |
})
|
77 |
|
78 |
-
# Add central node
|
79 |
-
G.add_node("DOCUMENT",
|
80 |
-
|
81 |
-
|
82 |
-
|
|
|
|
|
|
|
83 |
|
84 |
-
# Add entities with
|
85 |
max_categories = 5
|
86 |
-
max_entities =
|
87 |
|
88 |
for cat_idx, (category, values) in enumerate(entities.items()):
|
89 |
if cat_idx >= max_categories:
|
90 |
break
|
91 |
|
|
|
92 |
cat_node = f"CAT_{cat_idx}"
|
93 |
-
G.add_node(cat_node,
|
94 |
-
|
|
|
|
|
|
|
95 |
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
G.add_edge(cat_node, ent_node)
|
100 |
|
101 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
102 |
for engine in ['dot', 'neato', 'sfdp']:
|
103 |
try:
|
104 |
-
G.draw(output_path,
|
105 |
-
|
106 |
-
|
|
|
107 |
print(f"Successfully generated with {engine}")
|
108 |
-
|
|
|
|
|
|
|
|
|
109 |
except Exception as e:
|
110 |
print(f"Layout engine {engine} failed: {str(e)}")
|
111 |
continue
|
112 |
-
else:
|
113 |
-
raise RuntimeError("All layout engines failed")
|
114 |
|
115 |
-
|
116 |
-
if not os.path.exists(output_path):
|
117 |
-
raise FileNotFoundError("Mind map file was not generated")
|
118 |
-
|
119 |
-
return output_path
|
120 |
|
121 |
except Exception as e:
|
122 |
print(f"Mind map generation failed: {str(e)}")
|
123 |
-
#
|
124 |
-
|
125 |
-
if not os.path.exists(placeholder_path):
|
126 |
-
# Create simple placeholder
|
127 |
import matplotlib.pyplot as plt
|
128 |
-
|
129 |
-
|
130 |
-
|
|
|
131 |
plt.axis('off')
|
132 |
-
|
|
|
133 |
plt.close()
|
134 |
-
|
|
|
|
|
135 |
@app.post("/summarize")
|
136 |
def summarize_text(request: TextRequest):
|
137 |
chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
|
@@ -252,11 +305,27 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
|
|
252 |
return None
|
253 |
|
254 |
mindmap_btn.click(
|
255 |
-
|
256 |
-
|
257 |
-
|
|
|
|
|
258 |
)
|
259 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
260 |
if __name__ == "__main__":
|
261 |
iface.launch(
|
262 |
server_name="0.0.0.0",
|
|
|
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)
|
|
|
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="300", # 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)]
|
|
|
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(
|
331 |
server_name="0.0.0.0",
|
space/space/space/space/space/space/app.py
CHANGED
@@ -38,7 +38,7 @@ def wrap_label(label, max_length=15):
|
|
38 |
|
39 |
return "\\n".join(lines)
|
40 |
def generate_high_res_mindmap(text):
|
41 |
-
"""Generate mind map
|
42 |
try:
|
43 |
# Verify we have entities to visualize
|
44 |
entities = extract_entities(text)
|
@@ -46,92 +46,145 @@ def generate_high_res_mindmap(text):
|
|
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 |
-
#
|
55 |
G = pgv.AGraph(
|
56 |
directed=True,
|
57 |
-
rankdir="TB",
|
58 |
bgcolor="white",
|
59 |
-
fontname="
|
60 |
-
splines="ortho"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
61 |
)
|
62 |
|
63 |
-
#
|
64 |
G.node_attr.update({
|
65 |
-
"fontsize": "
|
|
|
66 |
"shape": "box",
|
67 |
"style": "rounded,filled",
|
68 |
"fillcolor": "#E1F5FE",
|
69 |
"color": "#0288D1",
|
|
|
|
|
|
|
|
|
70 |
})
|
71 |
|
72 |
-
#
|
73 |
G.edge_attr.update({
|
74 |
-
"color": "#
|
75 |
-
"penwidth": "
|
|
|
|
|
|
|
|
|
76 |
})
|
77 |
|
78 |
-
# Add central node
|
79 |
-
G.add_node("DOCUMENT",
|
80 |
-
|
81 |
-
|
82 |
-
|
|
|
|
|
|
|
83 |
|
84 |
-
# Add entities with
|
85 |
max_categories = 5
|
86 |
-
max_entities =
|
87 |
|
88 |
for cat_idx, (category, values) in enumerate(entities.items()):
|
89 |
if cat_idx >= max_categories:
|
90 |
break
|
91 |
|
|
|
92 |
cat_node = f"CAT_{cat_idx}"
|
93 |
-
G.add_node(cat_node,
|
94 |
-
|
|
|
|
|
|
|
95 |
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
G.add_edge(cat_node, ent_node)
|
100 |
|
101 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
102 |
for engine in ['dot', 'neato', 'sfdp']:
|
103 |
try:
|
104 |
-
G.draw(output_path,
|
105 |
-
|
106 |
-
|
|
|
107 |
print(f"Successfully generated with {engine}")
|
108 |
-
|
|
|
|
|
|
|
|
|
109 |
except Exception as e:
|
110 |
print(f"Layout engine {engine} failed: {str(e)}")
|
111 |
continue
|
112 |
-
else:
|
113 |
-
raise RuntimeError("All layout engines failed")
|
114 |
|
115 |
-
|
116 |
-
if not os.path.exists(output_path):
|
117 |
-
raise FileNotFoundError("Mind map file was not generated")
|
118 |
-
|
119 |
-
return output_path
|
120 |
|
121 |
except Exception as e:
|
122 |
print(f"Mind map generation failed: {str(e)}")
|
123 |
-
#
|
124 |
-
|
125 |
-
if not os.path.exists(placeholder_path):
|
126 |
-
# Create simple placeholder
|
127 |
import matplotlib.pyplot as plt
|
128 |
-
|
129 |
-
|
130 |
-
|
|
|
131 |
plt.axis('off')
|
132 |
-
|
|
|
133 |
plt.close()
|
134 |
-
|
|
|
|
|
135 |
@app.post("/summarize")
|
136 |
def summarize_text(request: TextRequest):
|
137 |
chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
|
@@ -252,11 +305,27 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
|
|
252 |
return None
|
253 |
|
254 |
mindmap_btn.click(
|
255 |
-
|
256 |
-
|
257 |
-
|
|
|
|
|
258 |
)
|
259 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
260 |
if __name__ == "__main__":
|
261 |
iface.launch(
|
262 |
server_name="0.0.0.0",
|
|
|
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)
|
|
|
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="300", # 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)]
|
|
|
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(
|
331 |
server_name="0.0.0.0",
|
space/space/space/space/space/space/space/app.py
CHANGED
@@ -38,7 +38,7 @@ def wrap_label(label, max_length=15):
|
|
38 |
|
39 |
return "\\n".join(lines)
|
40 |
def generate_high_res_mindmap(text):
|
41 |
-
"""Generate mind map
|
42 |
try:
|
43 |
# Verify we have entities to visualize
|
44 |
entities = extract_entities(text)
|
@@ -46,92 +46,145 @@ def generate_high_res_mindmap(text):
|
|
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 |
-
#
|
55 |
G = pgv.AGraph(
|
56 |
directed=True,
|
57 |
-
rankdir="TB",
|
58 |
bgcolor="white",
|
59 |
-
fontname="
|
60 |
-
splines="ortho"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
61 |
)
|
62 |
|
63 |
-
#
|
64 |
G.node_attr.update({
|
65 |
-
"fontsize": "
|
|
|
66 |
"shape": "box",
|
67 |
"style": "rounded,filled",
|
68 |
"fillcolor": "#E1F5FE",
|
69 |
"color": "#0288D1",
|
|
|
|
|
|
|
|
|
70 |
})
|
71 |
|
72 |
-
#
|
73 |
G.edge_attr.update({
|
74 |
-
"color": "#
|
75 |
-
"penwidth": "
|
|
|
|
|
|
|
|
|
76 |
})
|
77 |
|
78 |
-
# Add central node
|
79 |
-
G.add_node("DOCUMENT",
|
80 |
-
|
81 |
-
|
82 |
-
|
|
|
|
|
|
|
83 |
|
84 |
-
# Add entities with
|
85 |
max_categories = 5
|
86 |
-
max_entities =
|
87 |
|
88 |
for cat_idx, (category, values) in enumerate(entities.items()):
|
89 |
if cat_idx >= max_categories:
|
90 |
break
|
91 |
|
|
|
92 |
cat_node = f"CAT_{cat_idx}"
|
93 |
-
G.add_node(cat_node,
|
94 |
-
|
|
|
|
|
|
|
95 |
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
G.add_edge(cat_node, ent_node)
|
100 |
|
101 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
102 |
for engine in ['dot', 'neato', 'sfdp']:
|
103 |
try:
|
104 |
-
G.draw(output_path,
|
105 |
-
|
106 |
-
|
|
|
107 |
print(f"Successfully generated with {engine}")
|
108 |
-
|
|
|
|
|
|
|
|
|
109 |
except Exception as e:
|
110 |
print(f"Layout engine {engine} failed: {str(e)}")
|
111 |
continue
|
112 |
-
else:
|
113 |
-
raise RuntimeError("All layout engines failed")
|
114 |
|
115 |
-
|
116 |
-
if not os.path.exists(output_path):
|
117 |
-
raise FileNotFoundError("Mind map file was not generated")
|
118 |
-
|
119 |
-
return output_path
|
120 |
|
121 |
except Exception as e:
|
122 |
print(f"Mind map generation failed: {str(e)}")
|
123 |
-
#
|
124 |
-
|
125 |
-
if not os.path.exists(placeholder_path):
|
126 |
-
# Create simple placeholder
|
127 |
import matplotlib.pyplot as plt
|
128 |
-
|
129 |
-
|
130 |
-
|
|
|
131 |
plt.axis('off')
|
132 |
-
|
|
|
133 |
plt.close()
|
134 |
-
|
|
|
|
|
135 |
@app.post("/summarize")
|
136 |
def summarize_text(request: TextRequest):
|
137 |
chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
|
@@ -252,11 +305,27 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
|
|
252 |
return None
|
253 |
|
254 |
mindmap_btn.click(
|
255 |
-
|
256 |
-
|
257 |
-
|
|
|
|
|
258 |
)
|
259 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
260 |
if __name__ == "__main__":
|
261 |
iface.launch(
|
262 |
server_name="0.0.0.0",
|
|
|
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)
|
|
|
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="300", # 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)]
|
|
|
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(
|
331 |
server_name="0.0.0.0",
|
space/space/space/space/space/space/space/space/app.py
CHANGED
@@ -38,7 +38,7 @@ def wrap_label(label, max_length=15):
|
|
38 |
|
39 |
return "\\n".join(lines)
|
40 |
def generate_high_res_mindmap(text):
|
41 |
-
"""Generate mind map
|
42 |
try:
|
43 |
# Verify we have entities to visualize
|
44 |
entities = extract_entities(text)
|
@@ -46,92 +46,145 @@ def generate_high_res_mindmap(text):
|
|
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 |
-
#
|
55 |
G = pgv.AGraph(
|
56 |
directed=True,
|
57 |
-
rankdir="TB",
|
58 |
bgcolor="white",
|
59 |
-
fontname="
|
60 |
-
splines="ortho"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
61 |
)
|
62 |
|
63 |
-
#
|
64 |
G.node_attr.update({
|
65 |
-
"fontsize": "
|
|
|
66 |
"shape": "box",
|
67 |
"style": "rounded,filled",
|
68 |
"fillcolor": "#E1F5FE",
|
69 |
"color": "#0288D1",
|
|
|
|
|
|
|
|
|
70 |
})
|
71 |
|
72 |
-
#
|
73 |
G.edge_attr.update({
|
74 |
-
"color": "#
|
75 |
-
"penwidth": "
|
|
|
|
|
|
|
|
|
76 |
})
|
77 |
|
78 |
-
# Add central node
|
79 |
-
G.add_node("DOCUMENT",
|
80 |
-
|
81 |
-
|
82 |
-
|
|
|
|
|
|
|
83 |
|
84 |
-
# Add entities with
|
85 |
max_categories = 5
|
86 |
-
max_entities =
|
87 |
|
88 |
for cat_idx, (category, values) in enumerate(entities.items()):
|
89 |
if cat_idx >= max_categories:
|
90 |
break
|
91 |
|
|
|
92 |
cat_node = f"CAT_{cat_idx}"
|
93 |
-
G.add_node(cat_node,
|
94 |
-
|
|
|
|
|
|
|
95 |
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
G.add_edge(cat_node, ent_node)
|
100 |
|
101 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
102 |
for engine in ['dot', 'neato', 'sfdp']:
|
103 |
try:
|
104 |
-
G.draw(output_path,
|
105 |
-
|
106 |
-
|
|
|
107 |
print(f"Successfully generated with {engine}")
|
108 |
-
|
|
|
|
|
|
|
|
|
109 |
except Exception as e:
|
110 |
print(f"Layout engine {engine} failed: {str(e)}")
|
111 |
continue
|
112 |
-
else:
|
113 |
-
raise RuntimeError("All layout engines failed")
|
114 |
|
115 |
-
|
116 |
-
if not os.path.exists(output_path):
|
117 |
-
raise FileNotFoundError("Mind map file was not generated")
|
118 |
-
|
119 |
-
return output_path
|
120 |
|
121 |
except Exception as e:
|
122 |
print(f"Mind map generation failed: {str(e)}")
|
123 |
-
#
|
124 |
-
|
125 |
-
if not os.path.exists(placeholder_path):
|
126 |
-
# Create simple placeholder
|
127 |
import matplotlib.pyplot as plt
|
128 |
-
|
129 |
-
|
130 |
-
|
|
|
131 |
plt.axis('off')
|
132 |
-
|
|
|
133 |
plt.close()
|
134 |
-
|
|
|
|
|
135 |
@app.post("/summarize")
|
136 |
def summarize_text(request: TextRequest):
|
137 |
chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
|
@@ -252,11 +305,27 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
|
|
252 |
return None
|
253 |
|
254 |
mindmap_btn.click(
|
255 |
-
|
256 |
-
|
257 |
-
|
|
|
|
|
258 |
)
|
259 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
260 |
if __name__ == "__main__":
|
261 |
iface.launch(
|
262 |
server_name="0.0.0.0",
|
|
|
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)
|
|
|
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="300", # 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)]
|
|
|
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(
|
331 |
server_name="0.0.0.0",
|
space/space/space/space/space/space/space/space/space/app.py
CHANGED
@@ -38,7 +38,7 @@ def wrap_label(label, max_length=15):
|
|
38 |
|
39 |
return "\\n".join(lines)
|
40 |
def generate_high_res_mindmap(text):
|
41 |
-
"""Generate mind map
|
42 |
try:
|
43 |
# Verify we have entities to visualize
|
44 |
entities = extract_entities(text)
|
@@ -46,92 +46,145 @@ def generate_high_res_mindmap(text):
|
|
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 |
-
#
|
55 |
G = pgv.AGraph(
|
56 |
directed=True,
|
57 |
-
rankdir="TB",
|
58 |
bgcolor="white",
|
59 |
-
fontname="
|
60 |
-
splines="ortho"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
61 |
)
|
62 |
|
63 |
-
#
|
64 |
G.node_attr.update({
|
65 |
-
"fontsize": "
|
|
|
66 |
"shape": "box",
|
67 |
"style": "rounded,filled",
|
68 |
"fillcolor": "#E1F5FE",
|
69 |
"color": "#0288D1",
|
|
|
|
|
|
|
|
|
70 |
})
|
71 |
|
72 |
-
#
|
73 |
G.edge_attr.update({
|
74 |
-
"color": "#
|
75 |
-
"penwidth": "
|
|
|
|
|
|
|
|
|
76 |
})
|
77 |
|
78 |
-
# Add central node
|
79 |
-
G.add_node("DOCUMENT",
|
80 |
-
|
81 |
-
|
82 |
-
|
|
|
|
|
|
|
83 |
|
84 |
-
# Add entities with
|
85 |
max_categories = 5
|
86 |
-
max_entities =
|
87 |
|
88 |
for cat_idx, (category, values) in enumerate(entities.items()):
|
89 |
if cat_idx >= max_categories:
|
90 |
break
|
91 |
|
|
|
92 |
cat_node = f"CAT_{cat_idx}"
|
93 |
-
G.add_node(cat_node,
|
94 |
-
|
|
|
|
|
|
|
95 |
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
G.add_edge(cat_node, ent_node)
|
100 |
|
101 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
102 |
for engine in ['dot', 'neato', 'sfdp']:
|
103 |
try:
|
104 |
-
G.draw(output_path,
|
105 |
-
|
106 |
-
|
|
|
107 |
print(f"Successfully generated with {engine}")
|
108 |
-
|
|
|
|
|
|
|
|
|
109 |
except Exception as e:
|
110 |
print(f"Layout engine {engine} failed: {str(e)}")
|
111 |
continue
|
112 |
-
else:
|
113 |
-
raise RuntimeError("All layout engines failed")
|
114 |
|
115 |
-
|
116 |
-
if not os.path.exists(output_path):
|
117 |
-
raise FileNotFoundError("Mind map file was not generated")
|
118 |
-
|
119 |
-
return output_path
|
120 |
|
121 |
except Exception as e:
|
122 |
print(f"Mind map generation failed: {str(e)}")
|
123 |
-
#
|
124 |
-
|
125 |
-
if not os.path.exists(placeholder_path):
|
126 |
-
# Create simple placeholder
|
127 |
import matplotlib.pyplot as plt
|
128 |
-
|
129 |
-
|
130 |
-
|
|
|
131 |
plt.axis('off')
|
132 |
-
|
|
|
133 |
plt.close()
|
134 |
-
|
|
|
|
|
135 |
@app.post("/summarize")
|
136 |
def summarize_text(request: TextRequest):
|
137 |
chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
|
@@ -252,11 +305,27 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
|
|
252 |
return None
|
253 |
|
254 |
mindmap_btn.click(
|
255 |
-
|
256 |
-
|
257 |
-
|
|
|
|
|
258 |
)
|
259 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
260 |
if __name__ == "__main__":
|
261 |
iface.launch(
|
262 |
server_name="0.0.0.0",
|
|
|
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)
|
|
|
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="300", # 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)]
|
|
|
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(
|
331 |
server_name="0.0.0.0",
|
space/space/space/space/space/space/space/space/space/space/app.py
CHANGED
@@ -38,7 +38,7 @@ def wrap_label(label, max_length=15):
|
|
38 |
|
39 |
return "\\n".join(lines)
|
40 |
def generate_high_res_mindmap(text):
|
41 |
-
"""Generate mind map
|
42 |
try:
|
43 |
# Verify we have entities to visualize
|
44 |
entities = extract_entities(text)
|
@@ -46,92 +46,145 @@ def generate_high_res_mindmap(text):
|
|
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 |
-
#
|
55 |
G = pgv.AGraph(
|
56 |
directed=True,
|
57 |
-
rankdir="TB",
|
58 |
bgcolor="white",
|
59 |
-
fontname="
|
60 |
-
splines="ortho"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
61 |
)
|
62 |
|
63 |
-
#
|
64 |
G.node_attr.update({
|
65 |
-
"fontsize": "
|
|
|
66 |
"shape": "box",
|
67 |
"style": "rounded,filled",
|
68 |
"fillcolor": "#E1F5FE",
|
69 |
"color": "#0288D1",
|
|
|
|
|
|
|
|
|
70 |
})
|
71 |
|
72 |
-
#
|
73 |
G.edge_attr.update({
|
74 |
-
"color": "#
|
75 |
-
"penwidth": "
|
|
|
|
|
|
|
|
|
76 |
})
|
77 |
|
78 |
-
# Add central node
|
79 |
-
G.add_node("DOCUMENT",
|
80 |
-
|
81 |
-
|
82 |
-
|
|
|
|
|
|
|
83 |
|
84 |
-
# Add entities with
|
85 |
max_categories = 5
|
86 |
-
max_entities =
|
87 |
|
88 |
for cat_idx, (category, values) in enumerate(entities.items()):
|
89 |
if cat_idx >= max_categories:
|
90 |
break
|
91 |
|
|
|
92 |
cat_node = f"CAT_{cat_idx}"
|
93 |
-
G.add_node(cat_node,
|
94 |
-
|
|
|
|
|
|
|
95 |
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
G.add_edge(cat_node, ent_node)
|
100 |
|
101 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
102 |
for engine in ['dot', 'neato', 'sfdp']:
|
103 |
try:
|
104 |
-
G.draw(output_path,
|
105 |
-
|
106 |
-
|
|
|
107 |
print(f"Successfully generated with {engine}")
|
108 |
-
|
|
|
|
|
|
|
|
|
109 |
except Exception as e:
|
110 |
print(f"Layout engine {engine} failed: {str(e)}")
|
111 |
continue
|
112 |
-
else:
|
113 |
-
raise RuntimeError("All layout engines failed")
|
114 |
|
115 |
-
|
116 |
-
if not os.path.exists(output_path):
|
117 |
-
raise FileNotFoundError("Mind map file was not generated")
|
118 |
-
|
119 |
-
return output_path
|
120 |
|
121 |
except Exception as e:
|
122 |
print(f"Mind map generation failed: {str(e)}")
|
123 |
-
#
|
124 |
-
|
125 |
-
if not os.path.exists(placeholder_path):
|
126 |
-
# Create simple placeholder
|
127 |
import matplotlib.pyplot as plt
|
128 |
-
|
129 |
-
|
130 |
-
|
|
|
131 |
plt.axis('off')
|
132 |
-
|
|
|
133 |
plt.close()
|
134 |
-
|
|
|
|
|
135 |
@app.post("/summarize")
|
136 |
def summarize_text(request: TextRequest):
|
137 |
chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
|
@@ -252,11 +305,27 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
|
|
252 |
return None
|
253 |
|
254 |
mindmap_btn.click(
|
255 |
-
|
256 |
-
|
257 |
-
|
|
|
|
|
258 |
)
|
259 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
260 |
if __name__ == "__main__":
|
261 |
iface.launch(
|
262 |
server_name="0.0.0.0",
|
|
|
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)
|
|
|
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="300", # 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)]
|
|
|
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(
|
331 |
server_name="0.0.0.0",
|
space/space/space/space/space/space/space/space/space/space/space/app.py
CHANGED
@@ -38,7 +38,7 @@ def wrap_label(label, max_length=15):
|
|
38 |
|
39 |
return "\\n".join(lines)
|
40 |
def generate_high_res_mindmap(text):
|
41 |
-
"""Generate mind map
|
42 |
try:
|
43 |
# Verify we have entities to visualize
|
44 |
entities = extract_entities(text)
|
@@ -46,92 +46,145 @@ def generate_high_res_mindmap(text):
|
|
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 |
-
#
|
55 |
G = pgv.AGraph(
|
56 |
directed=True,
|
57 |
-
rankdir="TB",
|
58 |
bgcolor="white",
|
59 |
-
fontname="
|
60 |
-
splines="ortho"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
61 |
)
|
62 |
|
63 |
-
#
|
64 |
G.node_attr.update({
|
65 |
-
"fontsize": "
|
|
|
66 |
"shape": "box",
|
67 |
"style": "rounded,filled",
|
68 |
"fillcolor": "#E1F5FE",
|
69 |
"color": "#0288D1",
|
|
|
|
|
|
|
|
|
70 |
})
|
71 |
|
72 |
-
#
|
73 |
G.edge_attr.update({
|
74 |
-
"color": "#
|
75 |
-
"penwidth": "
|
|
|
|
|
|
|
|
|
76 |
})
|
77 |
|
78 |
-
# Add central node
|
79 |
-
G.add_node("DOCUMENT",
|
80 |
-
|
81 |
-
|
82 |
-
|
|
|
|
|
|
|
83 |
|
84 |
-
# Add entities with
|
85 |
max_categories = 5
|
86 |
-
max_entities =
|
87 |
|
88 |
for cat_idx, (category, values) in enumerate(entities.items()):
|
89 |
if cat_idx >= max_categories:
|
90 |
break
|
91 |
|
|
|
92 |
cat_node = f"CAT_{cat_idx}"
|
93 |
-
G.add_node(cat_node,
|
94 |
-
|
|
|
|
|
|
|
95 |
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
G.add_edge(cat_node, ent_node)
|
100 |
|
101 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
102 |
for engine in ['dot', 'neato', 'sfdp']:
|
103 |
try:
|
104 |
-
G.draw(output_path,
|
105 |
-
|
106 |
-
|
|
|
107 |
print(f"Successfully generated with {engine}")
|
108 |
-
|
|
|
|
|
|
|
|
|
109 |
except Exception as e:
|
110 |
print(f"Layout engine {engine} failed: {str(e)}")
|
111 |
continue
|
112 |
-
else:
|
113 |
-
raise RuntimeError("All layout engines failed")
|
114 |
|
115 |
-
|
116 |
-
if not os.path.exists(output_path):
|
117 |
-
raise FileNotFoundError("Mind map file was not generated")
|
118 |
-
|
119 |
-
return output_path
|
120 |
|
121 |
except Exception as e:
|
122 |
print(f"Mind map generation failed: {str(e)}")
|
123 |
-
#
|
124 |
-
|
125 |
-
if not os.path.exists(placeholder_path):
|
126 |
-
# Create simple placeholder
|
127 |
import matplotlib.pyplot as plt
|
128 |
-
|
129 |
-
|
130 |
-
|
|
|
131 |
plt.axis('off')
|
132 |
-
|
|
|
133 |
plt.close()
|
134 |
-
|
|
|
|
|
135 |
@app.post("/summarize")
|
136 |
def summarize_text(request: TextRequest):
|
137 |
chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
|
@@ -252,11 +305,27 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
|
|
252 |
return None
|
253 |
|
254 |
mindmap_btn.click(
|
255 |
-
|
256 |
-
|
257 |
-
|
|
|
|
|
258 |
)
|
259 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
260 |
if __name__ == "__main__":
|
261 |
iface.launch(
|
262 |
server_name="0.0.0.0",
|
|
|
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)
|
|
|
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="300", # 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)]
|
|
|
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(
|
331 |
server_name="0.0.0.0",
|
space/space/space/space/space/space/space/space/space/space/space/space/app.py
CHANGED
@@ -38,7 +38,7 @@ def wrap_label(label, max_length=15):
|
|
38 |
|
39 |
return "\\n".join(lines)
|
40 |
def generate_high_res_mindmap(text):
|
41 |
-
"""Generate mind map
|
42 |
try:
|
43 |
# Verify we have entities to visualize
|
44 |
entities = extract_entities(text)
|
@@ -46,92 +46,145 @@ def generate_high_res_mindmap(text):
|
|
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 |
-
#
|
55 |
G = pgv.AGraph(
|
56 |
directed=True,
|
57 |
-
rankdir="TB",
|
58 |
bgcolor="white",
|
59 |
-
fontname="
|
60 |
-
splines="ortho"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
61 |
)
|
62 |
|
63 |
-
#
|
64 |
G.node_attr.update({
|
65 |
-
"fontsize": "
|
|
|
66 |
"shape": "box",
|
67 |
"style": "rounded,filled",
|
68 |
"fillcolor": "#E1F5FE",
|
69 |
"color": "#0288D1",
|
|
|
|
|
|
|
|
|
70 |
})
|
71 |
|
72 |
-
#
|
73 |
G.edge_attr.update({
|
74 |
-
"color": "#
|
75 |
-
"penwidth": "
|
|
|
|
|
|
|
|
|
76 |
})
|
77 |
|
78 |
-
# Add central node
|
79 |
-
G.add_node("DOCUMENT",
|
80 |
-
|
81 |
-
|
82 |
-
|
|
|
|
|
|
|
83 |
|
84 |
-
# Add entities with
|
85 |
max_categories = 5
|
86 |
-
max_entities =
|
87 |
|
88 |
for cat_idx, (category, values) in enumerate(entities.items()):
|
89 |
if cat_idx >= max_categories:
|
90 |
break
|
91 |
|
|
|
92 |
cat_node = f"CAT_{cat_idx}"
|
93 |
-
G.add_node(cat_node,
|
94 |
-
|
|
|
|
|
|
|
95 |
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
G.add_edge(cat_node, ent_node)
|
100 |
|
101 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
102 |
for engine in ['dot', 'neato', 'sfdp']:
|
103 |
try:
|
104 |
-
G.draw(output_path,
|
105 |
-
|
106 |
-
|
|
|
107 |
print(f"Successfully generated with {engine}")
|
108 |
-
|
|
|
|
|
|
|
|
|
109 |
except Exception as e:
|
110 |
print(f"Layout engine {engine} failed: {str(e)}")
|
111 |
continue
|
112 |
-
else:
|
113 |
-
raise RuntimeError("All layout engines failed")
|
114 |
|
115 |
-
|
116 |
-
if not os.path.exists(output_path):
|
117 |
-
raise FileNotFoundError("Mind map file was not generated")
|
118 |
-
|
119 |
-
return output_path
|
120 |
|
121 |
except Exception as e:
|
122 |
print(f"Mind map generation failed: {str(e)}")
|
123 |
-
#
|
124 |
-
|
125 |
-
if not os.path.exists(placeholder_path):
|
126 |
-
# Create simple placeholder
|
127 |
import matplotlib.pyplot as plt
|
128 |
-
|
129 |
-
|
130 |
-
|
|
|
131 |
plt.axis('off')
|
132 |
-
|
|
|
133 |
plt.close()
|
134 |
-
|
|
|
|
|
135 |
@app.post("/summarize")
|
136 |
def summarize_text(request: TextRequest):
|
137 |
chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
|
@@ -252,11 +305,27 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
|
|
252 |
return None
|
253 |
|
254 |
mindmap_btn.click(
|
255 |
-
|
256 |
-
|
257 |
-
|
|
|
|
|
258 |
)
|
259 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
260 |
if __name__ == "__main__":
|
261 |
iface.launch(
|
262 |
server_name="0.0.0.0",
|
|
|
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)
|
|
|
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="300", # 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)]
|
|
|
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(
|
331 |
server_name="0.0.0.0",
|
space/space/space/space/space/space/space/space/space/space/space/space/space/app.py
CHANGED
@@ -38,7 +38,7 @@ def wrap_label(label, max_length=15):
|
|
38 |
|
39 |
return "\\n".join(lines)
|
40 |
def generate_high_res_mindmap(text):
|
41 |
-
"""Generate mind map
|
42 |
try:
|
43 |
# Verify we have entities to visualize
|
44 |
entities = extract_entities(text)
|
@@ -46,92 +46,145 @@ def generate_high_res_mindmap(text):
|
|
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 |
-
#
|
55 |
G = pgv.AGraph(
|
56 |
directed=True,
|
57 |
-
rankdir="TB",
|
58 |
bgcolor="white",
|
59 |
-
fontname="
|
60 |
-
splines="ortho"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
61 |
)
|
62 |
|
63 |
-
#
|
64 |
G.node_attr.update({
|
65 |
-
"fontsize": "
|
|
|
66 |
"shape": "box",
|
67 |
"style": "rounded,filled",
|
68 |
"fillcolor": "#E1F5FE",
|
69 |
"color": "#0288D1",
|
|
|
|
|
|
|
|
|
70 |
})
|
71 |
|
72 |
-
#
|
73 |
G.edge_attr.update({
|
74 |
-
"color": "#
|
75 |
-
"penwidth": "
|
|
|
|
|
|
|
|
|
76 |
})
|
77 |
|
78 |
-
# Add central node
|
79 |
-
G.add_node("DOCUMENT",
|
80 |
-
|
81 |
-
|
82 |
-
|
|
|
|
|
|
|
83 |
|
84 |
-
# Add entities with
|
85 |
max_categories = 5
|
86 |
-
max_entities =
|
87 |
|
88 |
for cat_idx, (category, values) in enumerate(entities.items()):
|
89 |
if cat_idx >= max_categories:
|
90 |
break
|
91 |
|
|
|
92 |
cat_node = f"CAT_{cat_idx}"
|
93 |
-
G.add_node(cat_node,
|
94 |
-
|
|
|
|
|
|
|
95 |
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
G.add_edge(cat_node, ent_node)
|
100 |
|
101 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
102 |
for engine in ['dot', 'neato', 'sfdp']:
|
103 |
try:
|
104 |
-
G.draw(output_path,
|
105 |
-
|
106 |
-
|
|
|
107 |
print(f"Successfully generated with {engine}")
|
108 |
-
|
|
|
|
|
|
|
|
|
109 |
except Exception as e:
|
110 |
print(f"Layout engine {engine} failed: {str(e)}")
|
111 |
continue
|
112 |
-
else:
|
113 |
-
raise RuntimeError("All layout engines failed")
|
114 |
|
115 |
-
|
116 |
-
if not os.path.exists(output_path):
|
117 |
-
raise FileNotFoundError("Mind map file was not generated")
|
118 |
-
|
119 |
-
return output_path
|
120 |
|
121 |
except Exception as e:
|
122 |
print(f"Mind map generation failed: {str(e)}")
|
123 |
-
#
|
124 |
-
|
125 |
-
if not os.path.exists(placeholder_path):
|
126 |
-
# Create simple placeholder
|
127 |
import matplotlib.pyplot as plt
|
128 |
-
|
129 |
-
|
130 |
-
|
|
|
131 |
plt.axis('off')
|
132 |
-
|
|
|
133 |
plt.close()
|
134 |
-
|
|
|
|
|
135 |
@app.post("/summarize")
|
136 |
def summarize_text(request: TextRequest):
|
137 |
chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
|
@@ -252,11 +305,27 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
|
|
252 |
return None
|
253 |
|
254 |
mindmap_btn.click(
|
255 |
-
|
256 |
-
|
257 |
-
|
|
|
|
|
258 |
)
|
259 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
260 |
if __name__ == "__main__":
|
261 |
iface.launch(
|
262 |
server_name="0.0.0.0",
|
|
|
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)
|
|
|
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="300", # 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)]
|
|
|
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(
|
331 |
server_name="0.0.0.0",
|
space/space/space/space/space/space/space/space/space/space/space/space/space/space/app.py
CHANGED
@@ -38,7 +38,7 @@ def wrap_label(label, max_length=15):
|
|
38 |
|
39 |
return "\\n".join(lines)
|
40 |
def generate_high_res_mindmap(text):
|
41 |
-
"""Generate mind map
|
42 |
try:
|
43 |
# Verify we have entities to visualize
|
44 |
entities = extract_entities(text)
|
@@ -46,92 +46,145 @@ def generate_high_res_mindmap(text):
|
|
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 |
-
#
|
55 |
G = pgv.AGraph(
|
56 |
directed=True,
|
57 |
-
rankdir="TB",
|
58 |
bgcolor="white",
|
59 |
-
fontname="
|
60 |
-
splines="ortho"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
61 |
)
|
62 |
|
63 |
-
#
|
64 |
G.node_attr.update({
|
65 |
-
"fontsize": "
|
|
|
66 |
"shape": "box",
|
67 |
"style": "rounded,filled",
|
68 |
"fillcolor": "#E1F5FE",
|
69 |
"color": "#0288D1",
|
|
|
|
|
|
|
|
|
70 |
})
|
71 |
|
72 |
-
#
|
73 |
G.edge_attr.update({
|
74 |
-
"color": "#
|
75 |
-
"penwidth": "
|
|
|
|
|
|
|
|
|
76 |
})
|
77 |
|
78 |
-
# Add central node
|
79 |
-
G.add_node("DOCUMENT",
|
80 |
-
|
81 |
-
|
82 |
-
|
|
|
|
|
|
|
83 |
|
84 |
-
# Add entities with
|
85 |
max_categories = 5
|
86 |
-
max_entities =
|
87 |
|
88 |
for cat_idx, (category, values) in enumerate(entities.items()):
|
89 |
if cat_idx >= max_categories:
|
90 |
break
|
91 |
|
|
|
92 |
cat_node = f"CAT_{cat_idx}"
|
93 |
-
G.add_node(cat_node,
|
94 |
-
|
|
|
|
|
|
|
95 |
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
G.add_edge(cat_node, ent_node)
|
100 |
|
101 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
102 |
for engine in ['dot', 'neato', 'sfdp']:
|
103 |
try:
|
104 |
-
G.draw(output_path,
|
105 |
-
|
106 |
-
|
|
|
107 |
print(f"Successfully generated with {engine}")
|
108 |
-
|
|
|
|
|
|
|
|
|
109 |
except Exception as e:
|
110 |
print(f"Layout engine {engine} failed: {str(e)}")
|
111 |
continue
|
112 |
-
else:
|
113 |
-
raise RuntimeError("All layout engines failed")
|
114 |
|
115 |
-
|
116 |
-
if not os.path.exists(output_path):
|
117 |
-
raise FileNotFoundError("Mind map file was not generated")
|
118 |
-
|
119 |
-
return output_path
|
120 |
|
121 |
except Exception as e:
|
122 |
print(f"Mind map generation failed: {str(e)}")
|
123 |
-
#
|
124 |
-
|
125 |
-
if not os.path.exists(placeholder_path):
|
126 |
-
# Create simple placeholder
|
127 |
import matplotlib.pyplot as plt
|
128 |
-
|
129 |
-
|
130 |
-
|
|
|
131 |
plt.axis('off')
|
132 |
-
|
|
|
133 |
plt.close()
|
134 |
-
|
|
|
|
|
135 |
@app.post("/summarize")
|
136 |
def summarize_text(request: TextRequest):
|
137 |
chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
|
@@ -252,11 +305,27 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
|
|
252 |
return None
|
253 |
|
254 |
mindmap_btn.click(
|
255 |
-
|
256 |
-
|
257 |
-
|
|
|
|
|
258 |
)
|
259 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
260 |
if __name__ == "__main__":
|
261 |
iface.launch(
|
262 |
server_name="0.0.0.0",
|
|
|
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)
|
|
|
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="300", # 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)]
|
|
|
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(
|
331 |
server_name="0.0.0.0",
|
space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/app.py
CHANGED
@@ -38,7 +38,7 @@ def wrap_label(label, max_length=15):
|
|
38 |
|
39 |
return "\\n".join(lines)
|
40 |
def generate_high_res_mindmap(text):
|
41 |
-
"""Generate mind map
|
42 |
try:
|
43 |
# Verify we have entities to visualize
|
44 |
entities = extract_entities(text)
|
@@ -46,92 +46,145 @@ def generate_high_res_mindmap(text):
|
|
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 |
-
#
|
55 |
G = pgv.AGraph(
|
56 |
directed=True,
|
57 |
-
rankdir="TB",
|
58 |
bgcolor="white",
|
59 |
-
fontname="
|
60 |
-
splines="ortho"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
61 |
)
|
62 |
|
63 |
-
#
|
64 |
G.node_attr.update({
|
65 |
-
"fontsize": "
|
|
|
66 |
"shape": "box",
|
67 |
"style": "rounded,filled",
|
68 |
"fillcolor": "#E1F5FE",
|
69 |
"color": "#0288D1",
|
|
|
|
|
|
|
|
|
70 |
})
|
71 |
|
72 |
-
#
|
73 |
G.edge_attr.update({
|
74 |
-
"color": "#
|
75 |
-
"penwidth": "
|
|
|
|
|
|
|
|
|
76 |
})
|
77 |
|
78 |
-
# Add central node
|
79 |
-
G.add_node("DOCUMENT",
|
80 |
-
|
81 |
-
|
82 |
-
|
|
|
|
|
|
|
83 |
|
84 |
-
# Add entities with
|
85 |
max_categories = 5
|
86 |
-
max_entities =
|
87 |
|
88 |
for cat_idx, (category, values) in enumerate(entities.items()):
|
89 |
if cat_idx >= max_categories:
|
90 |
break
|
91 |
|
|
|
92 |
cat_node = f"CAT_{cat_idx}"
|
93 |
-
G.add_node(cat_node,
|
94 |
-
|
|
|
|
|
|
|
95 |
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
G.add_edge(cat_node, ent_node)
|
100 |
|
101 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
102 |
for engine in ['dot', 'neato', 'sfdp']:
|
103 |
try:
|
104 |
-
G.draw(output_path,
|
105 |
-
|
106 |
-
|
|
|
107 |
print(f"Successfully generated with {engine}")
|
108 |
-
|
|
|
|
|
|
|
|
|
109 |
except Exception as e:
|
110 |
print(f"Layout engine {engine} failed: {str(e)}")
|
111 |
continue
|
112 |
-
else:
|
113 |
-
raise RuntimeError("All layout engines failed")
|
114 |
|
115 |
-
|
116 |
-
if not os.path.exists(output_path):
|
117 |
-
raise FileNotFoundError("Mind map file was not generated")
|
118 |
-
|
119 |
-
return output_path
|
120 |
|
121 |
except Exception as e:
|
122 |
print(f"Mind map generation failed: {str(e)}")
|
123 |
-
#
|
124 |
-
|
125 |
-
if not os.path.exists(placeholder_path):
|
126 |
-
# Create simple placeholder
|
127 |
import matplotlib.pyplot as plt
|
128 |
-
|
129 |
-
|
130 |
-
|
|
|
131 |
plt.axis('off')
|
132 |
-
|
|
|
133 |
plt.close()
|
134 |
-
|
|
|
|
|
135 |
@app.post("/summarize")
|
136 |
def summarize_text(request: TextRequest):
|
137 |
chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
|
@@ -252,11 +305,27 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
|
|
252 |
return None
|
253 |
|
254 |
mindmap_btn.click(
|
255 |
-
|
256 |
-
|
257 |
-
|
|
|
|
|
258 |
)
|
259 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
260 |
if __name__ == "__main__":
|
261 |
iface.launch(
|
262 |
server_name="0.0.0.0",
|
|
|
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)
|
|
|
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="300", # 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)]
|
|
|
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(
|
331 |
server_name="0.0.0.0",
|
space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/app.py
CHANGED
@@ -38,7 +38,7 @@ def wrap_label(label, max_length=15):
|
|
38 |
|
39 |
return "\\n".join(lines)
|
40 |
def generate_high_res_mindmap(text):
|
41 |
-
"""Generate mind map
|
42 |
try:
|
43 |
# Verify we have entities to visualize
|
44 |
entities = extract_entities(text)
|
@@ -46,92 +46,145 @@ def generate_high_res_mindmap(text):
|
|
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 |
-
#
|
55 |
G = pgv.AGraph(
|
56 |
directed=True,
|
57 |
-
rankdir="TB",
|
58 |
bgcolor="white",
|
59 |
-
fontname="
|
60 |
-
splines="ortho"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
61 |
)
|
62 |
|
63 |
-
#
|
64 |
G.node_attr.update({
|
65 |
-
"fontsize": "
|
|
|
66 |
"shape": "box",
|
67 |
"style": "rounded,filled",
|
68 |
"fillcolor": "#E1F5FE",
|
69 |
"color": "#0288D1",
|
|
|
|
|
|
|
|
|
70 |
})
|
71 |
|
72 |
-
#
|
73 |
G.edge_attr.update({
|
74 |
-
"color": "#
|
75 |
-
"penwidth": "
|
|
|
|
|
|
|
|
|
76 |
})
|
77 |
|
78 |
-
# Add central node
|
79 |
-
G.add_node("DOCUMENT",
|
80 |
-
|
81 |
-
|
82 |
-
|
|
|
|
|
|
|
83 |
|
84 |
-
# Add entities with
|
85 |
max_categories = 5
|
86 |
-
max_entities =
|
87 |
|
88 |
for cat_idx, (category, values) in enumerate(entities.items()):
|
89 |
if cat_idx >= max_categories:
|
90 |
break
|
91 |
|
|
|
92 |
cat_node = f"CAT_{cat_idx}"
|
93 |
-
G.add_node(cat_node,
|
94 |
-
|
|
|
|
|
|
|
95 |
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
G.add_edge(cat_node, ent_node)
|
100 |
|
101 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
102 |
for engine in ['dot', 'neato', 'sfdp']:
|
103 |
try:
|
104 |
-
G.draw(output_path,
|
105 |
-
|
106 |
-
|
|
|
107 |
print(f"Successfully generated with {engine}")
|
108 |
-
|
|
|
|
|
|
|
|
|
109 |
except Exception as e:
|
110 |
print(f"Layout engine {engine} failed: {str(e)}")
|
111 |
continue
|
112 |
-
else:
|
113 |
-
raise RuntimeError("All layout engines failed")
|
114 |
|
115 |
-
|
116 |
-
if not os.path.exists(output_path):
|
117 |
-
raise FileNotFoundError("Mind map file was not generated")
|
118 |
-
|
119 |
-
return output_path
|
120 |
|
121 |
except Exception as e:
|
122 |
print(f"Mind map generation failed: {str(e)}")
|
123 |
-
#
|
124 |
-
|
125 |
-
if not os.path.exists(placeholder_path):
|
126 |
-
# Create simple placeholder
|
127 |
import matplotlib.pyplot as plt
|
128 |
-
|
129 |
-
|
130 |
-
|
|
|
131 |
plt.axis('off')
|
132 |
-
|
|
|
133 |
plt.close()
|
134 |
-
|
|
|
|
|
135 |
@app.post("/summarize")
|
136 |
def summarize_text(request: TextRequest):
|
137 |
chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
|
@@ -252,11 +305,27 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
|
|
252 |
return None
|
253 |
|
254 |
mindmap_btn.click(
|
255 |
-
|
256 |
-
|
257 |
-
|
|
|
|
|
258 |
)
|
259 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
260 |
if __name__ == "__main__":
|
261 |
iface.launch(
|
262 |
server_name="0.0.0.0",
|
|
|
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)
|
|
|
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="300", # 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)]
|
|
|
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(
|
331 |
server_name="0.0.0.0",
|
space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/app.py
CHANGED
@@ -38,7 +38,7 @@ def wrap_label(label, max_length=15):
|
|
38 |
|
39 |
return "\\n".join(lines)
|
40 |
def generate_high_res_mindmap(text):
|
41 |
-
"""Generate mind map
|
42 |
try:
|
43 |
# Verify we have entities to visualize
|
44 |
entities = extract_entities(text)
|
@@ -46,92 +46,145 @@ def generate_high_res_mindmap(text):
|
|
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 |
-
#
|
55 |
G = pgv.AGraph(
|
56 |
directed=True,
|
57 |
-
rankdir="TB",
|
58 |
bgcolor="white",
|
59 |
-
fontname="
|
60 |
-
splines="ortho"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
61 |
)
|
62 |
|
63 |
-
#
|
64 |
G.node_attr.update({
|
65 |
-
"fontsize": "
|
|
|
66 |
"shape": "box",
|
67 |
"style": "rounded,filled",
|
68 |
"fillcolor": "#E1F5FE",
|
69 |
"color": "#0288D1",
|
|
|
|
|
|
|
|
|
70 |
})
|
71 |
|
72 |
-
#
|
73 |
G.edge_attr.update({
|
74 |
-
"color": "#
|
75 |
-
"penwidth": "
|
|
|
|
|
|
|
|
|
76 |
})
|
77 |
|
78 |
-
# Add central node
|
79 |
-
G.add_node("DOCUMENT",
|
80 |
-
|
81 |
-
|
82 |
-
|
|
|
|
|
|
|
83 |
|
84 |
-
# Add entities with
|
85 |
max_categories = 5
|
86 |
-
max_entities =
|
87 |
|
88 |
for cat_idx, (category, values) in enumerate(entities.items()):
|
89 |
if cat_idx >= max_categories:
|
90 |
break
|
91 |
|
|
|
92 |
cat_node = f"CAT_{cat_idx}"
|
93 |
-
G.add_node(cat_node,
|
94 |
-
|
|
|
|
|
|
|
95 |
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
G.add_edge(cat_node, ent_node)
|
100 |
|
101 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
102 |
for engine in ['dot', 'neato', 'sfdp']:
|
103 |
try:
|
104 |
-
G.draw(output_path,
|
105 |
-
|
106 |
-
|
|
|
107 |
print(f"Successfully generated with {engine}")
|
108 |
-
|
|
|
|
|
|
|
|
|
109 |
except Exception as e:
|
110 |
print(f"Layout engine {engine} failed: {str(e)}")
|
111 |
continue
|
112 |
-
else:
|
113 |
-
raise RuntimeError("All layout engines failed")
|
114 |
|
115 |
-
|
116 |
-
if not os.path.exists(output_path):
|
117 |
-
raise FileNotFoundError("Mind map file was not generated")
|
118 |
-
|
119 |
-
return output_path
|
120 |
|
121 |
except Exception as e:
|
122 |
print(f"Mind map generation failed: {str(e)}")
|
123 |
-
#
|
124 |
-
|
125 |
-
if not os.path.exists(placeholder_path):
|
126 |
-
# Create simple placeholder
|
127 |
import matplotlib.pyplot as plt
|
128 |
-
|
129 |
-
|
130 |
-
|
|
|
131 |
plt.axis('off')
|
132 |
-
|
|
|
133 |
plt.close()
|
134 |
-
|
|
|
|
|
135 |
@app.post("/summarize")
|
136 |
def summarize_text(request: TextRequest):
|
137 |
chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
|
@@ -252,11 +305,27 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
|
|
252 |
return None
|
253 |
|
254 |
mindmap_btn.click(
|
255 |
-
|
256 |
-
|
257 |
-
|
|
|
|
|
258 |
)
|
259 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
260 |
if __name__ == "__main__":
|
261 |
iface.launch(
|
262 |
server_name="0.0.0.0",
|
|
|
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)
|
|
|
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="300", # 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)]
|
|
|
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(
|
331 |
server_name="0.0.0.0",
|
space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/app.py
CHANGED
@@ -38,7 +38,7 @@ def wrap_label(label, max_length=15):
|
|
38 |
|
39 |
return "\\n".join(lines)
|
40 |
def generate_high_res_mindmap(text):
|
41 |
-
"""Generate mind map
|
42 |
try:
|
43 |
# Verify we have entities to visualize
|
44 |
entities = extract_entities(text)
|
@@ -46,92 +46,145 @@ def generate_high_res_mindmap(text):
|
|
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 |
-
#
|
55 |
G = pgv.AGraph(
|
56 |
directed=True,
|
57 |
-
rankdir="TB",
|
58 |
bgcolor="white",
|
59 |
-
fontname="
|
60 |
-
splines="ortho"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
61 |
)
|
62 |
|
63 |
-
#
|
64 |
G.node_attr.update({
|
65 |
-
"fontsize": "
|
|
|
66 |
"shape": "box",
|
67 |
"style": "rounded,filled",
|
68 |
"fillcolor": "#E1F5FE",
|
69 |
"color": "#0288D1",
|
|
|
|
|
|
|
|
|
70 |
})
|
71 |
|
72 |
-
#
|
73 |
G.edge_attr.update({
|
74 |
-
"color": "#
|
75 |
-
"penwidth": "
|
|
|
|
|
|
|
|
|
76 |
})
|
77 |
|
78 |
-
# Add central node
|
79 |
-
G.add_node("DOCUMENT",
|
80 |
-
|
81 |
-
|
82 |
-
|
|
|
|
|
|
|
83 |
|
84 |
-
# Add entities with
|
85 |
max_categories = 5
|
86 |
-
max_entities =
|
87 |
|
88 |
for cat_idx, (category, values) in enumerate(entities.items()):
|
89 |
if cat_idx >= max_categories:
|
90 |
break
|
91 |
|
|
|
92 |
cat_node = f"CAT_{cat_idx}"
|
93 |
-
G.add_node(cat_node,
|
94 |
-
|
|
|
|
|
|
|
95 |
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
G.add_edge(cat_node, ent_node)
|
100 |
|
101 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
102 |
for engine in ['dot', 'neato', 'sfdp']:
|
103 |
try:
|
104 |
-
G.draw(output_path,
|
105 |
-
|
106 |
-
|
|
|
107 |
print(f"Successfully generated with {engine}")
|
108 |
-
|
|
|
|
|
|
|
|
|
109 |
except Exception as e:
|
110 |
print(f"Layout engine {engine} failed: {str(e)}")
|
111 |
continue
|
112 |
-
else:
|
113 |
-
raise RuntimeError("All layout engines failed")
|
114 |
|
115 |
-
|
116 |
-
if not os.path.exists(output_path):
|
117 |
-
raise FileNotFoundError("Mind map file was not generated")
|
118 |
-
|
119 |
-
return output_path
|
120 |
|
121 |
except Exception as e:
|
122 |
print(f"Mind map generation failed: {str(e)}")
|
123 |
-
#
|
124 |
-
|
125 |
-
if not os.path.exists(placeholder_path):
|
126 |
-
# Create simple placeholder
|
127 |
import matplotlib.pyplot as plt
|
128 |
-
|
129 |
-
|
130 |
-
|
|
|
131 |
plt.axis('off')
|
132 |
-
|
|
|
133 |
plt.close()
|
134 |
-
|
|
|
|
|
135 |
@app.post("/summarize")
|
136 |
def summarize_text(request: TextRequest):
|
137 |
chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
|
@@ -252,11 +305,27 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
|
|
252 |
return None
|
253 |
|
254 |
mindmap_btn.click(
|
255 |
-
|
256 |
-
|
257 |
-
|
|
|
|
|
258 |
)
|
259 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
260 |
if __name__ == "__main__":
|
261 |
iface.launch(
|
262 |
server_name="0.0.0.0",
|
|
|
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)
|
|
|
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="300", # 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)]
|
|
|
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(
|
331 |
server_name="0.0.0.0",
|
space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/app.py
CHANGED
@@ -38,7 +38,7 @@ def wrap_label(label, max_length=15):
|
|
38 |
|
39 |
return "\\n".join(lines)
|
40 |
def generate_high_res_mindmap(text):
|
41 |
-
"""Generate mind map
|
42 |
try:
|
43 |
# Verify we have entities to visualize
|
44 |
entities = extract_entities(text)
|
@@ -46,92 +46,145 @@ def generate_high_res_mindmap(text):
|
|
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 |
-
#
|
55 |
G = pgv.AGraph(
|
56 |
directed=True,
|
57 |
-
rankdir="TB",
|
58 |
bgcolor="white",
|
59 |
-
fontname="
|
60 |
-
splines="ortho"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
61 |
)
|
62 |
|
63 |
-
#
|
64 |
G.node_attr.update({
|
65 |
-
"fontsize": "
|
|
|
66 |
"shape": "box",
|
67 |
"style": "rounded,filled",
|
68 |
"fillcolor": "#E1F5FE",
|
69 |
"color": "#0288D1",
|
|
|
|
|
|
|
|
|
70 |
})
|
71 |
|
72 |
-
#
|
73 |
G.edge_attr.update({
|
74 |
-
"color": "#
|
75 |
-
"penwidth": "
|
|
|
|
|
|
|
|
|
76 |
})
|
77 |
|
78 |
-
# Add central node
|
79 |
-
G.add_node("DOCUMENT",
|
80 |
-
|
81 |
-
|
82 |
-
|
|
|
|
|
|
|
83 |
|
84 |
-
# Add entities with
|
85 |
max_categories = 5
|
86 |
-
max_entities =
|
87 |
|
88 |
for cat_idx, (category, values) in enumerate(entities.items()):
|
89 |
if cat_idx >= max_categories:
|
90 |
break
|
91 |
|
|
|
92 |
cat_node = f"CAT_{cat_idx}"
|
93 |
-
G.add_node(cat_node,
|
94 |
-
|
|
|
|
|
|
|
95 |
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
G.add_edge(cat_node, ent_node)
|
100 |
|
101 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
102 |
for engine in ['dot', 'neato', 'sfdp']:
|
103 |
try:
|
104 |
-
G.draw(output_path,
|
105 |
-
|
106 |
-
|
|
|
107 |
print(f"Successfully generated with {engine}")
|
108 |
-
|
|
|
|
|
|
|
|
|
109 |
except Exception as e:
|
110 |
print(f"Layout engine {engine} failed: {str(e)}")
|
111 |
continue
|
112 |
-
else:
|
113 |
-
raise RuntimeError("All layout engines failed")
|
114 |
|
115 |
-
|
116 |
-
if not os.path.exists(output_path):
|
117 |
-
raise FileNotFoundError("Mind map file was not generated")
|
118 |
-
|
119 |
-
return output_path
|
120 |
|
121 |
except Exception as e:
|
122 |
print(f"Mind map generation failed: {str(e)}")
|
123 |
-
#
|
124 |
-
|
125 |
-
if not os.path.exists(placeholder_path):
|
126 |
-
# Create simple placeholder
|
127 |
import matplotlib.pyplot as plt
|
128 |
-
|
129 |
-
|
130 |
-
|
|
|
131 |
plt.axis('off')
|
132 |
-
|
|
|
133 |
plt.close()
|
134 |
-
|
|
|
|
|
135 |
@app.post("/summarize")
|
136 |
def summarize_text(request: TextRequest):
|
137 |
chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
|
@@ -252,11 +305,27 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
|
|
252 |
return None
|
253 |
|
254 |
mindmap_btn.click(
|
255 |
-
|
256 |
-
|
257 |
-
|
|
|
|
|
258 |
)
|
259 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
260 |
if __name__ == "__main__":
|
261 |
iface.launch(
|
262 |
server_name="0.0.0.0",
|
|
|
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)
|
|
|
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="300", # 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)]
|
|
|
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(
|
331 |
server_name="0.0.0.0",
|
space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/app.py
CHANGED
@@ -38,7 +38,7 @@ def wrap_label(label, max_length=15):
|
|
38 |
|
39 |
return "\\n".join(lines)
|
40 |
def generate_high_res_mindmap(text):
|
41 |
-
"""Generate mind map
|
42 |
try:
|
43 |
# Verify we have entities to visualize
|
44 |
entities = extract_entities(text)
|
@@ -46,92 +46,145 @@ def generate_high_res_mindmap(text):
|
|
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 |
-
#
|
55 |
G = pgv.AGraph(
|
56 |
directed=True,
|
57 |
-
rankdir="TB",
|
58 |
bgcolor="white",
|
59 |
-
fontname="
|
60 |
-
splines="ortho"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
61 |
)
|
62 |
|
63 |
-
#
|
64 |
G.node_attr.update({
|
65 |
-
"fontsize": "
|
|
|
66 |
"shape": "box",
|
67 |
"style": "rounded,filled",
|
68 |
"fillcolor": "#E1F5FE",
|
69 |
"color": "#0288D1",
|
|
|
|
|
|
|
|
|
70 |
})
|
71 |
|
72 |
-
#
|
73 |
G.edge_attr.update({
|
74 |
-
"color": "#
|
75 |
-
"penwidth": "
|
|
|
|
|
|
|
|
|
76 |
})
|
77 |
|
78 |
-
# Add central node
|
79 |
-
G.add_node("DOCUMENT",
|
80 |
-
|
81 |
-
|
82 |
-
|
|
|
|
|
|
|
83 |
|
84 |
-
# Add entities with
|
85 |
max_categories = 5
|
86 |
-
max_entities =
|
87 |
|
88 |
for cat_idx, (category, values) in enumerate(entities.items()):
|
89 |
if cat_idx >= max_categories:
|
90 |
break
|
91 |
|
|
|
92 |
cat_node = f"CAT_{cat_idx}"
|
93 |
-
G.add_node(cat_node,
|
94 |
-
|
|
|
|
|
|
|
95 |
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
G.add_edge(cat_node, ent_node)
|
100 |
|
101 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
102 |
for engine in ['dot', 'neato', 'sfdp']:
|
103 |
try:
|
104 |
-
G.draw(output_path,
|
105 |
-
|
106 |
-
|
|
|
107 |
print(f"Successfully generated with {engine}")
|
108 |
-
|
|
|
|
|
|
|
|
|
109 |
except Exception as e:
|
110 |
print(f"Layout engine {engine} failed: {str(e)}")
|
111 |
continue
|
112 |
-
else:
|
113 |
-
raise RuntimeError("All layout engines failed")
|
114 |
|
115 |
-
|
116 |
-
if not os.path.exists(output_path):
|
117 |
-
raise FileNotFoundError("Mind map file was not generated")
|
118 |
-
|
119 |
-
return output_path
|
120 |
|
121 |
except Exception as e:
|
122 |
print(f"Mind map generation failed: {str(e)}")
|
123 |
-
#
|
124 |
-
|
125 |
-
if not os.path.exists(placeholder_path):
|
126 |
-
# Create simple placeholder
|
127 |
import matplotlib.pyplot as plt
|
128 |
-
|
129 |
-
|
130 |
-
|
|
|
131 |
plt.axis('off')
|
132 |
-
|
|
|
133 |
plt.close()
|
134 |
-
|
|
|
|
|
135 |
@app.post("/summarize")
|
136 |
def summarize_text(request: TextRequest):
|
137 |
chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
|
@@ -252,11 +305,27 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
|
|
252 |
return None
|
253 |
|
254 |
mindmap_btn.click(
|
255 |
-
|
256 |
-
|
257 |
-
|
|
|
|
|
258 |
)
|
259 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
260 |
if __name__ == "__main__":
|
261 |
iface.launch(
|
262 |
server_name="0.0.0.0",
|
|
|
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)
|
|
|
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="300", # 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)]
|
|
|
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(
|
331 |
server_name="0.0.0.0",
|
space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/app.py
CHANGED
@@ -38,7 +38,7 @@ def wrap_label(label, max_length=15):
|
|
38 |
|
39 |
return "\\n".join(lines)
|
40 |
def generate_high_res_mindmap(text):
|
41 |
-
"""Generate mind map
|
42 |
try:
|
43 |
# Verify we have entities to visualize
|
44 |
entities = extract_entities(text)
|
@@ -46,92 +46,145 @@ def generate_high_res_mindmap(text):
|
|
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 |
-
#
|
55 |
G = pgv.AGraph(
|
56 |
directed=True,
|
57 |
-
rankdir="TB",
|
58 |
bgcolor="white",
|
59 |
-
fontname="
|
60 |
-
splines="ortho"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
61 |
)
|
62 |
|
63 |
-
#
|
64 |
G.node_attr.update({
|
65 |
-
"fontsize": "
|
|
|
66 |
"shape": "box",
|
67 |
"style": "rounded,filled",
|
68 |
"fillcolor": "#E1F5FE",
|
69 |
"color": "#0288D1",
|
|
|
|
|
|
|
|
|
70 |
})
|
71 |
|
72 |
-
#
|
73 |
G.edge_attr.update({
|
74 |
-
"color": "#
|
75 |
-
"penwidth": "
|
|
|
|
|
|
|
|
|
76 |
})
|
77 |
|
78 |
-
# Add central node
|
79 |
-
G.add_node("DOCUMENT",
|
80 |
-
|
81 |
-
|
82 |
-
|
|
|
|
|
|
|
83 |
|
84 |
-
# Add entities with
|
85 |
max_categories = 5
|
86 |
-
max_entities =
|
87 |
|
88 |
for cat_idx, (category, values) in enumerate(entities.items()):
|
89 |
if cat_idx >= max_categories:
|
90 |
break
|
91 |
|
|
|
92 |
cat_node = f"CAT_{cat_idx}"
|
93 |
-
G.add_node(cat_node,
|
94 |
-
|
|
|
|
|
|
|
95 |
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
G.add_edge(cat_node, ent_node)
|
100 |
|
101 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
102 |
for engine in ['dot', 'neato', 'sfdp']:
|
103 |
try:
|
104 |
-
G.draw(output_path,
|
105 |
-
|
106 |
-
|
|
|
107 |
print(f"Successfully generated with {engine}")
|
108 |
-
|
|
|
|
|
|
|
|
|
109 |
except Exception as e:
|
110 |
print(f"Layout engine {engine} failed: {str(e)}")
|
111 |
continue
|
112 |
-
else:
|
113 |
-
raise RuntimeError("All layout engines failed")
|
114 |
|
115 |
-
|
116 |
-
if not os.path.exists(output_path):
|
117 |
-
raise FileNotFoundError("Mind map file was not generated")
|
118 |
-
|
119 |
-
return output_path
|
120 |
|
121 |
except Exception as e:
|
122 |
print(f"Mind map generation failed: {str(e)}")
|
123 |
-
#
|
124 |
-
|
125 |
-
if not os.path.exists(placeholder_path):
|
126 |
-
# Create simple placeholder
|
127 |
import matplotlib.pyplot as plt
|
128 |
-
|
129 |
-
|
130 |
-
|
|
|
131 |
plt.axis('off')
|
132 |
-
|
|
|
133 |
plt.close()
|
134 |
-
|
|
|
|
|
135 |
@app.post("/summarize")
|
136 |
def summarize_text(request: TextRequest):
|
137 |
chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
|
@@ -252,11 +305,27 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
|
|
252 |
return None
|
253 |
|
254 |
mindmap_btn.click(
|
255 |
-
|
256 |
-
|
257 |
-
|
|
|
|
|
258 |
)
|
259 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
260 |
if __name__ == "__main__":
|
261 |
iface.launch(
|
262 |
server_name="0.0.0.0",
|
|
|
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)
|
|
|
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="300", # 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)]
|
|
|
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(
|
331 |
server_name="0.0.0.0",
|
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
@@ -38,7 +38,7 @@ def wrap_label(label, max_length=15):
|
|
38 |
|
39 |
return "\\n".join(lines)
|
40 |
def generate_high_res_mindmap(text):
|
41 |
-
"""Generate mind map
|
42 |
try:
|
43 |
# Verify we have entities to visualize
|
44 |
entities = extract_entities(text)
|
@@ -46,92 +46,145 @@ def generate_high_res_mindmap(text):
|
|
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 |
-
#
|
55 |
G = pgv.AGraph(
|
56 |
directed=True,
|
57 |
-
rankdir="TB",
|
58 |
bgcolor="white",
|
59 |
-
fontname="
|
60 |
-
splines="ortho"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
61 |
)
|
62 |
|
63 |
-
#
|
64 |
G.node_attr.update({
|
65 |
-
"fontsize": "
|
|
|
66 |
"shape": "box",
|
67 |
"style": "rounded,filled",
|
68 |
"fillcolor": "#E1F5FE",
|
69 |
"color": "#0288D1",
|
|
|
|
|
|
|
|
|
70 |
})
|
71 |
|
72 |
-
#
|
73 |
G.edge_attr.update({
|
74 |
-
"color": "#
|
75 |
-
"penwidth": "
|
|
|
|
|
|
|
|
|
76 |
})
|
77 |
|
78 |
-
# Add central node
|
79 |
-
G.add_node("DOCUMENT",
|
80 |
-
|
81 |
-
|
82 |
-
|
|
|
|
|
|
|
83 |
|
84 |
-
# Add entities with
|
85 |
max_categories = 5
|
86 |
-
max_entities =
|
87 |
|
88 |
for cat_idx, (category, values) in enumerate(entities.items()):
|
89 |
if cat_idx >= max_categories:
|
90 |
break
|
91 |
|
|
|
92 |
cat_node = f"CAT_{cat_idx}"
|
93 |
-
G.add_node(cat_node,
|
94 |
-
|
|
|
|
|
|
|
95 |
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
G.add_edge(cat_node, ent_node)
|
100 |
|
101 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
102 |
for engine in ['dot', 'neato', 'sfdp']:
|
103 |
try:
|
104 |
-
G.draw(output_path,
|
105 |
-
|
106 |
-
|
|
|
107 |
print(f"Successfully generated with {engine}")
|
108 |
-
|
|
|
|
|
|
|
|
|
109 |
except Exception as e:
|
110 |
print(f"Layout engine {engine} failed: {str(e)}")
|
111 |
continue
|
112 |
-
else:
|
113 |
-
raise RuntimeError("All layout engines failed")
|
114 |
|
115 |
-
|
116 |
-
if not os.path.exists(output_path):
|
117 |
-
raise FileNotFoundError("Mind map file was not generated")
|
118 |
-
|
119 |
-
return output_path
|
120 |
|
121 |
except Exception as e:
|
122 |
print(f"Mind map generation failed: {str(e)}")
|
123 |
-
#
|
124 |
-
|
125 |
-
if not os.path.exists(placeholder_path):
|
126 |
-
# Create simple placeholder
|
127 |
import matplotlib.pyplot as plt
|
128 |
-
|
129 |
-
|
130 |
-
|
|
|
131 |
plt.axis('off')
|
132 |
-
|
|
|
133 |
plt.close()
|
134 |
-
|
|
|
|
|
135 |
@app.post("/summarize")
|
136 |
def summarize_text(request: TextRequest):
|
137 |
chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
|
@@ -252,11 +305,27 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
|
|
252 |
return None
|
253 |
|
254 |
mindmap_btn.click(
|
255 |
-
|
256 |
-
|
257 |
-
|
|
|
|
|
258 |
)
|
259 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
260 |
if __name__ == "__main__":
|
261 |
iface.launch(
|
262 |
server_name="0.0.0.0",
|
|
|
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)
|
|
|
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="300", # 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)]
|
|
|
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(
|
331 |
server_name="0.0.0.0",
|
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
@@ -38,7 +38,7 @@ def wrap_label(label, max_length=15):
|
|
38 |
|
39 |
return "\\n".join(lines)
|
40 |
def generate_high_res_mindmap(text):
|
41 |
-
"""Generate mind map
|
42 |
try:
|
43 |
# Verify we have entities to visualize
|
44 |
entities = extract_entities(text)
|
@@ -46,92 +46,145 @@ def generate_high_res_mindmap(text):
|
|
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 |
-
#
|
55 |
G = pgv.AGraph(
|
56 |
directed=True,
|
57 |
-
rankdir="TB",
|
58 |
bgcolor="white",
|
59 |
-
fontname="
|
60 |
-
splines="ortho"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
61 |
)
|
62 |
|
63 |
-
#
|
64 |
G.node_attr.update({
|
65 |
-
"fontsize": "
|
|
|
66 |
"shape": "box",
|
67 |
"style": "rounded,filled",
|
68 |
"fillcolor": "#E1F5FE",
|
69 |
"color": "#0288D1",
|
|
|
|
|
|
|
|
|
70 |
})
|
71 |
|
72 |
-
#
|
73 |
G.edge_attr.update({
|
74 |
-
"color": "#
|
75 |
-
"penwidth": "
|
|
|
|
|
|
|
|
|
76 |
})
|
77 |
|
78 |
-
# Add central node
|
79 |
-
G.add_node("DOCUMENT",
|
80 |
-
|
81 |
-
|
82 |
-
|
|
|
|
|
|
|
83 |
|
84 |
-
# Add entities with
|
85 |
max_categories = 5
|
86 |
-
max_entities =
|
87 |
|
88 |
for cat_idx, (category, values) in enumerate(entities.items()):
|
89 |
if cat_idx >= max_categories:
|
90 |
break
|
91 |
|
|
|
92 |
cat_node = f"CAT_{cat_idx}"
|
93 |
-
G.add_node(cat_node,
|
94 |
-
|
|
|
|
|
|
|
95 |
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
G.add_edge(cat_node, ent_node)
|
100 |
|
101 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
102 |
for engine in ['dot', 'neato', 'sfdp']:
|
103 |
try:
|
104 |
-
G.draw(output_path,
|
105 |
-
|
106 |
-
|
|
|
107 |
print(f"Successfully generated with {engine}")
|
108 |
-
|
|
|
|
|
|
|
|
|
109 |
except Exception as e:
|
110 |
print(f"Layout engine {engine} failed: {str(e)}")
|
111 |
continue
|
112 |
-
else:
|
113 |
-
raise RuntimeError("All layout engines failed")
|
114 |
|
115 |
-
|
116 |
-
if not os.path.exists(output_path):
|
117 |
-
raise FileNotFoundError("Mind map file was not generated")
|
118 |
-
|
119 |
-
return output_path
|
120 |
|
121 |
except Exception as e:
|
122 |
print(f"Mind map generation failed: {str(e)}")
|
123 |
-
#
|
124 |
-
|
125 |
-
if not os.path.exists(placeholder_path):
|
126 |
-
# Create simple placeholder
|
127 |
import matplotlib.pyplot as plt
|
128 |
-
|
129 |
-
|
130 |
-
|
|
|
131 |
plt.axis('off')
|
132 |
-
|
|
|
133 |
plt.close()
|
134 |
-
|
|
|
|
|
135 |
@app.post("/summarize")
|
136 |
def summarize_text(request: TextRequest):
|
137 |
chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
|
@@ -252,11 +305,27 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
|
|
252 |
return None
|
253 |
|
254 |
mindmap_btn.click(
|
255 |
-
|
256 |
-
|
257 |
-
|
|
|
|
|
258 |
)
|
259 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
260 |
if __name__ == "__main__":
|
261 |
iface.launch(
|
262 |
server_name="0.0.0.0",
|
|
|
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)
|
|
|
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="300", # 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)]
|
|
|
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(
|
331 |
server_name="0.0.0.0",
|
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
@@ -38,7 +38,7 @@ def wrap_label(label, max_length=15):
|
|
38 |
|
39 |
return "\\n".join(lines)
|
40 |
def generate_high_res_mindmap(text):
|
41 |
-
"""Generate mind map
|
42 |
try:
|
43 |
# Verify we have entities to visualize
|
44 |
entities = extract_entities(text)
|
@@ -46,92 +46,145 @@ def generate_high_res_mindmap(text):
|
|
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 |
-
#
|
55 |
G = pgv.AGraph(
|
56 |
directed=True,
|
57 |
-
rankdir="TB",
|
58 |
bgcolor="white",
|
59 |
-
fontname="
|
60 |
-
splines="ortho"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
61 |
)
|
62 |
|
63 |
-
#
|
64 |
G.node_attr.update({
|
65 |
-
"fontsize": "
|
|
|
66 |
"shape": "box",
|
67 |
"style": "rounded,filled",
|
68 |
"fillcolor": "#E1F5FE",
|
69 |
"color": "#0288D1",
|
|
|
|
|
|
|
|
|
70 |
})
|
71 |
|
72 |
-
#
|
73 |
G.edge_attr.update({
|
74 |
-
"color": "#
|
75 |
-
"penwidth": "
|
|
|
|
|
|
|
|
|
76 |
})
|
77 |
|
78 |
-
# Add central node
|
79 |
-
G.add_node("DOCUMENT",
|
80 |
-
|
81 |
-
|
82 |
-
|
|
|
|
|
|
|
83 |
|
84 |
-
# Add entities with
|
85 |
max_categories = 5
|
86 |
-
max_entities =
|
87 |
|
88 |
for cat_idx, (category, values) in enumerate(entities.items()):
|
89 |
if cat_idx >= max_categories:
|
90 |
break
|
91 |
|
|
|
92 |
cat_node = f"CAT_{cat_idx}"
|
93 |
-
G.add_node(cat_node,
|
94 |
-
|
|
|
|
|
|
|
95 |
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
G.add_edge(cat_node, ent_node)
|
100 |
|
101 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
102 |
for engine in ['dot', 'neato', 'sfdp']:
|
103 |
try:
|
104 |
-
G.draw(output_path,
|
105 |
-
|
106 |
-
|
|
|
107 |
print(f"Successfully generated with {engine}")
|
108 |
-
|
|
|
|
|
|
|
|
|
109 |
except Exception as e:
|
110 |
print(f"Layout engine {engine} failed: {str(e)}")
|
111 |
continue
|
112 |
-
else:
|
113 |
-
raise RuntimeError("All layout engines failed")
|
114 |
|
115 |
-
|
116 |
-
if not os.path.exists(output_path):
|
117 |
-
raise FileNotFoundError("Mind map file was not generated")
|
118 |
-
|
119 |
-
return output_path
|
120 |
|
121 |
except Exception as e:
|
122 |
print(f"Mind map generation failed: {str(e)}")
|
123 |
-
#
|
124 |
-
|
125 |
-
if not os.path.exists(placeholder_path):
|
126 |
-
# Create simple placeholder
|
127 |
import matplotlib.pyplot as plt
|
128 |
-
|
129 |
-
|
130 |
-
|
|
|
131 |
plt.axis('off')
|
132 |
-
|
|
|
133 |
plt.close()
|
134 |
-
|
|
|
|
|
135 |
@app.post("/summarize")
|
136 |
def summarize_text(request: TextRequest):
|
137 |
chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
|
@@ -252,11 +305,27 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
|
|
252 |
return None
|
253 |
|
254 |
mindmap_btn.click(
|
255 |
-
|
256 |
-
|
257 |
-
|
|
|
|
|
258 |
)
|
259 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
260 |
if __name__ == "__main__":
|
261 |
iface.launch(
|
262 |
server_name="0.0.0.0",
|
|
|
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)
|
|
|
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="300", # 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)]
|
|
|
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(
|
331 |
server_name="0.0.0.0",
|
space/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
@@ -38,7 +38,7 @@ def wrap_label(label, max_length=15):
|
|
38 |
|
39 |
return "\\n".join(lines)
|
40 |
def generate_high_res_mindmap(text):
|
41 |
-
"""Generate mind map
|
42 |
try:
|
43 |
# Verify we have entities to visualize
|
44 |
entities = extract_entities(text)
|
@@ -46,92 +46,145 @@ def generate_high_res_mindmap(text):
|
|
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 |
-
#
|
55 |
G = pgv.AGraph(
|
56 |
directed=True,
|
57 |
-
rankdir="TB",
|
58 |
bgcolor="white",
|
59 |
-
fontname="
|
60 |
-
splines="ortho"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
61 |
)
|
62 |
|
63 |
-
#
|
64 |
G.node_attr.update({
|
65 |
-
"fontsize": "
|
|
|
66 |
"shape": "box",
|
67 |
"style": "rounded,filled",
|
68 |
"fillcolor": "#E1F5FE",
|
69 |
"color": "#0288D1",
|
|
|
|
|
|
|
|
|
70 |
})
|
71 |
|
72 |
-
#
|
73 |
G.edge_attr.update({
|
74 |
-
"color": "#
|
75 |
-
"penwidth": "
|
|
|
|
|
|
|
|
|
76 |
})
|
77 |
|
78 |
-
# Add central node
|
79 |
-
G.add_node("DOCUMENT",
|
80 |
-
|
81 |
-
|
82 |
-
|
|
|
|
|
|
|
83 |
|
84 |
-
# Add entities with
|
85 |
max_categories = 5
|
86 |
-
max_entities =
|
87 |
|
88 |
for cat_idx, (category, values) in enumerate(entities.items()):
|
89 |
if cat_idx >= max_categories:
|
90 |
break
|
91 |
|
|
|
92 |
cat_node = f"CAT_{cat_idx}"
|
93 |
-
G.add_node(cat_node,
|
94 |
-
|
|
|
|
|
|
|
95 |
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
G.add_edge(cat_node, ent_node)
|
100 |
|
101 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
102 |
for engine in ['dot', 'neato', 'sfdp']:
|
103 |
try:
|
104 |
-
G.draw(output_path,
|
105 |
-
|
106 |
-
|
|
|
107 |
print(f"Successfully generated with {engine}")
|
108 |
-
|
|
|
|
|
|
|
|
|
109 |
except Exception as e:
|
110 |
print(f"Layout engine {engine} failed: {str(e)}")
|
111 |
continue
|
112 |
-
else:
|
113 |
-
raise RuntimeError("All layout engines failed")
|
114 |
|
115 |
-
|
116 |
-
if not os.path.exists(output_path):
|
117 |
-
raise FileNotFoundError("Mind map file was not generated")
|
118 |
-
|
119 |
-
return output_path
|
120 |
|
121 |
except Exception as e:
|
122 |
print(f"Mind map generation failed: {str(e)}")
|
123 |
-
#
|
124 |
-
|
125 |
-
if not os.path.exists(placeholder_path):
|
126 |
-
# Create simple placeholder
|
127 |
import matplotlib.pyplot as plt
|
128 |
-
|
129 |
-
|
130 |
-
|
|
|
131 |
plt.axis('off')
|
132 |
-
|
|
|
133 |
plt.close()
|
134 |
-
|
|
|
|
|
135 |
@app.post("/summarize")
|
136 |
def summarize_text(request: TextRequest):
|
137 |
chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
|
@@ -252,11 +305,27 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
|
|
252 |
return None
|
253 |
|
254 |
mindmap_btn.click(
|
255 |
-
|
256 |
-
|
257 |
-
|
|
|
|
|
258 |
)
|
259 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
260 |
if __name__ == "__main__":
|
261 |
iface.launch(
|
262 |
server_name="0.0.0.0",
|
|
|
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)
|
|
|
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="300", # 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)]
|
|
|
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(
|
331 |
server_name="0.0.0.0",
|
space/space/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
@@ -38,7 +38,7 @@ def wrap_label(label, max_length=15):
|
|
38 |
|
39 |
return "\\n".join(lines)
|
40 |
def generate_high_res_mindmap(text):
|
41 |
-
"""Generate mind map
|
42 |
try:
|
43 |
# Verify we have entities to visualize
|
44 |
entities = extract_entities(text)
|
@@ -46,92 +46,145 @@ def generate_high_res_mindmap(text):
|
|
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 |
-
#
|
55 |
G = pgv.AGraph(
|
56 |
directed=True,
|
57 |
-
rankdir="TB",
|
58 |
bgcolor="white",
|
59 |
-
fontname="
|
60 |
-
splines="ortho"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
61 |
)
|
62 |
|
63 |
-
#
|
64 |
G.node_attr.update({
|
65 |
-
"fontsize": "
|
|
|
66 |
"shape": "box",
|
67 |
"style": "rounded,filled",
|
68 |
"fillcolor": "#E1F5FE",
|
69 |
"color": "#0288D1",
|
|
|
|
|
|
|
|
|
70 |
})
|
71 |
|
72 |
-
#
|
73 |
G.edge_attr.update({
|
74 |
-
"color": "#
|
75 |
-
"penwidth": "
|
|
|
|
|
|
|
|
|
76 |
})
|
77 |
|
78 |
-
# Add central node
|
79 |
-
G.add_node("DOCUMENT",
|
80 |
-
|
81 |
-
|
82 |
-
|
|
|
|
|
|
|
83 |
|
84 |
-
# Add entities with
|
85 |
max_categories = 5
|
86 |
-
max_entities =
|
87 |
|
88 |
for cat_idx, (category, values) in enumerate(entities.items()):
|
89 |
if cat_idx >= max_categories:
|
90 |
break
|
91 |
|
|
|
92 |
cat_node = f"CAT_{cat_idx}"
|
93 |
-
G.add_node(cat_node,
|
94 |
-
|
|
|
|
|
|
|
95 |
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
G.add_edge(cat_node, ent_node)
|
100 |
|
101 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
102 |
for engine in ['dot', 'neato', 'sfdp']:
|
103 |
try:
|
104 |
-
G.draw(output_path,
|
105 |
-
|
106 |
-
|
|
|
107 |
print(f"Successfully generated with {engine}")
|
108 |
-
|
|
|
|
|
|
|
|
|
109 |
except Exception as e:
|
110 |
print(f"Layout engine {engine} failed: {str(e)}")
|
111 |
continue
|
112 |
-
else:
|
113 |
-
raise RuntimeError("All layout engines failed")
|
114 |
|
115 |
-
|
116 |
-
if not os.path.exists(output_path):
|
117 |
-
raise FileNotFoundError("Mind map file was not generated")
|
118 |
-
|
119 |
-
return output_path
|
120 |
|
121 |
except Exception as e:
|
122 |
print(f"Mind map generation failed: {str(e)}")
|
123 |
-
#
|
124 |
-
|
125 |
-
if not os.path.exists(placeholder_path):
|
126 |
-
# Create simple placeholder
|
127 |
import matplotlib.pyplot as plt
|
128 |
-
|
129 |
-
|
130 |
-
|
|
|
131 |
plt.axis('off')
|
132 |
-
|
|
|
133 |
plt.close()
|
134 |
-
|
|
|
|
|
135 |
@app.post("/summarize")
|
136 |
def summarize_text(request: TextRequest):
|
137 |
chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
|
@@ -252,11 +305,27 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
|
|
252 |
return None
|
253 |
|
254 |
mindmap_btn.click(
|
255 |
-
|
256 |
-
|
257 |
-
|
|
|
|
|
258 |
)
|
259 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
260 |
if __name__ == "__main__":
|
261 |
iface.launch(
|
262 |
server_name="0.0.0.0",
|
|
|
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)
|
|
|
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="300", # 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)]
|
|
|
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(
|
331 |
server_name="0.0.0.0",
|
space/space/space/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
@@ -38,7 +38,7 @@ def wrap_label(label, max_length=15):
|
|
38 |
|
39 |
return "\\n".join(lines)
|
40 |
def generate_high_res_mindmap(text):
|
41 |
-
"""Generate mind map
|
42 |
try:
|
43 |
# Verify we have entities to visualize
|
44 |
entities = extract_entities(text)
|
@@ -46,92 +46,145 @@ def generate_high_res_mindmap(text):
|
|
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 |
-
#
|
55 |
G = pgv.AGraph(
|
56 |
directed=True,
|
57 |
-
rankdir="TB",
|
58 |
bgcolor="white",
|
59 |
-
fontname="
|
60 |
-
splines="ortho"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
61 |
)
|
62 |
|
63 |
-
#
|
64 |
G.node_attr.update({
|
65 |
-
"fontsize": "
|
|
|
66 |
"shape": "box",
|
67 |
"style": "rounded,filled",
|
68 |
"fillcolor": "#E1F5FE",
|
69 |
"color": "#0288D1",
|
|
|
|
|
|
|
|
|
70 |
})
|
71 |
|
72 |
-
#
|
73 |
G.edge_attr.update({
|
74 |
-
"color": "#
|
75 |
-
"penwidth": "
|
|
|
|
|
|
|
|
|
76 |
})
|
77 |
|
78 |
-
# Add central node
|
79 |
-
G.add_node("DOCUMENT",
|
80 |
-
|
81 |
-
|
82 |
-
|
|
|
|
|
|
|
83 |
|
84 |
-
# Add entities with
|
85 |
max_categories = 5
|
86 |
-
max_entities =
|
87 |
|
88 |
for cat_idx, (category, values) in enumerate(entities.items()):
|
89 |
if cat_idx >= max_categories:
|
90 |
break
|
91 |
|
|
|
92 |
cat_node = f"CAT_{cat_idx}"
|
93 |
-
G.add_node(cat_node,
|
94 |
-
|
|
|
|
|
|
|
95 |
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
G.add_edge(cat_node, ent_node)
|
100 |
|
101 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
102 |
for engine in ['dot', 'neato', 'sfdp']:
|
103 |
try:
|
104 |
-
G.draw(output_path,
|
105 |
-
|
106 |
-
|
|
|
107 |
print(f"Successfully generated with {engine}")
|
108 |
-
|
|
|
|
|
|
|
|
|
109 |
except Exception as e:
|
110 |
print(f"Layout engine {engine} failed: {str(e)}")
|
111 |
continue
|
112 |
-
else:
|
113 |
-
raise RuntimeError("All layout engines failed")
|
114 |
|
115 |
-
|
116 |
-
if not os.path.exists(output_path):
|
117 |
-
raise FileNotFoundError("Mind map file was not generated")
|
118 |
-
|
119 |
-
return output_path
|
120 |
|
121 |
except Exception as e:
|
122 |
print(f"Mind map generation failed: {str(e)}")
|
123 |
-
#
|
124 |
-
|
125 |
-
if not os.path.exists(placeholder_path):
|
126 |
-
# Create simple placeholder
|
127 |
import matplotlib.pyplot as plt
|
128 |
-
|
129 |
-
|
130 |
-
|
|
|
131 |
plt.axis('off')
|
132 |
-
|
|
|
133 |
plt.close()
|
134 |
-
|
|
|
|
|
135 |
@app.post("/summarize")
|
136 |
def summarize_text(request: TextRequest):
|
137 |
chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
|
@@ -252,11 +305,27 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
|
|
252 |
return None
|
253 |
|
254 |
mindmap_btn.click(
|
255 |
-
|
256 |
-
|
257 |
-
|
|
|
|
|
258 |
)
|
259 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
260 |
if __name__ == "__main__":
|
261 |
iface.launch(
|
262 |
server_name="0.0.0.0",
|
|
|
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)
|
|
|
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="300", # 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)]
|
|
|
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(
|
331 |
server_name="0.0.0.0",
|
space/space/space/space/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
@@ -38,7 +38,7 @@ def wrap_label(label, max_length=15):
|
|
38 |
|
39 |
return "\\n".join(lines)
|
40 |
def generate_high_res_mindmap(text):
|
41 |
-
"""Generate mind map
|
42 |
try:
|
43 |
# Verify we have entities to visualize
|
44 |
entities = extract_entities(text)
|
@@ -46,92 +46,145 @@ def generate_high_res_mindmap(text):
|
|
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 |
-
#
|
55 |
G = pgv.AGraph(
|
56 |
directed=True,
|
57 |
-
rankdir="TB",
|
58 |
bgcolor="white",
|
59 |
-
fontname="
|
60 |
-
splines="ortho"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
61 |
)
|
62 |
|
63 |
-
#
|
64 |
G.node_attr.update({
|
65 |
-
"fontsize": "
|
|
|
66 |
"shape": "box",
|
67 |
"style": "rounded,filled",
|
68 |
"fillcolor": "#E1F5FE",
|
69 |
"color": "#0288D1",
|
|
|
|
|
|
|
|
|
70 |
})
|
71 |
|
72 |
-
#
|
73 |
G.edge_attr.update({
|
74 |
-
"color": "#
|
75 |
-
"penwidth": "
|
|
|
|
|
|
|
|
|
76 |
})
|
77 |
|
78 |
-
# Add central node
|
79 |
-
G.add_node("DOCUMENT",
|
80 |
-
|
81 |
-
|
82 |
-
|
|
|
|
|
|
|
83 |
|
84 |
-
# Add entities with
|
85 |
max_categories = 5
|
86 |
-
max_entities =
|
87 |
|
88 |
for cat_idx, (category, values) in enumerate(entities.items()):
|
89 |
if cat_idx >= max_categories:
|
90 |
break
|
91 |
|
|
|
92 |
cat_node = f"CAT_{cat_idx}"
|
93 |
-
G.add_node(cat_node,
|
94 |
-
|
|
|
|
|
|
|
95 |
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
G.add_edge(cat_node, ent_node)
|
100 |
|
101 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
102 |
for engine in ['dot', 'neato', 'sfdp']:
|
103 |
try:
|
104 |
-
G.draw(output_path,
|
105 |
-
|
106 |
-
|
|
|
107 |
print(f"Successfully generated with {engine}")
|
108 |
-
|
|
|
|
|
|
|
|
|
109 |
except Exception as e:
|
110 |
print(f"Layout engine {engine} failed: {str(e)}")
|
111 |
continue
|
112 |
-
else:
|
113 |
-
raise RuntimeError("All layout engines failed")
|
114 |
|
115 |
-
|
116 |
-
if not os.path.exists(output_path):
|
117 |
-
raise FileNotFoundError("Mind map file was not generated")
|
118 |
-
|
119 |
-
return output_path
|
120 |
|
121 |
except Exception as e:
|
122 |
print(f"Mind map generation failed: {str(e)}")
|
123 |
-
#
|
124 |
-
|
125 |
-
if not os.path.exists(placeholder_path):
|
126 |
-
# Create simple placeholder
|
127 |
import matplotlib.pyplot as plt
|
128 |
-
|
129 |
-
|
130 |
-
|
|
|
131 |
plt.axis('off')
|
132 |
-
|
|
|
133 |
plt.close()
|
134 |
-
|
|
|
|
|
135 |
@app.post("/summarize")
|
136 |
def summarize_text(request: TextRequest):
|
137 |
chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
|
@@ -252,11 +305,27 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
|
|
252 |
return None
|
253 |
|
254 |
mindmap_btn.click(
|
255 |
-
|
256 |
-
|
257 |
-
|
|
|
|
|
258 |
)
|
259 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
260 |
if __name__ == "__main__":
|
261 |
iface.launch(
|
262 |
server_name="0.0.0.0",
|
|
|
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)
|
|
|
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="300", # 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)]
|
|
|
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(
|
331 |
server_name="0.0.0.0",
|
space/space/space/space/space/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
@@ -38,7 +38,7 @@ def wrap_label(label, max_length=15):
|
|
38 |
|
39 |
return "\\n".join(lines)
|
40 |
def generate_high_res_mindmap(text):
|
41 |
-
"""Generate mind map
|
42 |
try:
|
43 |
# Verify we have entities to visualize
|
44 |
entities = extract_entities(text)
|
@@ -46,92 +46,145 @@ def generate_high_res_mindmap(text):
|
|
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 |
-
#
|
55 |
G = pgv.AGraph(
|
56 |
directed=True,
|
57 |
-
rankdir="TB",
|
58 |
bgcolor="white",
|
59 |
-
fontname="
|
60 |
-
splines="ortho"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
61 |
)
|
62 |
|
63 |
-
#
|
64 |
G.node_attr.update({
|
65 |
-
"fontsize": "
|
|
|
66 |
"shape": "box",
|
67 |
"style": "rounded,filled",
|
68 |
"fillcolor": "#E1F5FE",
|
69 |
"color": "#0288D1",
|
|
|
|
|
|
|
|
|
70 |
})
|
71 |
|
72 |
-
#
|
73 |
G.edge_attr.update({
|
74 |
-
"color": "#
|
75 |
-
"penwidth": "
|
|
|
|
|
|
|
|
|
76 |
})
|
77 |
|
78 |
-
# Add central node
|
79 |
-
G.add_node("DOCUMENT",
|
80 |
-
|
81 |
-
|
82 |
-
|
|
|
|
|
|
|
83 |
|
84 |
-
# Add entities with
|
85 |
max_categories = 5
|
86 |
-
max_entities =
|
87 |
|
88 |
for cat_idx, (category, values) in enumerate(entities.items()):
|
89 |
if cat_idx >= max_categories:
|
90 |
break
|
91 |
|
|
|
92 |
cat_node = f"CAT_{cat_idx}"
|
93 |
-
G.add_node(cat_node,
|
94 |
-
|
|
|
|
|
|
|
95 |
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
G.add_edge(cat_node, ent_node)
|
100 |
|
101 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
102 |
for engine in ['dot', 'neato', 'sfdp']:
|
103 |
try:
|
104 |
-
G.draw(output_path,
|
105 |
-
|
106 |
-
|
|
|
107 |
print(f"Successfully generated with {engine}")
|
108 |
-
|
|
|
|
|
|
|
|
|
109 |
except Exception as e:
|
110 |
print(f"Layout engine {engine} failed: {str(e)}")
|
111 |
continue
|
112 |
-
else:
|
113 |
-
raise RuntimeError("All layout engines failed")
|
114 |
|
115 |
-
|
116 |
-
if not os.path.exists(output_path):
|
117 |
-
raise FileNotFoundError("Mind map file was not generated")
|
118 |
-
|
119 |
-
return output_path
|
120 |
|
121 |
except Exception as e:
|
122 |
print(f"Mind map generation failed: {str(e)}")
|
123 |
-
#
|
124 |
-
|
125 |
-
if not os.path.exists(placeholder_path):
|
126 |
-
# Create simple placeholder
|
127 |
import matplotlib.pyplot as plt
|
128 |
-
|
129 |
-
|
130 |
-
|
|
|
131 |
plt.axis('off')
|
132 |
-
|
|
|
133 |
plt.close()
|
134 |
-
|
|
|
|
|
135 |
@app.post("/summarize")
|
136 |
def summarize_text(request: TextRequest):
|
137 |
chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
|
@@ -252,11 +305,27 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
|
|
252 |
return None
|
253 |
|
254 |
mindmap_btn.click(
|
255 |
-
|
256 |
-
|
257 |
-
|
|
|
|
|
258 |
)
|
259 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
260 |
if __name__ == "__main__":
|
261 |
iface.launch(
|
262 |
server_name="0.0.0.0",
|
|
|
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)
|
|
|
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="300", # 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)]
|
|
|
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(
|
331 |
server_name="0.0.0.0",
|
space/space/space/space/space/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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
|
space/space/space/space/space/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-10064.md
ADDED
@@ -0,0 +1,149 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# SECRET
|
2 |
+
|
3 |
+
2025 RELEASE UNDER THE PRESIDENT JOHN F. KENNEDY ASSASSINATION RECORDS ACT OF 1992
|
4 |
+
|
5 |
+
OPERATOR: SEEGER, EDWA BADGE: KT283 DATE : 14 SEP 93
|
6 |
+
OFFICE : IMS/FABOSS PHONE: 047552 TIME : 15:24
|
7 |
+
ROOM : GC520HB PRINTER: T019 PAGE : 001
|
8 |
+
REQUESTER: HM877
|
9 |
+
DSN: SPET 21162 DOC DATE: 20 NOV 91 MHF#: 91-6320813
|
10 |
+
|
11 |
+
//
|
12 |
+
|
13 |
+
SECRET FRP:
|
14 |
+
STAFF
|
15 |
+
|
16 |
+
ACTION: SE/USSR/10-3 (752) INFO: C/ORMS, DOMDS, LIMITO, ODPD, SEDORECORD.
|
17 |
+
FILE, DDO-2, SE/RR-3 (9/W)
|
18 |
+
|
19 |
+
91 6320813 ASR PAGE 001 IN 6320813
|
20 |
+
TOR: 201455Z NOV 91 SPET 21162
|
21 |
+
|
22 |
+
SECRET 201454Z NOV 91 STAFF
|
23 |
+
|
24 |
+
CITE ST PETERSBURG 21162
|
25 |
+
|
26 |
+
TO: MOSCOW INFO DIRECTOR.
|
27 |
+
|
28 |
+
FOR: LIMIT SE/USSR/10 INFO SE/RR
|
29 |
+
|
30 |
+
SLUGS: WNINTEL GTDANCER
|
31 |
+
|
32 |
+
SUBJECT: KGB OFFICIAL NIKONOV
|
33 |
+
|
34 |
+
REF: NONE
|
35 |
+
|
36 |
+
TEXT:
|
37 |
+
|
38 |
+
1. ACTION REQUIRED: NONE.
|
39 |
+
|
40 |
+
2. DURING THE WEEK OF 3-9 NOVEMBER 1991, U.S. PROFESSOR
|
41 |
+
Ε.Β. ((SMITH)), HAD SEVERAL DISCUSSIONS IN MOSCOW WITH "SLAVA"
|
42 |
+
((NIKONOV)), WHO IS A LONGTIME FRI?ND AND NOW DEPUTY TO KGB
|
43 |
+
DIRECTOR ((BAKATIN)). THE PROFESSOR HAS KNOWN NIKONOV WELL
|
44 |
+
SINCE 1976. HE CURRENTLY IS INSTRUCTING ON A FULBRIGHT GRANT
|
45 |
+
AT ST PETERSBURG STATE UNIVERSITY UNTIL 22 DECEMBER 1991. SEE
|
46 |
+
PARA 7 FOR BIO ON THE PROFESSOR. DCOB STEVEN R. HEIBERG HAS
|
47 |
+
BEFRIENDED THE PROFESSOR, WHO WAS DINNER GUEST AT HEIBERG'S
|
48 |
+
HOME ON 10 NOVEMBER AND PROVIDED THE FOLLOWING INFO ON NIKONOV
|
49 |
+
AND HIS NEW KGB JOB.
|
50 |
+
|
51 |
+
3. NIKONOV IS THE GRANDSON OF FORMER SOVIET FOREIGN
|
52 |
+
MINISTER VYACHESLAV MOLOTOV. THE U.S. PROFESSOR TAUGHT NIKONOV
|
53 |
+
IN 1976 AT MOSCOW STATE UNIVERSITY WHILE A FULBRIGHT
|
54 |
+
PROFESSOR. NIKONOV WAS REGARDED AS EXTREMELY INTELLIGENT AND
|
55 |
+
CAPABLE BUT GAVE THE IMPRESSION THAT HE WAS AN IDEOLOGICAL
|
56 |
+
HARDLINER. THE PROFESSOR BELIEVED THAT HE WAS LIKELY TO BE A
|
57 |
+
RISING STAR IN THE SOVIET SYSTEM AND RECOMMENDED HIM FOR AN
|
58 |
+
IREX-SPONSORED VISIT TO THE U.S. AS EXPECTED, NIKONOV'S VIEWS
|
59 |
+
AND RHETORIC MODERATED VERY VISIBLY AFTER HIS FIRST DIRECT
|
60 |
+
EXPOSURE TO THE U.S. HE HAS HAD AT LEAST ONE ADDITIONAL
|
61 |
+
IREX-SPONSORED TRIP TO THE U.S. AND HAS SPENT PERIODS OF TIME
|
62 |
+
AS A PERSONAL GUEST AT THE HOME OF THE U.S. PROFESSOR IN
|
63 |
+
MARYLAND.
|
64 |
+
|
65 |
+
4. ΝΙΚΟΝNOV CAME TO WORK IN HIS POSITION AT THE KGB AS A
|
66 |
+
RESULT OF BEING A CLOSE FRIEND OF BAKATIN. DURING THE AUGUST
|
67 |
+
1991 COUP ATTEMPT NIKONOV SAID THAT HE REFUSED TO FOLLOW HIS
|
68 |
+
BOSS'S ORDER TO ACT IN ACCORDANCE WITH THE DECLARED STATE OF
|
69 |
+
EMERGENCY. HE WAS DISMISSED BY HIS BOSS (NFI) FROM THIS
|
70 |
+
POSITION AND CALLED BAKATIN TO SEEK ADVICE. BAKATIN SAID HE
|
71 |
+
WAS ALSO OPPOSING THE COUP AND WOULD LOOK OUT FOR NIKONOV ONCE
|
72 |
+
ORDER WAS RESTORED. SOON AFTER THE COUP BAKATIN CALLED HIM TO
|
73 |
+
ASK THAT HE ASSIST WITH RESTRUCTURING THE KGB. AFTER IT WAS
|
74 |
+
AGREED THAT NIKONOV COULD DECLINE TO ACCEPT TWO-STAR MILITARY
|
75 |
+
KGB RANK AND WORK IN THE JOB FOR AN EQUIVALENT CIVILIAN
|
76 |
+
COMPENSATION PACKAGE, HE CAME TO THE KGB AS BAKATIN'S DEPUTY.
|
77 |
+
NIKONOV SAID HIS FRIENDS WERE DELIGHTED THAT HE HAD DECLINED
|
78 |
+
THE KGB COMMISSION.
|
79 |
+
|
80 |
+
5. ΝΙΚΟΝOV'S FIRST ASSIGNMENT FROM BAKATIN WAS MAKING
|
81 |
+
ARRANGEMENTS FOR THE KGB-CIA LIAISON RELATIONSHIP WHICH HAS NOW
|
82 |
+
COME INTO BEING. IN PREPARATION FOR ONE POSSIBLE QUESTION
|
83 |
+
|
84 |
+
<<< TEMPORARY WORKING COPY DESTROY AFTER USE >>>
|
85 |
+
SECRET
|
86 |
+
|
87 |
+
# SECRET
|
88 |
+
|
89 |
+
OPERATOR: SEEGER, EDWA BADGE: KT283 DATE : 14 SEP 93
|
90 |
+
OFFICE : IMS/FABOSS PHONE: 047552 TIME : 15:24
|
91 |
+
ROOM : GC520HB PRINTER: T019 PAGE : 002
|
92 |
+
REQUESTER: HM877
|
93 |
+
DSN: SPET 21162 DOC DATE: 20 NOV 91 MHF#: 31-63208:3
|
94 |
+
|
95 |
+
WHICH MIGHT BE RAISED, NIKONOV PERSONALLY REVIEWED KGB FILES TO
|
96 |
+
DETERMINE IF LEE HARVEY ((OSWALD)) HAD BEEN A KGB AGENT. HE
|
97 |
+
REVIEWED FIVE THICK VOLUMES OF FILES ON OSWALD. NIKONOV IS NOW
|
98 |
+
CONFIDENT THAT OSWALD WAS AT NO TIME AN AGENT CONTROLLED BY THE
|
99 |
+
KGB. FROM THE DESCRIPTION OF OSWALD IN THE FILES HE DOUBTED
|
100 |
+
THAT ANYONE COULD CONTROL OSWALD, BUT NOTED THAT THE KBG
|
101 |
+
WATCHED HIM CLOSELY AND CONSTANTLY WHILE HE WAS IN THE USSR.
|
102 |
+
HE COMMENTED THAT OSWALD HAD A STORMY RELATIONSHIP WITH HIS
|
103 |
+
SOVIET WIFE, WHO RODE HIM INCESSANTLY. THE FILE ALSO REFLECTED
|
104 |
+
THAT OSWALD WAS A POOR SHOT WHEN HE TRIED TARGET FIRING IN THE
|
105 |
+
USSR.
|
106 |
+
|
107 |
+
6. IN PREPARATION FOR ESTABLISHMENT OF A LIAISON
|
108 |
+
RELATIONSHIP WITH THE SWEDISH INTELLIGENCE SERVICE, NIKONOV
|
109 |
+
PERSONALLY PERFORMED AN INQUIRY FOR BAKATIN INTO THE FATE OF
|
110 |
+
SWEDISH DIPLOMAT RAOUL ((WALLENBERG)). THERE IS STILL PRESSURE
|
111 |
+
FROM THE SWEDISH SIDE TO HAVE A DEFINITIVE ANSWER ON THIS
|
112 |
+
MATTER BECAUSE OF THE CONTINUING IMPORTANCE OF THE WALLENBERG
|
113 |
+
FAMILY. NIKONOV WAS AMAZED TO FIND OUT THAT THE KG3 HAD NOT
|
114 |
+
BEEN ABLE TO PREVIOUSLY ESTABLISH WHETHER WALLENBERG HAD DIED
|
115 |
+
AND UNDER WHAT CIRCUMSTANCES. HE WAS ABLE TO FIND PARTIAL
|
116 |
+
EVIDENCE FROM FOURTEEN DIFFERENT SOURCES (NF:). NIKONOV NOW
|
117 |
+
BELIEVES, BUT FOUND NO CONCLUSIVE PROOF, THAT WALLENBERG WAS
|
118 |
+
EXECUTED LATE IN 1947. THERE WERE INDICATIONS THAT WALLENBERG
|
119 |
+
WAS SUSPECTED OF HAVING CONTACTS WITH OTHERS WHO WERE ACCUSED
|
120 |
+
OF PROVIDING FALSE DIPLOMATIC IDENTITY DOCUMENTS TO OTHERS
|
121 |
+
BEYOND JEWS SAVED FROM THE HOLOCAUST. AMONG THESE WERE NAZI
|
122 |
+
WAR CRIMINALS WHO WERE ALLOWED TO ESCAPE. THERE WAS NO PROOF
|
123 |
+
OF WALLENBERG'S GUILT IN ANY OF THESE CHARGES.
|
124 |
+
|
125 |
+
7. FULBRIGHT PROFESSOR WHO IS NIKONOV'S FORMER PROFESSOR
|
126 |
+
AND FRIEND IS:
|
127 |
+
NAME: Ε.Β. ((SMITH))
|
128 |
+
DOB: C.1920
|
129 |
+
CIT: USA
|
130 |
+
OCC: PROFESSOR OF HISTORY AT UNIVERSITY OF MARYLAND,
|
131 |
+
RETIRED
|
132 |
+
LOC: RESIDES NEAR ANNAPOLIS, MD
|
133 |
+
OTHER: FULBRIGHT PROFESSOR FOR WINTER 1991 TERM IN ST
|
134 |
+
PETERSBURG STATE UNIVERSITY, USSR, TWO PREVIOUS FULBRIGHT
|
135 |
+
ASSIGNMENTS IN MOSCOW AND SEVERAL IN PRC AND GERMANY; HOSTS
|
136 |
+
FORMER STUDENTS FROM USSR AND PRC ON U.S. VISITS
|
137 |
+
THERE ARE NO BASE TRACES ON SMITH. HE SERVED IN THE
|
138 |
+
MILITARY AND IS VERY WELL DISPOSED TOWARDS THE U.S.
|
139 |
+
GOVERNMENT. HE VOLUNTEERED INFO ON NIKONOV AND OTHER USSR, PRC
|
140 |
+
AND GERMAN CONTACTS TO HEIBERG AND CAN PROVIDE CONSIDERABLE 810
|
141 |
+
AND ASSESSMENT INFO ON THEM.
|
142 |
+
|
143 |
+
8. FILE: 074-005-011, 201-0005925
|
144 |
+
DEFER. DECL OADR DRV HUM 4-82.
|
145 |
+
END OF MESSAGE SECRET
|
146 |
+
|
147 |
+
END OF DOCUMENT
|
148 |
+
|
149 |
+
<<< TEMPORARY WORKING COPY DESTROY AFTER USE >>>
|
space/space/space/space/space/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-10016-10021.md
ADDED
@@ -0,0 +1,74 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
104-10016-10021
|
2 |
+
|
3 |
+
2025 RELEASE UNDER THE PRESIDENT JOHN F. KENNEDY ASSASSINATION RECORDS ACT OF 1992
|
4 |
+
|
5 |
+
CLASSIFIED MESSAGE
|
6 |
+
|
7 |
+
SECRET
|
8 |
+
|
9 |
+
ROUTING
|
10 |
+
1
|
11 |
+
2
|
12 |
+
4
|
13 |
+
5
|
14 |
+
6
|
15 |
+
|
16 |
+
DIRECTOR
|
17 |
+
RECORDS OFFICER STAMP
|
18 |
+
|
19 |
+
MELBOURNE
|
20 |
+
The following action is authorized: DE SENSITIZE
|
21 |
+
|
22 |
+
CAMH
|
23 |
+
Signed: R. Haufton
|
24 |
+
DCI, D/DCI, DDP, C/CI, C/CI/SI, VR
|
25 |
+
R.O. #1 - Unit: CI/RKA
|
26 |
+
CS COPY
|
27 |
+
|
28 |
+
SECRET 0204222
|
29 |
+
Note: If destruction, cite reasons and coordinate if appropriate.
|
30 |
+
|
31 |
+
DIR INFO CNBR CITE MELB 2517 (ROLLOFIER ACTING)
|
32 |
+
2 DEC 63 IN 71187
|
33 |
+
AVDAT GPFLOOR
|
34 |
+
|
35 |
+
REF DIR 85690
|
36 |
+
|
37 |
+
1. SQUARE PRELIMINARY CHECKS ON RECORDED CONVERSATIONS REVEAL FOLL:
|
38 |
+
|
39 |
+
A NO TRACE 1952 DARK BLUE BUICK BELONGING SOVIET OR BLOC INSTALLATION CNBR OR SYDNEY.
|
40 |
+
|
41 |
+
B NO LICENSE PLATE IDENTICAL TO ONE MENTIONED BUT FOLL N.S.W. VARIANTS CHECKED: CCC 012, 1960 VAUXHALL, TWO-TONED BLUE, HERMAN SATRAPINSKY, 149 WENTWORTH AVE, WENTWORTHVILLE; CCC 122, 1949 STANDARD, FAUN, WILLIAM JOHN SIMS, BINALONG; CCO 122, 1960 HOLDEN, BIEGE, KEITH BETHKE, 28 HEWITT AVE, WAHROONGA. NO SQUARE DEROG ON ABOVE.
|
42 |
+
|
43 |
+
Document Number 270-676 for FOIA Review on. MAY 1976
|
44 |
+
C NO IDENTIFIABLE INFO ON AUSSIE MENTIONED CNBR 9591.(IN 68838)
|
45 |
+
|
46 |
+
D FRASERS MENTIONED SAME REF ARE ALP MPS.
|
47 |
+
|
48 |
+
E INDON FIRST SECY POSSIBLY IDW R. WILLY SASTRANEGARA HAS MOUSTACHE; RUSSIAN CAPABILITY NOT KNOWN TO SQUARE; NOT NOTICEABLY CLOSE TO SOVS CNBR.
|
49 |
+
|
50 |
+
D: 200-5-41
|
51 |
+
CLASSIFICATION REVIEW
|
52 |
+
CS COPY CONDUCTED ON 24 MAY 1970 1289248
|
53 |
+
E IMPDET CL BY 012208
|
54 |
+
|
55 |
+
GROUP
|
56 |
+
SECRET
|
57 |
+
Excluded from ovlomatic downgrading and declassification
|
58 |
+
|
59 |
+
REPRODUCTION BY OTHER THAN THE ISSUING OFFICE IS PROHIBITED
|
60 |
+
Copy No.
|
61 |
+
|
62 |
+
13-00000
|
63 |
+
|
64 |
+
CLASSIFIED MESSAGE 71187 PAGE 2
|
65 |
+
|
66 |
+
2. SQUARE HAS ARRANGED WITH PMG LIAISON OFFICER TED YOUNG TRACE ANY FURTHER CALLS MADE. EMBASSY IN CLOSE CONTACT SQUARE REP CNBR.
|
67 |
+
|
68 |
+
3. WILL ADVISE FURTHER DEVELOPMENTS.
|
69 |
+
|
70 |
+
SECRET
|
71 |
+
|
72 |
+
C/S COMMENY: Hqs requested information on the Polish driver connected with the Russian diplomatic establishment in Australia.
|
73 |
+
|
74 |
+
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/jfk_text/104-10023-10087.md
ADDED
@@ -0,0 +1,907 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
1400000
|
2 |
+
104-10023-10087
|
3 |
+
2025 RELEASE UNDER THE PRESIDENT JOHN F. KENNEDY ASSASSINATION RECORDS ACT OF 1992
|
4 |
+
|
5 |
+
( SECRET DO NOT REPRODUCE
|
6 |
+
RETURN TO CIA
|
7 |
+
(
|
8 |
+
DOHB 70-1-1
|
9 |
+
CHAPTER III
|
10 |
+
15 November 1974
|
11 |
+
ANNEX B
|
12 |
+
THE 201 SYSTEM
|
13 |
+
RETURN TO CIA
|
14 |
+
Background Use Only
|
15 |
+
Do Not Reproduce
|
16 |
+
:
|
17 |
+
|
18 |
+
Rescission: Annex B of Chapter III, CSHB 70-1-1, 27 October 1966
|
19 |
+
|
20 |
+
1. INTRODUCTION
|
21 |
+
|
22 |
+
The 201 system provides a method for identifying a person of specific in-
|
23 |
+
terest to the Operations Directorate and for controlling and filing all pertinent
|
24 |
+
information about that person. The system also provides a means for identifying
|
25 |
+
subjects of 201 files from various categories of information about them and for
|
26 |
+
producing lisits of 201 personalities according to those categories. Only a rela-
|
27 |
+
tively small number of personalities indexed are of sufficient interest to justify
|
28 |
+
opening a 201 dossier. These are normally subjects of extensive reporting and
|
29 |
+
CI investigation, prospective agents and sources, members of groups and organi-
|
30 |
+
zations of continuing target interest, or subjects on whom a volume of corre-
|
31 |
+
spondence has accumulated.
|
32 |
+
|
33 |
+
2. THE 201 SYSTEM
|
34 |
+
|
35 |
+
The principal features of the 201 system are:
|
36 |
+
|
37 |
+
a. The 201 Number: a unique number, i.e., 201-1234567, assigned to each
|
38 |
+
individual in the system to serve as identifying file number for reporting on that
|
39 |
+
individual.
|
40 |
+
|
41 |
+
b. The 201 Dossier: the official file containing the 201 opening form (Form
|
42 |
+
831) and all biographic reporting on and references to the individual, i.e., per-
|
43 |
+
sonal history, current status, and prospects.
|
44 |
+
|
45 |
+
c. The Master 201 Record: a machine record generated by the opening of
|
46 |
+
a 201 file. This record produces the master 201 reference for the Main Index and
|
47 |
+
stores the pertinent information which may later be retrieved for special listings.
|
48 |
+
|
49 |
+
d. Main Index Master 201 Reference: this reference, printed in reply to an
|
50 |
+
Index Search Request, is printed as illustrated below. When data are absent
|
51 |
+
within the record, succeeding data items or lines will be moved up and the ref-
|
52 |
+
erence consolidated..
|
53 |
+
|
54 |
+
SECRET
|
55 |
+
14-00000
|
56 |
+
SECRET
|
57 |
+
(
|
58 |
+
DOHB 70-1-1
|
59 |
+
CHAPTER III, ANNEX B
|
60 |
+
15 November 1974
|
61 |
+
い
|
62 |
+
0002 CROIX, WILLIAM PENDLETON
|
63 |
+
SEX M DOB 12 APR 26
|
64 |
+
CIT GERM
|
65 |
+
REF AACD-12345, 20 JUN 53
|
66 |
+
POB GERM, BERLIN 5
|
67 |
+
OCC PHARMACIST 6
|
68 |
+
OCC CODE CHEN
|
69 |
+
201-0032671*
|
70 |
+
ΤΥΡΕ ΝΑΜE T-
|
71 |
+
ΟΙ CODES AA XX-10
|
72 |
+
RCD DATE 53.
|
73 |
+
SUBJECT RECENTLY ATTENDED THE SEVENTEENTH ANNUAL
|
74 |
+
CONFERENCE OF THE INTERNATIONAL ASSOCIATION OF CHEMISTS
|
75 |
+
AND PHARMACISTS HELD IN MUNICH, GERMANY FROM 22 THROUGH
|
76 |
+
29 ОСТОВER.
|
77 |
+
30 NOV 70
|
78 |
+
(3
|
79 |
+
Information About Subject
|
80 |
+
1. Sequence Number and Name
|
81 |
+
2. Sex and Date of Birth
|
82 |
+
3. Citizenship
|
83 |
+
4. Place of Birth
|
84 |
+
5. Occupation
|
85 |
+
6. Occupation Code
|
86 |
+
7. Text
|
87 |
+
Document Reference Data Group
|
88 |
+
8. 201 Number
|
89 |
+
7
|
90 |
+
9. Name Type Indicator
|
91 |
+
10. OI Codes
|
92 |
+
11. Record Date (year only)
|
93 |
+
12. Reference
|
94 |
+
ISG Control Information
|
95 |
+
13. Date of latest update of the record
|
96 |
+
14. STAR Index Record Number
|
97 |
+
24
|
98 |
+
SECRET
|
99 |
+
00833555
|
100 |
+
14
|
101 |
+
!
|
102 |
+
14-00000
|
103 |
+
( SECRET (
|
104 |
+
DOHB 70-1-1
|
105 |
+
CHAPTER III, ANNEX B
|
106 |
+
15 November 1974
|
107 |
+
7
|
108 |
+
e. Ol Code: a two letter symbol used in conjunction with the 201 per-
|
109 |
+
sonality records in the 201 system to record the association of an individual
|
110 |
+
with organizations or activities of operational interest. OI codes cover intelli-
|
111 |
+
gence and security service affiliation, whether staff or agent, or known or
|
112 |
+
suspect, as well as activities of DDO interest. There are two categories of OI
|
113 |
+
codes for use by components:
|
114 |
+
|
115 |
+
(1) general OI codes (Attachment 4)
|
116 |
+
(2) OI codes assigned to a specific component for intelligence services
|
117 |
+
or other specific organizations.
|
118 |
+
|
119 |
+
À component may request an OI code be established by submitting a mem-
|
120 |
+
orandum to the DDO/RMO through the component Records Management
|
121 |
+
Officer.
|
122 |
+
|
123 |
+
A 201 personality may be assigned two OI codes. An OI code may be assigned
|
124 |
+
when the 201 Personality File Action Request (Form 831) is initiated (see
|
125 |
+
paragraph 3b below) by filling in Box 13 or a code may be assigned or added
|
126 |
+
at a later date by a Form 831 amendment.
|
127 |
+
|
128 |
+
The 201 system has the capability of producing machine listings of 201
|
129 |
+
personalities by Of codes. For example, if an Ol code has been opened for the
|
130 |
+
security service of a certain country a listing may be compiled of all members
|
131 |
+
of that service.
|
132 |
+
|
133 |
+
f. 201 Machine Lists: produced from the mechanized 201 Index, based on
|
134 |
+
names or other identifying information of personalities on whom 201 dossiers
|
135 |
+
exist.
|
136 |
+
|
137 |
+
3. OPENING A 201 DOSSIER
|
138 |
+
|
139 |
+
a. General
|
140 |
+
|
141 |
+
The opening of a 201 dossier is the prerogative of an operational com-
|
142 |
+
ponent, in coordination with the Information Services Group. An opening creates
|
143 |
+
a master 201 record. Changes to the master record and the occasional closing.
|
144 |
+
of a 201 dossier are controlled jointly by the desks and ISG. 201 dossiers may be
|
145 |
+
opened on persons who meet the carding criteria described in Chapter If of this
|
146 |
+
handbook, when there is a reasonable expectation that additional information
|
147 |
+
will be acquired and filed in such a dossier. Generally dossiers are opened on
|
148 |
+
persons about whom counterintelligence information is being reported, and per-
|
149 |
+
sons of operational interest to the Operations Directorate, specifically those
|
150 |
+
persons for whom provisional operational approvals and operational approvals
|
151 |
+
are requested (see exception below). 201 files are not to be opened on staff
|
152 |
+
employees, staff agents and most categories of contract employees. Files on
|
153 |
+
|
154 |
+
25
|
155 |
+
SECRET
|
156 |
+
14-00000
|
157 |
+
|
158 |
+
SECRET
|
159 |
+
(
|
160 |
+
DOHB 70-1-1
|
161 |
+
CHAPTER III, ANNEX B
|
162 |
+
15 November 1974
|
163 |
+
|
164 |
+
persons who are only of local interest to a field station or Headquarters desk
|
165 |
+
and on whom no DDO records correspondence exists are not a part of the DDO
|
166 |
+
records system and are to be maintained by that unit. Some desks levy require-
|
167 |
+
ments on ISG for automatic 201 openings on certain categories of persons whose.
|
168 |
+
names appear in incoming dispatches. These are listed in Attachment 2. 201
|
169 |
+
dossiers should be opened in the following categories:
|
170 |
+
|
171 |
+
(1) Subjects of provisional operational approval and operational ap-
|
172 |
+
proval requests. However, a file need not be opened when a POA is requested
|
173 |
+
for persons being trained for a foreign liaison service and who are of opera-
|
174 |
+
tional interest for training purposes only.
|
175 |
+
اه
|
176 |
+
|
177 |
+
(2) Persons for whom the field requests a 201 opening.
|
178 |
+
|
179 |
+
(3) MHFIXTURE personalities: bonafide diplomats of other than
|
180 |
+
denied area countries, in close association with staff personnel.
|
181 |
+
|
182 |
+
(4) Subjects of a Personal Record Questionnaire Part I.
|
183 |
+
|
184 |
+
(5) Persons on whom a Main Index search reveals information in five
|
185 |
+
or more documents (see DOI 70-20).
|
186 |
+
|
187 |
+
(6) Subjects of Interagency Source Register memoranda from LSN/
|
188 |
+
ISR (opened only by IP/RMS).
|
189 |
+
|
190 |
+
b. Requesting a 201 File Opening
|
191 |
+
|
192 |
+
Headquarters desks may open a 201 file by filling out and submitting
|
193 |
+
a 201 Personality File Action Request (Form 831) to the Records Main-
|
194 |
+
tenance Section (IP/RMS). Form 831 is also used to create or amend the
|
195 |
+
master 201 record and 201 machine listings and to register the assign-
|
196 |
+
ment of a cryptonym to a 201 personality. Attachment 3 consists of sample
|
197 |
+
201 Personality File Action Requests for opening and amending 201's. A field
|
198 |
+
station may request the opening of a 201 file by writing 201- in the Head-
|
199 |
+
quarters file or cross-reference box on the dispatch form and/or after the
|
200 |
+
subject's name in the body of the dispatch. A telepouch request for a 201 opening
|
201 |
+
is made by indicating 201- in the file number line. A cable request is made by
|
202 |
+
placing 201- after the term "File" on the last line of the transmission. IP/AN
|
203 |
+
will open 201 files as requested by dispatch or telepouch but it is the responsi-
|
204 |
+
bility of the desk to respond to cable requests. Field stations are notified of
|
205 |
+
201 openings through receipt of the field master 201 record.
|
206 |
+
|
207 |
+
28
|
208 |
+
SECRET
|
209 |
+
che kind while distribunal raudase andur, sinclarations . indian phính thi song
|
210 |
+
14-00000
|
211 |
+
( SECRET (
|
212 |
+
DOHB 70-1-1
|
213 |
+
CHAPTER III, ANNEX B
|
214 |
+
15 November 1974
|
215 |
+
|
216 |
+
4. CONTENTS OF THE DOSSIER
|
217 |
+
|
218 |
+
Information about a 201 personality should be filed or cross-referenced into
|
219 |
+
his dossier. When additional information is discovered on a 201 subject through
|
220 |
+
a name trace or other process, i.e., review of predecessor documents, it must
|
221 |
+
be consolidated into his personality dossier. See DOI 70-20 for consolidation
|
222 |
+
procedures.
|
223 |
+
?
|
224 |
+
Material which is filed in the dossier includes but is not limited to:
|
225 |
+
|
226 |
+
a. 201 Personality File Action Request (Form 831).
|
227 |
+
|
228 |
+
b. Biographic information including photographs, fingerprints, and
|
229 |
+
handwriting samples.
|
230 |
+
1.1
|
231 |
+
c. Personal Record Questionnaire Parts I and II.
|
232 |
+
|
233 |
+
d. Operational and other security approvals.
|
234 |
+
|
235 |
+
e. Name check replies, requests, clearances, and approvals.
|
236 |
+
|
237 |
+
f. Acknowledgement of pseudonym.
|
238 |
+
|
239 |
+
g. 201 personality assessments and evaluations.
|
240 |
+
|
241 |
+
h. Copy of contract and termination papers.
|
242 |
+
|
243 |
+
i. Secrecy agreement.
|
244 |
+
|
245 |
+
j. Agent Duty Status Report.
|
246 |
+
|
247 |
+
k. Training and evaluation.
|
248 |
+
|
249 |
+
1. SGSWIRL report.
|
250 |
+
|
251 |
+
m. Newspaper clippings.
|
252 |
+
|
253 |
+
n. Any information which helps provide a better understanding of the
|
254 |
+
subject and our interest in him; this may include operational reporting:
|
255 |
+
:
|
256 |
+
|
257 |
+
5. MAINTENANCE OF 201 DOSSIERS
|
258 |
+
|
259 |
+
The 201 personality dossier contains, in document date order, papers which
|
260 |
+
have been made a part of the Central Records System as well as those which
|
261 |
+
have not. Record documents may range from newspaper or magazine articles
|
262 |
+
on the subject to finance and other administrative papers.
|
263 |
+
|
264 |
+
26,1
|
265 |
+
عت
|
266 |
+
SECRET
|
267 |
+
14-00000
|
268 |
+
( SECRET (
|
269 |
+
DOHB 70-1-1-4
|
270 |
+
CHAPTER III, ANNEX B
|
271 |
+
15 November 1974
|
272 |
+
|
273 |
+
a. Purging
|
274 |
+
Purging a 201 dossier is the responsibility of the desk officer. It requires
|
275 |
+
discrimination in recognizing operationally useful material, rather than the
|
276 |
+
simple distinction between official and unofficial papers; it will therefore take
|
277 |
+
place under the supervision of a Records Officer. Purging should be done
|
278 |
+
periodically. A 201 dossier being forwarded to Central Files for retention should
|
279 |
+
be purged. A 201 dossier should be purged of the following:
|
280 |
+
|
281 |
+
(1) Duplicate material, i.e., exact copy(s) of a document.
|
282 |
+
|
283 |
+
(2) Name trace form (Form 362) unless it has been the basis for
|
284 |
+
the opening.
|
285 |
+
|
286 |
+
(3) All abstract slips.
|
287 |
+
|
288 |
+
(4) All document restriction notices (Form 1884).
|
289 |
+
|
290 |
+
(5) The disseminated version of positive intelligence information if
|
291 |
+
a copy of the raw report is contained in the 201 file; the dissemination number
|
292 |
+
then must be transferred to the first page of the raw report.
|
293 |
+
|
294 |
+
(6) Routing slips, routing and record sheets (Form 610) and dispatch
|
295 |
+
cover sheets unless there are remarks such as coordinations or comments.
|
296 |
+
|
297 |
+
(7) Record copy documents which only repeat substantive information
|
298 |
+
contained in other documents in the file; authorization for destruction is
|
299 |
+
by the Records Officer.
|
300 |
+
|
301 |
+
(8) Top Secret documents are not to be retained in a 201 dossier
|
302 |
+
forwarded to Central Files; the document must be downgraded for retention
|
303 |
+
in the 201 dossier. To downgrade a Top Secret document, an authorized
|
304 |
+
officer in the originating office or the Records Officer having jurisdiction
|
305 |
+
over the contents of the material must possess Top Secret classification-
|
306 |
+
authority. If the document cannot be downgraded the file should be retained
|
307 |
+
at the desk or the copy of the TS document should be removed, retained
|
308 |
+
in a desk TS file or forwarded to the Top Secret Control Officer, and a
|
309 |
+
cross-reference sheet (Form 867) placed in the 201 file giving the location
|
310 |
+
of the TS document.
|
311 |
+
|
312 |
+
(9) Deferred documents (see 5b(2)).
|
313 |
+
|
314 |
+
b. Maintenance Procedures
|
315 |
+
|
316 |
+
(1) All material in a 201 dossier will be filed in document date order.
|
317 |
+
In the case of document attachments which have been classified into a 201
|
318 |
+
26.2
|
319 |
+
SECRET
|
320 |
+
14-00000
|
321 |
+
SECRET (
|
322 |
+
DOHB 70-1-1
|
323 |
+
CHAPTER III, ANNEX B
|
324 |
+
15 November 1974
|
325 |
+
7
|
326 |
+
dossier and separated from the basic document by the assignment of a slash
|
327 |
+
number, the attachment will be filed by the date of the basic document.
|
328 |
+
|
329 |
+
(2) Deferred documents will not be filed in a 201 dossier. If they are
|
330 |
+
to be retained in the dossier they should be sent to IP/RMS for classification
|
331 |
+
into that 201.
|
332 |
+
|
333 |
+
(3) Field index cards (held by some desks) and area desk cards may
|
334 |
+
be retained in the 201 as part of a consolidation procedure. These cards
|
335 |
+
should be mounted on a full-size sheet of paper for filing in the 201..
|
336 |
+
|
337 |
+
(4) A 201 dossier previously opened on a person who becomes a staff
|
338 |
+
employee and which contains Record Copy documents will be restricted to
|
339 |
+
the ISG/DIP unless the desk retains the restriction. The dossier should be
|
340 |
+
closed if there are no Record Copy documents in it.
|
341 |
+
|
342 |
+
(5) A 201 opened in pseudonym should be consolidated into the true
|
343 |
+
name 201 if one exists or converted to the true name.
|
344 |
+
|
345 |
+
(6) Field and duplicate (shadow) (201 files no longer of active interest
|
346 |
+
should be incorporated into the official 201 after the duplicate material
|
347 |
+
has been purged by the desk officer and the remaining information classified
|
348 |
+
to that 201 by the Analysis Section (IP/AN).
|
349 |
+
|
350 |
+
(7) Any document with a predecessor organization cover sheet or an
|
351 |
+
OPC (Office of Policy Coordination) cover sheet from the Archives and
|
352 |
+
Disposition Section (IP/ARD) must be returned to IP/ARD for processing
|
353 |
+
to the 201.
|
354 |
+
|
355 |
+
(8) Desk memoranda (with or without a document source number)
|
356 |
+
containing substantive or derogatory information on the subject of the 201
|
357 |
+
should be sent to. IP/AN to be classified officially into the 201 file.
|
358 |
+
|
359 |
+
(9) An attachment which should be separated from its basic document
|
360 |
+
for inclusion in a-201 personality dossier will be forwarded with the basic
|
361 |
+
document to IP/AN for processing into the 201.
|
362 |
+
|
363 |
+
(10) To retain the P&L, RYBAT, or KAPOK sensitivity of a document
|
364 |
+
remaining in a 201 dossier being retired to Central Files, place that document
|
365 |
+
in an envelope sealed with black tape (see DOI 70-17). Any RYBAT, P&L,
|
366 |
+
or KAPOK document sent to Central Files not in a black-taped envelope will
|
367 |
+
automatically be handled as desensitized. A black-taped envelope may con-
|
368 |
+
tain only one document and must be filed in chronological order within the
|
369 |
+
file. If there are numerous documents of this type the desk officer may black--- v
|
370 |
+
tape the entire dossier rather than individual documents (see DOI 70-10).
|
371 |
+
|
372 |
+
26.3
|
373 |
+
SECRET
|
374 |
+
14-00000
|
375 |
+
SECRET
|
376 |
+
(
|
377 |
+
DOHB 70-1-14
|
378 |
+
CHAPTER III, ANNEX B
|
379 |
+
15 November 1974
|
380 |
+
|
381 |
+
Black-taped dossiers or dossiers with black-taped documents will be
|
382 |
+
handled as restricted dossiers.
|
383 |
+
|
384 |
+
(11) An inactive 201 dossier or an inactive volume of a large 201
|
385 |
+
dossier on permanent charge should be returned to Central Files under a
|
386 |
+
Routing and Record Sheet with the notation shown below..
|
387 |
+
|
388 |
+
UNCLASSIFIED
|
389 |
+
INTERNAL
|
390 |
+
USE ONLY
|
391 |
+
SUBJECT:
|
392 |
+
FROM
|
393 |
+
TO O
|
394 |
+
1.
|
395 |
+
IP/Files
|
396 |
+
CC-52
|
397 |
+
2
|
398 |
+
5.
|
399 |
+
7.
|
400 |
+
L
|
401 |
+
CONFIDENTIAL
|
402 |
+
SECRET
|
403 |
+
ROUTING AND RECORD SHEET
|
404 |
+
TRANSMITTAL OF INACTIVE 201 DOSSIERS
|
405 |
+
DATE
|
406 |
+
OFFICERS COMMENTS eru samned to show ham sh
|
407 |
+
SHETLALS
|
408 |
+
(For guidance see CSHB 70-1-1,
|
409 |
+
Chapter III, Annex B.)
|
410 |
+
Volume(s) of volume(s)
|
411 |
+
of 201-
|
412 |
+
Restricted Dossier
|
413 |
+
(Attach Foru 2021 to
|
414 |
+
Dossier)
|
415 |
+
Non-Restricted Dossier
|
416 |
+
10.
|
417 |
+
For Split Charge Dossiers:
|
418 |
+
11.
|
419 |
+
All documents prior to
|
420 |
+
(date)
|
421 |
+
12
|
422 |
+
12
|
423 |
+
14.
|
424 |
+
15.
|
425 |
+
forvarded to IP/Files. All
|
426 |
+
documents after
|
427 |
+
retained at
|
428 |
+
BIDE
|
429 |
+
SECRET CONFIDENTIAL
|
430 |
+
PETERMAL
|
431 |
+
28.4
|
432 |
+
SECRET
|
433 |
+
(date)
|
434 |
+
desk.
|
435 |
+
CL STA
|
436 |
+
UNCLASSIFIED
|
437 |
+
::
|
438 |
+
14-00000
|
439 |
+
( SECRET (
|
440 |
+
DOHB 70-1-1
|
441 |
+
CHAPTER III, ANNEX B
|
442 |
+
15 November 1974
|
443 |
+
|
444 |
+
6. 201 DOSSIER CHARGES
|
445 |
+
|
446 |
+
A 201 dossier may be kept on permanent charge at the desk during any
|
447 |
+
period of active interest. If the dossier is transferred to another desk, the desk
|
448 |
+
officer who is transferring the dossier must notify Central Files of the transfer.
|
449 |
+
Central Files will then send the Notice of Transfer of Document or File Account-
|
450 |
+
ability (Form 2977) to the new action desk officer.
|
451 |
+
TO:
|
452 |
+
HAME
|
453 |
+
CONFIDENTIAL
|
454 |
+
(Thon gitled in)
|
455 |
+
NOTICE OF TRANSFER OF DOCUMENT OR FILE ACCOUNTABILITY
|
456 |
+
BADGE
|
457 |
+
COMPONENT
|
458 |
+
ROOM
|
459 |
+
TUDE
|
460 |
+
EXT.
|
461 |
+
This is to notify you that accountability for the document(s) and/or file(s) cited
|
462 |
+
below has been transferred to you by:
|
463 |
+
Accordingly, IP's records now reflect you as the custodian. Please contact IP/Files,
|
464 |
+
Ext. 4362, if you have any questions regarding this transfer.
|
465 |
+
SUBJECT OF REQUEST
|
466 |
+
FORM 2377E PREVIOUS COITIONS
|
467 |
+
1-73
|
468 |
+
DATE
|
469 |
+
FILE NO.
|
470 |
+
DOC. STHSOL & NUMBER BOC. DATE
|
471 |
+
40
|
472 |
+
TRANSFER
|
473 |
+
CHARGE
|
474 |
+
PERM
|
475 |
+
OR TENP
|
476 |
+
CONFIDENTIAL
|
477 |
+
CL BY: 007672
|
478 |
+
The new action desk officer must then fill out a 201 Personality File Action
|
479 |
+
Request (Form 813) to change the action desk designation to insure that the
|
480 |
+
201 personality will be included in the Headquarters and field machine listings
|
481 |
+
for his component..
|
482 |
+
|
483 |
+
7. RESTRICTED DOSSIERS
|
484 |
+
|
485 |
+
a. Access to a sensitive 201 dossier may be restricted by holding the file at the
|
486 |
+
desk or placing it on restriction in Central Files.
|
487 |
+
|
488 |
+
(1) The dossier may be restricted by checking Box 2 on the 201
|
489 |
+
Personality File Action Request (Form 831) when the file is opened.
|
490 |
+
|
491 |
+
26.5
|
492 |
+
SECRET
|
493 |
+
:
|
494 |
+
:
|
495 |
+
14-00000
|
496 |
+
( SECRET (
|
497 |
+
DOHB 70-1-1
|
498 |
+
CHAPTER III, ANNEX B
|
499 |
+
15 November 1974
|
500 |
+
|
501 |
+
(2) The dossier may be restricted by holding it on permanent charge
|
502 |
+
from Central Files. (Note: To maintain the restriction of a dossier being
|
503 |
+
returned to Central Files for retention, a File Restriction Notice (Form
|
504 |
+
2021) must accompany the dossier.)
|
505 |
+
|
506 |
+
(3) The dossier may be restricted and held in Central Files by sub-
|
507 |
+
mitting a File Restriction Notice (Form 2021).
|
508 |
+
TO
|
509 |
+
IP/FI
|
510 |
+
GC-52 TUBE DT-6
|
511 |
+
IP/DCU
|
512 |
+
GC-40 TUBE HT-4
|
513 |
+
ACTION DESK: 1.
|
514 |
+
SECTION A
|
515 |
+
CONFIDENTIAL
|
516 |
+
(When Pilled In)
|
517 |
+
INITIALS
|
518 |
+
FILE RESTRICTION NOTICE
|
519 |
+
To restrict a file, complete Section A (signature of R.O. not
|
520 |
+
necessary).
|
521 |
+
2. To remove a restriction, complete Section B (R.O. signature
|
522 |
+
Decessary).
|
523 |
+
FILE HUNGER
|
524 |
+
RESTRICT TO: (Use country or non-country code number. See CSI 70-28)
|
525 |
+
RESTRICTED BY:
|
526 |
+
COMPONENT:
|
527 |
+
Date:
|
528 |
+
SECTION B
|
529 |
+
REMOVE RESTRICTION (AUTHORIZED BY)
|
530 |
+
COMPONENT:
|
531 |
+
R.O. No.
|
532 |
+
Date:
|
533 |
+
FORN
|
534 |
+
2-23 2021 IONS
|
535 |
+
CONFIDENTIAL
|
536 |
+
8-2, IMPORT CL BY, CG7122
|
537 |
+
7
|
538 |
+
b. Access to a restricted dossier located in Central Files is limited to the
|
539 |
+
personnel of the restricting desk or persons authorized by that desk. Any request
|
540 |
+
for the charge of a restricted dossier or any document within a restricted dossier
|
541 |
+
held in Central Files will be forwarded with the entire dossier and a multiple-
|
542 |
+
routed cover sheet to the restricting desk. This desk may then forward the file
|
543 |
+
to the requester or deny the request and return the dossier to Central Files. The
|
544 |
+
desk will notify the requester of a denial.
|
545 |
+
|
546 |
+
c. Anyone requesting a restricted dossier, or a document within a restricted
|
547 |
+
dossier, permanently or temporarily charged to a desk, will be referred to that
|
548 |
+
desk by Central Files.
|
549 |
+
|
550 |
+
26.6
|
551 |
+
SECRET
|
552 |
+
14-00000
|
553 |
+
( SECRET (
|
554 |
+
DOHB 70-1-1
|
555 |
+
CHAPTER III, ANNEX B
|
556 |
+
15 November 1974
|
557 |
+
?
|
558 |
+
8. REQUESTS FOR INFORMATION ON 201 PERSONALITIES
|
559 |
+
|
560 |
+
The Automated Index Section (IP/AIS) will provide the identity of the
|
561 |
+
subject of a 201 number unless the 201 file is restricted, in which case the
|
562 |
+
requester will be referred to the restricting desk.
|
563 |
+
|
564 |
+
IP/AIS will also provide the 201 number assigned to a name, unless the 201
|
565 |
+
file is restricted, or state that there is no 201 number assigned. Requesters should
|
566 |
+
supply identifying information whenever available for each name submitted.
|
567 |
+
|
568 |
+
`Requests pertaining to five or fewer names or numbers may be made by
|
569 |
+
telephone by calling the IP/AIS red line extension; IP/AIS will provide the
|
570 |
+
information by return call to the requester's extension as listed in the Badge
|
571 |
+
Table. Requests for more than five names or numbers must be listed and sent
|
572 |
+
by tube or courier to IP/AIS; IP/AIS will reply by return mail.
|
573 |
+
|
574 |
+
9. 201 DOSSIER CANCELLATION
|
575 |
+
|
576 |
+
A 201 file may be authorized for cancellation by a Records Officer, after
|
577 |
+
appropriate coordination. The file should be forwarded to IP/RMS which will
|
578 |
+
destroy the folder and the cards leading to it and will remove the name and
|
579 |
+
number from machine lists. Any Record Copy document contained in the folder
|
580 |
+
will be reclassified to another appropriate file or sent to the Destruction Unit
|
581 |
+
(IP/DU) as directed by the desk Records Officer.
|
582 |
+
|
583 |
+
10. 201 MACHINE LISTINGS
|
584 |
+
|
585 |
+
Machine listings provide field stations and Headquarters desks with names
|
586 |
+
and 201 numbers in the requester's particular geographic or functional area of
|
587 |
+
interest. If a component wishes to exclude a sensitive 201 personality from its
|
588 |
+
alphabetic, numeric, and cryptonym listings, this may be done when opening
|
589 |
+
the 201 or later by a 201 amendment. On the 201 Personality File Action Request
|
590 |
+
(Form 831) leave the country of location (Box 15) and interest desk (Box 16)
|
591 |
+
blank, use the non-country code 900 in the action box (Box -14), and indicate
|
592 |
+
permanent charge to the responsible desk. The only listing which will include the
|
593 |
+
201 number is the IP/201 record for the Vital Records program. 201 listings are
|
594 |
+
categorized as standard or nonstandard and as scheduled or special.
|
595 |
+
|
596 |
+
a. Standard Listings
|
597 |
+
|
598 |
+
Issued semi-annually to Headquarters and the field; based on a component's
|
599 |
+
interest as indicated in the "Action Desk," "Country of Location," and "Interest
|
600 |
+
|
601 |
+
28.7
|
602 |
+
SECRET
|
603 |
+
14-00000
|
604 |
+
|
605 |
+
( (
|
606 |
+
SECRET
|
607 |
+
DOHB 70-1-1
|
608 |
+
CHAPTER III, ANNEX B
|
609 |
+
15 November 1974
|
610 |
+
**
|
611 |
+
Desk" blocks on the 201 Personality File Action Request (Form 831). The
|
612 |
+
standard listings available are:
|
613 |
+
i
|
614 |
+
|
615 |
+
(1) Alphabetical by surname, leading to a 201 number;
|
616 |
+
|
617 |
+
(2) Alphabetical by given name, leading to a 201 number;
|
618 |
+
|
619 |
+
(3) Alphabetical by cryptonym, leading to a 201 number;
|
620 |
+
९.
|
621 |
+
i
|
622 |
+
|
623 |
+
(4) Numerical, leading to a surname;
|
624 |
+
|
625 |
+
(5) Numerical, leading to a cryptonym.
|
626 |
+
FUL & CHINA
|
627 |
+
201 SURNAME ALPHA LIST
|
628 |
+
03 ICT
|
629 |
+
1973.
|
630 |
+
NAPIE
|
631 |
+
SECRET/ORGANIZATION INTERNAL USE ONLY
|
632 |
+
C, SH 117185/1343/5030/
|
633 |
+
CHEM. SHOU 117115/1343/0001/
|
634 |
+
CINE. SHU 1. 17115/1343/0001/
|
635 |
+
CHE. SHOU-JFY 16774/1108/0088
|
636 |
+
CHEM, SHOU EI
|
637 |
+
17JUL14
|
638 |
+
BIRTHPLACE
|
639 |
+
DA/MO/YR
|
640 |
+
CERY GEFY
|
641 |
+
CHIN, RHANGTUNG
|
642 |
+
4
|
643 |
+
24 JANES
|
644 |
+
90
|
645 |
+
CHIN, AMOY
|
646 |
+
04JAN19
|
647 |
+
CHIN, FUXIEM, PROV.
|
648 |
+
A
|
649 |
+
1240V22
|
650 |
+
CHIN, HUNムス
|
651 |
+
IPMARAS
|
652 |
+
CHIN
|
653 |
+
C41
|
654 |
+
CHIN, CAN ΤΩΝ
|
655 |
+
TYPE
|
656 |
+
008
|
657 |
+
DCC. CIT. 201
|
658 |
+
01-101-2. ACT. LOC. (ir.
|
659 |
+
MAME
|
660 |
+
CRAY
|
661 |
+
CIRY CE
|
662 |
+
CHINT 0165401
|
663 |
+
CHIN HR
|
664 |
+
DIPT
|
665 |
+
0218859
|
666 |
+
CHIN CHIN
|
667 |
+
5178653
|
668 |
+
CHEY
|
669 |
+
f-41G 17109/1343/690
|
670 |
+
CHAN. SIEU SHIH 17115/1105/001
|
671 |
+
CHFE SHCU-TAN
|
672 |
+
CHEY, SH-155467115/1109/1
|
673 |
+
CHEN, SHCU 126 /0701/1343/1807
|
674 |
+
CHEN, SHC-17115/1109/495
|
675 |
+
CHEM, SHU-٩٨١
|
676 |
+
CHY. SHAI-CHI4 17115/2005/6930
|
677 |
+
CHE: SHIU CINIAM 7115/3219/122
|
678 |
+
CHOM, SH-C17115/2535/2
|
679 |
+
CNCS. SITU 7115/2055/2797/ דניים
|
680 |
+
CHEN, SHU FEM
|
681 |
+
A
|
682 |
+
R
|
683 |
+
0258926 CHIM, LEARNING PRO
|
684 |
+
12JAN18
|
685 |
+
09 JUN99
|
686 |
+
1905619
|
687 |
+
02 JUL 30
|
688 |
+
:
|
689 |
+
19
|
690 |
+
NOV30
|
691 |
+
CIAC22
|
692 |
+
OF JUL 14
|
693 |
+
CHIN, FURIEN
|
694 |
+
CHIN, CAЧТО
|
695 |
+
CHIN, FLANGTING PROV
|
696 |
+
CHIN, KWANGTUNG PROV.
|
697 |
+
CHIN, FIJAN TANG IS
|
698 |
+
CHIN. PFILIU
|
699 |
+
CHIN, RAANG TUNG
|
700 |
+
ENGR CHAT 0832655
|
701 |
+
CHI47 0130415
|
702 |
+
CCC? 0091803
|
703 |
+
PROF CHIN? 0040289
|
704 |
+
CH417 0052638
|
705 |
+
ARMY CHAT 0328328
|
706 |
+
CHIN? 0124438
|
707 |
+
TSEA CRAT 0797335
|
708 |
+
210CT06 CHIM, PANCINIPIA, PORT ARTH
|
709 |
+
BUSP CCOM? 0043751
|
710 |
+
CHAT 0179620
|
711 |
+
CHIN HK
|
712 |
+
CHIM? 0234629
|
713 |
+
:
|
714 |
+
CHIN CUSA
|
715 |
+
CHIN CHIN
|
716 |
+
CHAT
|
717 |
+
0069786
|
718 |
+
CHIN
|
719 |
+
DIPT CCON
|
720 |
+
0905340
|
721 |
+
CHIM MALT
|
722 |
+
:
|
723 |
+
CHIK HX
|
724 |
+
CHIR TAIW
|
725 |
+
CHIN
|
726 |
+
CHIN USA
|
727 |
+
CHEN HWA
|
728 |
+
CHER TAL
|
729 |
+
CHEN IK
|
730 |
+
CHIN H
|
731 |
+
CHIT, SMI HA /7113/2885/3185/
|
732 |
+
CFT, SITI HEANG 17115/2579/74
|
733 |
+
CFS-510 7115/2985/7
|
734 |
+
10
|
735 |
+
23FERO7
|
736 |
+
CHIN, FUKIEN
|
737 |
+
CHEN, KWANGTUNG
|
738 |
+
CIER, SHU MS
|
739 |
+
17115/2835/8133
|
740 |
+
OSMAY18
|
741 |
+
CHIN, FOOCH
|
742 |
+
CHIT. SHU-درس
|
743 |
+
30×4326
|
744 |
+
CHIEN SINI-1 2711.5/2925/5030/
|
745 |
+
A
|
746 |
+
06F5816
|
747 |
+
CHIN, HOPET
|
748 |
+
CHIN? 0171622
|
749 |
+
DIPT CCCM. 0223161
|
750 |
+
CHIR USA
|
751 |
+
CHEN CHI
|
752 |
+
CHIN
|
753 |
+
CHIN CHIN
|
754 |
+
CHER USA
|
755 |
+
CHIN? 0200223
|
756 |
+
CHIN
|
757 |
+
04RAST7
|
758 |
+
CHIN ETH
|
759 |
+
CHEY? 0179621
|
760 |
+
CHIK? 0014759
|
761 |
+
CCO? 00923195
|
762 |
+
CILEN
|
763 |
+
CHIN CEY
|
764 |
+
CHEN, SIRU RUET /7215/2695/2710
|
765 |
+
Girn, SIRI LAY
|
766 |
+
27NQY23
|
767 |
+
CHIN. FANG CHIFING
|
768 |
+
PROF CHIN? 0175673
|
769 |
+
CHIM CHI
|
770 |
+
食
|
771 |
+
CHIN
|
772 |
+
CCON 0221972
|
773 |
+
CHIA CHI
|
774 |
+
CHLR, SIPI LIANG 77115/0547/009
|
775 |
+
CHEM. Sins 114 7115/2579/2631/
|
776 |
+
CIRCZE
|
777 |
+
CHIN
|
778 |
+
DEPT CHEN? 0223162
|
779 |
+
CHIN CHIN
|
780 |
+
25MMV20-
|
781 |
+
CHIN, FERGSHUN
|
782 |
+
CHIN? 0179624
|
783 |
+
CHIM TAT
|
784 |
+
CHOEN SHIT-L145 17107/2473/010
|
785 |
+
01 JUL 29
|
786 |
+
CHIN, FIANGSU
|
787 |
+
MILA CCM
|
788 |
+
0834440
|
789 |
+
CHIM LACS
|
790 |
+
20SE 20
|
791 |
+
CHER, HSIAM-HSLEN, KLANGSU
|
792 |
+
CHAT
|
793 |
+
009647-
|
794 |
+
CHIN USA
|
795 |
+
CHEM, SHY 4/7119/2285/0589/
|
796 |
+
CILM, SHU-PAD 7115/2579/0202/
|
797 |
+
CHFA, SHU-SEM/7115/2895/2773/
|
798 |
+
CHIFT, SINI-SHAN 17115/2579/091
|
799 |
+
CHEM, SHU-TE /7115/2455/1795/
|
800 |
+
154PR 30
|
801 |
+
1°PECI
|
802 |
+
A
|
803 |
+
300EC26
|
804 |
+
27JAN25
|
805 |
+
210EC37
|
806 |
+
CIPEN, SHU 1EH/475/
|
807 |
+
27MA 20
|
808 |
+
CHEN, CHEHCHA 1
|
809 |
+
CHIN, KWANGTING PROV.
|
810 |
+
CHIM, KWANG TUPIG
|
811 |
+
CHIM, FUKIEN PROY
|
812 |
+
CHEN, SHANGHAI
|
813 |
+
CHIM, CHANG SHO
|
814 |
+
CHIN CHI
|
815 |
+
CHAT? 0052638
|
816 |
+
CHEN HWAL
|
817 |
+
CHINT 0085119
|
818 |
+
CHIN TATH
|
819 |
+
CHIN? OL03249
|
820 |
+
CHEN CHIN.
|
821 |
+
GEOL CHIN? 0763416-
|
822 |
+
CHEN BUSA
|
823 |
+
0013991
|
824 |
+
CHIN
|
825 |
+
CM. SH15/0647/6639
|
826 |
+
CIPCTS
|
827 |
+
CHIN, HANG CHEA
|
828 |
+
CHIN? 0153929
|
829 |
+
OHER CAIR
|
830 |
+
CHEE, SHE T120 /7115/245/2757/
|
831 |
+
CICM. SU 1217:15/0647/0317 וי/
|
832 |
+
LAMAR17
|
833 |
+
CHEN:
|
834 |
+
FIN CCON0767442-CIA "UR
|
835 |
+
A
|
836 |
+
OZFEROS
|
837 |
+
0151320
|
838 |
+
CHIN
|
839 |
+
CEA, S-T40/7115/2655/1031
|
840 |
+
CIPES, SM-T11
|
841 |
+
CHIR. SHIP 1/7115/2845/5341
|
842 |
+
CHIM, SIRI-19/7115/2579/6992/
|
843 |
+
アレった。ベリー
|
844 |
+
COUNT. SIN 7115/2579/3842/ ניז/
|
845 |
+
11AOVOS
|
846 |
+
CHIN, RUENGTING
|
847 |
+
CHIN
|
848 |
+
OSAPRE?
|
849 |
+
CHIN, PEIPING
|
850 |
+
CHINT 0107306
|
851 |
+
CHIN CHEN
|
852 |
+
15 JUNOG
|
853 |
+
CHEN, FARG CHET KU
|
854 |
+
CHIM? 0179624
|
855 |
+
CHIN CHIN
|
856 |
+
0200130
|
857 |
+
21APP21
|
858 |
+
CHIN, SHANGHAS
|
859 |
+
04 SEP28
|
860 |
+
CHIS. SIECINAN
|
861 |
+
CHIN, HENG YANG HSIEN, HIJN ARMY-CHAT 0349624
|
862 |
+
171FM38 CHIN. CHER LANG
|
863 |
+
SECRET/ORGANIZATION INTERNAL USE ONLY
|
864 |
+
82 INPORS CL BY 056979
|
865 |
+
CHIN? 44010
|
866 |
+
CHIN? 0144758
|
867 |
+
CHIN TAIN
|
868 |
+
INT
|
869 |
+
0111410
|
870 |
+
CHIN DEUX
|
871 |
+
CHIN
|
872 |
+
CHIM TAEw
|
873 |
+
PAGE
|
874 |
+
150
|
875 |
+
26.8
|
876 |
+
SECRET
|
877 |
+
14-00000
|
878 |
+
::
|
879 |
+
( (
|
880 |
+
SECRET
|
881 |
+
DOHB 70-1-1
|
882 |
+
CHAPTER III, ANNEX B
|
883 |
+
15 November 1974
|
884 |
+
|
885 |
+
All standard listings are cumulative; previous editions must be destroyed
|
886 |
+
upon receipt of current editions. These listings are by their very nature extremely
|
887 |
+
sensitive compilations of information and must be given every possible safeguard.
|
888 |
+
|
889 |
+
b. Non-Standard Listings
|
890 |
+
?
|
891 |
+
:
|
892 |
+
Based on one or more of the following selection criteria:
|
893 |
+
|
894 |
+
(1) Country of location
|
895 |
+
|
896 |
+
(2) OI codes (organization and/or intelligence affiliation)
|
897 |
+
|
898 |
+
(3) Citizenship
|
899 |
+
;
|
900 |
+
|
901 |
+
(4) Year of birth (plus or minus a given number of years)
|
902 |
+
|
903 |
+
(5) Occupation.
|
904 |
+
|
905 |
+
These selection criteria may be used singly or in combinations. For example,
|
906 |
+
a user could obtain a list of all 201 personalities who have been assigned the
|
907 |
+
OI code of XX or codes of XX, XY, or XZ. A
|