levalencia commited on
Commit
2d87de0
·
1 Parent(s): 665cc97

feat: enhance app.py with session state management and extraction strategy selection

Browse files

- Added initialization of session state for field descriptions and unique indices tables to improve user experience.
- Implemented a strategy selection feature allowing users to choose between "Original Strategy" and "Unique Indices Strategy" for data extraction.
- Updated the configuration section to load and save configurations, enhancing flexibility in managing extraction settings.
- Improved logging and error handling throughout the extraction process for better monitoring and debugging.

logs/di_content/di_content_20250618_134751_tables.html ADDED
@@ -0,0 +1,382 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>Azure DI Tables</title>
5
+ <style>
6
+ body { font-family: Arial, sans-serif; margin: 20px; }
7
+ .table-container { margin-bottom: 40px; }
8
+ h2 { color: #333; }
9
+ table { border-collapse: collapse; width: 100%; margin-bottom: 10px; }
10
+ th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
11
+ th { background-color: #f5f5f5; }
12
+ hr { border: none; border-top: 2px solid #ccc; margin: 20px 0; }
13
+ </style>
14
+ </head>
15
+ <body>
16
+ <h1>Azure Document Intelligence Tables</h1>
17
+
18
+ <div class="table-container">
19
+ <h2>Table 1</h2>
20
+ <table border="1">
21
+ <tr>
22
+ <td>Account # 0800011357</td>
23
+ <td>Billing reference LBT/PI/2025/481; BRU354089 (6300005106)</td>
24
+ <td>Billing reference LBT/PI/2025/481; BRU354089 (6300005106)</td>
25
+ <td>Rec'd by WC (name) MIN-2</td>
26
+ <td>Rec'd by WC (name) MIN-2</td>
27
+ </tr>
28
+ <tr>
29
+ <td>From (Shipper)</td>
30
+ <td>From (Shipper)</td>
31
+ <td>To (Consignee)</td>
32
+ <td>To (Consignee)</td>
33
+ <td>To (Consignee)</td>
34
+ </tr>
35
+ <tr>
36
+ <td>Lim Ngian Gin/Jesline Ang</td>
37
+ <td>+6565213671/+65213959</td>
38
+ <td>Michelle de Meyer</td>
39
+ <td>+32 9 310 34 00</td>
40
+ <td>+32 9 310 34 00</td>
41
+ </tr>
42
+ <tr>
43
+ <td>LONZA BIOLOGICS TUAS PTE LTD</td>
44
+ <td></td>
45
+ <td>ARGENX BV</td>
46
+ <td></td>
47
+ <td></td>
48
+ </tr>
49
+ <tr>
50
+ <td>35 TUAS SOUTH AVE 6</td>
51
+ <td></td>
52
+ <td>INDUSTRIEPARK ZWIJNAARDE 7</td>
53
+ <td></td>
54
+ <td></td>
55
+ </tr>
56
+ <tr>
57
+ <td>TUAS 637377 SG</td>
58
+ <td></td>
59
+ <td>ZWIJNAARDE 9052 BE</td>
60
+ <td></td>
61
+ <td></td>
62
+ </tr>
63
+ <tr>
64
+ <td>Shipment information</td>
65
+ <td></td>
66
+ <td></td>
67
+ <td></td>
68
+ <td></td>
69
+ </tr>
70
+ <tr>
71
+ <td>Full description of contents</td>
72
+ <td></td>
73
+ <td>Special handling</td>
74
+ <td></td>
75
+ <td></td>
76
+ </tr>
77
+ <tr>
78
+ <td>PROTEIN SAMPLES, Deep Frozen Dry Ice -70C [+/-10C]</td>
79
+ <td>PROTEIN SAMPLES, Deep Frozen Dry Ice -70C [+/-10C]</td>
80
+ <td></td>
81
+ <td></td>
82
+ <td></td>
83
+ </tr>
84
+ </table>
85
+ <hr>
86
+ </div>
87
+
88
+ <div class="table-container">
89
+ <h2>Table 2</h2>
90
+ <table border="1">
91
+ <tr>
92
+ <td>Number of pieces</td>
93
+ <td>:unselected: Weight LBS</td>
94
+ <td>Dimensions</td>
95
+ <td>:selected: CM</td>
96
+ <td>Does this shipment contain dangerous goods?</td>
97
+ <td>Does this shipment contain dangerous goods?</td>
98
+ <td></td>
99
+ </tr>
100
+ <tr>
101
+ <td>1</td>
102
+ <td>:selected: 22 KGS</td>
103
+ <td>53 X 36 X 44</td>
104
+ <td>:unselected: IN</td>
105
+ <td>:unselected: NO</td>
106
+ <td>:unselected: YES (Per attached shipper's declaration)</td>
107
+ <td>:selected:
108
+ YES (Shipper's declaration not required)</td>
109
+ </tr>
110
+ </table>
111
+ <hr>
112
+ </div>
113
+
114
+ <div class="table-container">
115
+ <h2>Table 3</h2>
116
+ <table border="1">
117
+ <tr>
118
+ <td>Country of origin</td>
119
+ <td>Declared value for customs</td>
120
+ <td>Declared value for carriage Check if surcharge elected</td>
121
+ </tr>
122
+ <tr>
123
+ <td></td>
124
+ <td>10.00 USD</td>
125
+ <td>:unselected:</td>
126
+ </tr>
127
+ </table>
128
+ <hr>
129
+ </div>
130
+
131
+ <div class="table-container">
132
+ <h2>Table 4</h2>
133
+ <table border="1">
134
+ <tr>
135
+ <td>Print name of shipper or shipper's agent Jesline Ang</td>
136
+ <td>Date 19 Mag25</td>
137
+ <td>Print name of consignee or consignee's agent Gavein Vanden Albeck</td>
138
+ <td>Date</td>
139
+ </tr>
140
+ <tr>
141
+ <td>Print name of shipper or shipper's agent Jesline Ang</td>
142
+ <td>Date 19 Mag25</td>
143
+ <td>Print name of consignee or consignee's agent Gavein Vanden Albeck</td>
144
+ <td>27/05/2025</td>
145
+ </tr>
146
+ <tr>
147
+ <td>Signature of shipper or shipper's agent
148
+ :selected:</td>
149
+ <td>Time</td>
150
+ <td>Signature of consignee or consignee's agent</td>
151
+ <td>Time</td>
152
+ </tr>
153
+ <tr>
154
+ <td>$
155
+ :selected:</td>
156
+ <td>1230</td>
157
+ <td>Estudia</td>
158
+ <td>gu 25</td>
159
+ </tr>
160
+ </table>
161
+ <hr>
162
+ </div>
163
+
164
+ <div class="table-container">
165
+ <h2>Table 5</h2>
166
+ <table border="1">
167
+ <tr>
168
+ <td>Company Reg. No</td>
169
+ <td>:200614708M</td>
170
+ </tr>
171
+ <tr>
172
+ <td>MGST Reg. No.</td>
173
+ <td>:20-0614708-M</td>
174
+ </tr>
175
+ </table>
176
+ <hr>
177
+ </div>
178
+
179
+ <div class="table-container">
180
+ <h2>Table 6</h2>
181
+ <table border="1">
182
+ <tr>
183
+ <td>Shipping Invoice no:</td>
184
+ <td>LBT/PI/2025/481</td>
185
+ </tr>
186
+ <tr>
187
+ <td>Dated:</td>
188
+ <td>5/19/2025</td>
189
+ </tr>
190
+ </table>
191
+ <hr>
192
+ </div>
193
+
194
+ <div class="table-container">
195
+ <h2>Table 7</h2>
196
+ <table border="1">
197
+ <tr>
198
+ <td>Contact Person :</td>
199
+ <td>Lim Ngian Gin/Jesline Ang</td>
200
+ </tr>
201
+ <tr>
202
+ <td>Telephone:</td>
203
+ <td>+6565213671/+65213959</td>
204
+ </tr>
205
+ <tr>
206
+ <td>Email:</td>
207
+ <td>Lbtshippingops.singapore@lonza.com</td>
208
+ </tr>
209
+ <tr>
210
+ <td>Freight charges</td>
211
+ <td>WC acct # 354089 (6300005106)</td>
212
+ </tr>
213
+ </table>
214
+ <hr>
215
+ </div>
216
+
217
+ <div class="table-container">
218
+ <h2>Table 8</h2>
219
+ <table border="1">
220
+ <tr>
221
+ <td>Contact Person :</td>
222
+ <td>Michelle de Meyer</td>
223
+ </tr>
224
+ <tr>
225
+ <td>Telephone:</td>
226
+ <td>+32 9 310 34 00</td>
227
+ </tr>
228
+ <tr>
229
+ <td>Email:</td>
230
+ <td>CMC.shipping@argenx.com</td>
231
+ </tr>
232
+ </table>
233
+ <hr>
234
+ </div>
235
+
236
+ <div class="table-container">
237
+ <h2>Table 9</h2>
238
+ <table border="1">
239
+ <tr>
240
+ <td>Shipper's Reference:</td>
241
+ <td>LBT/PI/2025/481</td>
242
+ </tr>
243
+ <tr>
244
+ <td>Shipping Terms:</td>
245
+ <td>Ex work</td>
246
+ </tr>
247
+ <tr>
248
+ <td>Dimension of Box (LXWXH)</td>
249
+ <td>E89 (53x35.5x44cm)</td>
250
+ </tr>
251
+ <tr>
252
+ <td>Gross Weight:</td>
253
+ <td>22 KG</td>
254
+ </tr>
255
+ <tr>
256
+ <td>No of Boxes:</td>
257
+ <td>1</td>
258
+ </tr>
259
+ <tr>
260
+ <td>Country of Origin:</td>
261
+ <td>Singapore</td>
262
+ </tr>
263
+ </table>
264
+ <hr>
265
+ </div>
266
+
267
+ <div class="table-container">
268
+ <h2>Table 10</h2>
269
+ <table border="1">
270
+ <tr>
271
+ <td>HAWB:</td>
272
+ <td>716450106</td>
273
+ </tr>
274
+ <tr>
275
+ <td>Shipment condition:</td>
276
+ <td>Dry ice</td>
277
+ </tr>
278
+ <tr>
279
+ <td>NET WT:</td>
280
+ <td>20 KG</td>
281
+ </tr>
282
+ </table>
283
+ <hr>
284
+ </div>
285
+
286
+ <div class="table-container">
287
+ <h2>Table 11</h2>
288
+ <table border="1">
289
+ <tr>
290
+ <td>Description of Goods</td>
291
+ <td>Quantity</td>
292
+ <td>Value of Goods</td>
293
+ </tr>
294
+ <tr>
295
+ <td>3060 Stability Timepoint Sample, T=12M Lot Number - 1233490 HS Code : 3002.00.00</td>
296
+ <td>4 x 2mL</td>
297
+ <td>10</td>
298
+ </tr>
299
+ <tr>
300
+ <td>Origin: CHO Genus/Species: Cricetulus Griseus The samples are mixture of highly purified Protien samples and Cell Culture fluids. The intended use of these samples is for laboratory analysis only. Material is recombinant, but contains no genes or expresses no products of exotic livestock or poultry disease agents. These samples do not come from a facility where work with exotic viruses affecting livestock and avian species is conducted .. The product was highly purified to remove all cell material, DNA and animal substances. The samples do not contain any active pharmaceutical/drug</td>
301
+ <td></td>
302
+ <td></td>
303
+ </tr>
304
+ </table>
305
+ <hr>
306
+ </div>
307
+
308
+ <div class="table-container">
309
+ <h2>Table 12</h2>
310
+ <table border="1">
311
+ <tr>
312
+ <td>Customer Code</td>
313
+ <td>Stability Protocol</td>
314
+ <td>Lot #</td>
315
+ <td>Storage Condition</td>
316
+ <td>Timepoint</td>
317
+ <td>Test</td>
318
+ <td>Aliquot Volume</td>
319
+ <td>Aliquot Container</td>
320
+ <td>Shipping Temperature (deg C)</td>
321
+ <td>LIMS ID</td>
322
+ <td></td>
323
+ </tr>
324
+ <tr>
325
+ <td>3060</td>
326
+ <td>SGTS-34842</td>
327
+ <td>1233490</td>
328
+ <td>-70 deg C</td>
329
+ <td>T=12M</td>
330
+ <td>N/A (Customer Sample)</td>
331
+ <td>:selected: 1 x 2mL</td>
332
+ <td>PP Tube</td>
333
+ <td>≤-65</td>
334
+ <td>1 BA- :selected:</td>
335
+ <td>2244197</td>
336
+ </tr>
337
+ <tr>
338
+ <td>3060</td>
339
+ <td>SGTS-34842</td>
340
+ <td>1233490</td>
341
+ <td>-40 deg C</td>
342
+ <td>T=12M</td>
343
+ <td>N/A (Customer Sample)</td>
344
+ <td>:selected: 1 x 2mL
345
+ Y</td>
346
+ <td>PP Tube</td>
347
+ <td>≤-65</td>
348
+ <td>1 FBA-
349
+ :selected:</td>
350
+ <td>2244196</td>
351
+ </tr>
352
+ <tr>
353
+ <td>3060</td>
354
+ <td>SGTS-34842</td>
355
+ <td>1233490</td>
356
+ <td>+25 deg C</td>
357
+ <td>T=12M</td>
358
+ <td>N/A (Customer Sample)</td>
359
+ <td>4
360
+ :selected: 1 x 2mL</td>
361
+ <td>PP Tube</td>
362
+ <td>≤-65</td>
363
+ <td>1 TBA- :selected:</td>
364
+ <td>2244199</td>
365
+ </tr>
366
+ <tr>
367
+ <td>3060</td>
368
+ <td>SGTS-34842</td>
369
+ <td>1233490</td>
370
+ <td>+5 deg C</td>
371
+ <td>T=12M</td>
372
+ <td>N/A (Customer Sample)</td>
373
+ <td>:selected: 1 x 2mL V</td>
374
+ <td>PP Tube</td>
375
+ <td>≤-65</td>
376
+ <td>TBA- :selected:</td>
377
+ <td>2244200</td>
378
+ </tr>
379
+ </table>
380
+ <hr>
381
+ </div>
382
+ </body></html>
logs/di_content/di_content_20250618_135405_tables.html ADDED
@@ -0,0 +1,382 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>Azure DI Tables</title>
5
+ <style>
6
+ body { font-family: Arial, sans-serif; margin: 20px; }
7
+ .table-container { margin-bottom: 40px; }
8
+ h2 { color: #333; }
9
+ table { border-collapse: collapse; width: 100%; margin-bottom: 10px; }
10
+ th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
11
+ th { background-color: #f5f5f5; }
12
+ hr { border: none; border-top: 2px solid #ccc; margin: 20px 0; }
13
+ </style>
14
+ </head>
15
+ <body>
16
+ <h1>Azure Document Intelligence Tables</h1>
17
+
18
+ <div class="table-container">
19
+ <h2>Table 1</h2>
20
+ <table border="1">
21
+ <tr>
22
+ <td>Account # 0800011357</td>
23
+ <td>Billing reference LBT/PI/2025/481; BRU354089 (6300005106)</td>
24
+ <td>Billing reference LBT/PI/2025/481; BRU354089 (6300005106)</td>
25
+ <td>Rec'd by WC (name) MIN-2</td>
26
+ <td>Rec'd by WC (name) MIN-2</td>
27
+ </tr>
28
+ <tr>
29
+ <td>From (Shipper)</td>
30
+ <td>From (Shipper)</td>
31
+ <td>To (Consignee)</td>
32
+ <td>To (Consignee)</td>
33
+ <td>To (Consignee)</td>
34
+ </tr>
35
+ <tr>
36
+ <td>Lim Ngian Gin/Jesline Ang</td>
37
+ <td>+6565213671/+65213959</td>
38
+ <td>Michelle de Meyer</td>
39
+ <td>+32 9 310 34 00</td>
40
+ <td>+32 9 310 34 00</td>
41
+ </tr>
42
+ <tr>
43
+ <td>LONZA BIOLOGICS TUAS PTE LTD</td>
44
+ <td></td>
45
+ <td>ARGENX BV</td>
46
+ <td></td>
47
+ <td></td>
48
+ </tr>
49
+ <tr>
50
+ <td>35 TUAS SOUTH AVE 6</td>
51
+ <td></td>
52
+ <td>INDUSTRIEPARK ZWIJNAARDE 7</td>
53
+ <td></td>
54
+ <td></td>
55
+ </tr>
56
+ <tr>
57
+ <td>TUAS 637377 SG</td>
58
+ <td></td>
59
+ <td>ZWIJNAARDE 9052 BE</td>
60
+ <td></td>
61
+ <td></td>
62
+ </tr>
63
+ <tr>
64
+ <td>Shipment information</td>
65
+ <td></td>
66
+ <td></td>
67
+ <td></td>
68
+ <td></td>
69
+ </tr>
70
+ <tr>
71
+ <td>Full description of contents</td>
72
+ <td></td>
73
+ <td>Special handling</td>
74
+ <td></td>
75
+ <td></td>
76
+ </tr>
77
+ <tr>
78
+ <td>PROTEIN SAMPLES, Deep Frozen Dry Ice -70C [+/-10C]</td>
79
+ <td>PROTEIN SAMPLES, Deep Frozen Dry Ice -70C [+/-10C]</td>
80
+ <td></td>
81
+ <td></td>
82
+ <td></td>
83
+ </tr>
84
+ </table>
85
+ <hr>
86
+ </div>
87
+
88
+ <div class="table-container">
89
+ <h2>Table 2</h2>
90
+ <table border="1">
91
+ <tr>
92
+ <td>Number of pieces</td>
93
+ <td>:unselected: Weight LBS</td>
94
+ <td>Dimensions</td>
95
+ <td>:selected: CM</td>
96
+ <td>Does this shipment contain dangerous goods?</td>
97
+ <td>Does this shipment contain dangerous goods?</td>
98
+ <td></td>
99
+ </tr>
100
+ <tr>
101
+ <td>1</td>
102
+ <td>:selected: 22 KGS</td>
103
+ <td>53 X 36 X 44</td>
104
+ <td>:unselected: IN</td>
105
+ <td>:unselected: NO</td>
106
+ <td>:unselected: YES (Per attached shipper's declaration)</td>
107
+ <td>:selected:
108
+ YES (Shipper's declaration not required)</td>
109
+ </tr>
110
+ </table>
111
+ <hr>
112
+ </div>
113
+
114
+ <div class="table-container">
115
+ <h2>Table 3</h2>
116
+ <table border="1">
117
+ <tr>
118
+ <td>Country of origin</td>
119
+ <td>Declared value for customs</td>
120
+ <td>Declared value for carriage Check if surcharge elected</td>
121
+ </tr>
122
+ <tr>
123
+ <td></td>
124
+ <td>10.00 USD</td>
125
+ <td>:unselected:</td>
126
+ </tr>
127
+ </table>
128
+ <hr>
129
+ </div>
130
+
131
+ <div class="table-container">
132
+ <h2>Table 4</h2>
133
+ <table border="1">
134
+ <tr>
135
+ <td>Print name of shipper or shipper's agent Jesline Ang</td>
136
+ <td>Date 19 Mag25</td>
137
+ <td>Print name of consignee or consignee's agent Gavein Vanden Albeck</td>
138
+ <td>Date</td>
139
+ </tr>
140
+ <tr>
141
+ <td>Print name of shipper or shipper's agent Jesline Ang</td>
142
+ <td>Date 19 Mag25</td>
143
+ <td>Print name of consignee or consignee's agent Gavein Vanden Albeck</td>
144
+ <td>27/05/2025</td>
145
+ </tr>
146
+ <tr>
147
+ <td>Signature of shipper or shipper's agent
148
+ :selected:</td>
149
+ <td>Time</td>
150
+ <td>Signature of consignee or consignee's agent</td>
151
+ <td>Time</td>
152
+ </tr>
153
+ <tr>
154
+ <td>$
155
+ :selected:</td>
156
+ <td>1230</td>
157
+ <td>Estudia</td>
158
+ <td>gu 25</td>
159
+ </tr>
160
+ </table>
161
+ <hr>
162
+ </div>
163
+
164
+ <div class="table-container">
165
+ <h2>Table 5</h2>
166
+ <table border="1">
167
+ <tr>
168
+ <td>Company Reg. No</td>
169
+ <td>:200614708M</td>
170
+ </tr>
171
+ <tr>
172
+ <td>MGST Reg. No.</td>
173
+ <td>:20-0614708-M</td>
174
+ </tr>
175
+ </table>
176
+ <hr>
177
+ </div>
178
+
179
+ <div class="table-container">
180
+ <h2>Table 6</h2>
181
+ <table border="1">
182
+ <tr>
183
+ <td>Shipping Invoice no:</td>
184
+ <td>LBT/PI/2025/481</td>
185
+ </tr>
186
+ <tr>
187
+ <td>Dated:</td>
188
+ <td>5/19/2025</td>
189
+ </tr>
190
+ </table>
191
+ <hr>
192
+ </div>
193
+
194
+ <div class="table-container">
195
+ <h2>Table 7</h2>
196
+ <table border="1">
197
+ <tr>
198
+ <td>Contact Person :</td>
199
+ <td>Lim Ngian Gin/Jesline Ang</td>
200
+ </tr>
201
+ <tr>
202
+ <td>Telephone:</td>
203
+ <td>+6565213671/+65213959</td>
204
+ </tr>
205
+ <tr>
206
+ <td>Email:</td>
207
+ <td>Lbtshippingops.singapore@lonza.com</td>
208
+ </tr>
209
+ <tr>
210
+ <td>Freight charges</td>
211
+ <td>WC acct # 354089 (6300005106)</td>
212
+ </tr>
213
+ </table>
214
+ <hr>
215
+ </div>
216
+
217
+ <div class="table-container">
218
+ <h2>Table 8</h2>
219
+ <table border="1">
220
+ <tr>
221
+ <td>Contact Person :</td>
222
+ <td>Michelle de Meyer</td>
223
+ </tr>
224
+ <tr>
225
+ <td>Telephone:</td>
226
+ <td>+32 9 310 34 00</td>
227
+ </tr>
228
+ <tr>
229
+ <td>Email:</td>
230
+ <td>CMC.shipping@argenx.com</td>
231
+ </tr>
232
+ </table>
233
+ <hr>
234
+ </div>
235
+
236
+ <div class="table-container">
237
+ <h2>Table 9</h2>
238
+ <table border="1">
239
+ <tr>
240
+ <td>Shipper's Reference:</td>
241
+ <td>LBT/PI/2025/481</td>
242
+ </tr>
243
+ <tr>
244
+ <td>Shipping Terms:</td>
245
+ <td>Ex work</td>
246
+ </tr>
247
+ <tr>
248
+ <td>Dimension of Box (LXWXH)</td>
249
+ <td>E89 (53x35.5x44cm)</td>
250
+ </tr>
251
+ <tr>
252
+ <td>Gross Weight:</td>
253
+ <td>22 KG</td>
254
+ </tr>
255
+ <tr>
256
+ <td>No of Boxes:</td>
257
+ <td>1</td>
258
+ </tr>
259
+ <tr>
260
+ <td>Country of Origin:</td>
261
+ <td>Singapore</td>
262
+ </tr>
263
+ </table>
264
+ <hr>
265
+ </div>
266
+
267
+ <div class="table-container">
268
+ <h2>Table 10</h2>
269
+ <table border="1">
270
+ <tr>
271
+ <td>HAWB:</td>
272
+ <td>716450106</td>
273
+ </tr>
274
+ <tr>
275
+ <td>Shipment condition:</td>
276
+ <td>Dry ice</td>
277
+ </tr>
278
+ <tr>
279
+ <td>NET WT:</td>
280
+ <td>20 KG</td>
281
+ </tr>
282
+ </table>
283
+ <hr>
284
+ </div>
285
+
286
+ <div class="table-container">
287
+ <h2>Table 11</h2>
288
+ <table border="1">
289
+ <tr>
290
+ <td>Description of Goods</td>
291
+ <td>Quantity</td>
292
+ <td>Value of Goods</td>
293
+ </tr>
294
+ <tr>
295
+ <td>3060 Stability Timepoint Sample, T=12M Lot Number - 1233490 HS Code : 3002.00.00</td>
296
+ <td>4 x 2mL</td>
297
+ <td>10</td>
298
+ </tr>
299
+ <tr>
300
+ <td>Origin: CHO Genus/Species: Cricetulus Griseus The samples are mixture of highly purified Protien samples and Cell Culture fluids. The intended use of these samples is for laboratory analysis only. Material is recombinant, but contains no genes or expresses no products of exotic livestock or poultry disease agents. These samples do not come from a facility where work with exotic viruses affecting livestock and avian species is conducted .. The product was highly purified to remove all cell material, DNA and animal substances. The samples do not contain any active pharmaceutical/drug</td>
301
+ <td></td>
302
+ <td></td>
303
+ </tr>
304
+ </table>
305
+ <hr>
306
+ </div>
307
+
308
+ <div class="table-container">
309
+ <h2>Table 12</h2>
310
+ <table border="1">
311
+ <tr>
312
+ <td>Customer Code</td>
313
+ <td>Stability Protocol</td>
314
+ <td>Lot #</td>
315
+ <td>Storage Condition</td>
316
+ <td>Timepoint</td>
317
+ <td>Test</td>
318
+ <td>Aliquot Volume</td>
319
+ <td>Aliquot Container</td>
320
+ <td>Shipping Temperature (deg C)</td>
321
+ <td>LIMS ID</td>
322
+ <td></td>
323
+ </tr>
324
+ <tr>
325
+ <td>3060</td>
326
+ <td>SGTS-34842</td>
327
+ <td>1233490</td>
328
+ <td>-70 deg C</td>
329
+ <td>T=12M</td>
330
+ <td>N/A (Customer Sample)</td>
331
+ <td>:selected: 1 x 2mL</td>
332
+ <td>PP Tube</td>
333
+ <td>≤-65</td>
334
+ <td>1 BA- :selected:</td>
335
+ <td>2244197</td>
336
+ </tr>
337
+ <tr>
338
+ <td>3060</td>
339
+ <td>SGTS-34842</td>
340
+ <td>1233490</td>
341
+ <td>-40 deg C</td>
342
+ <td>T=12M</td>
343
+ <td>N/A (Customer Sample)</td>
344
+ <td>:selected: 1 x 2mL
345
+ Y</td>
346
+ <td>PP Tube</td>
347
+ <td>≤-65</td>
348
+ <td>1 FBA-
349
+ :selected:</td>
350
+ <td>2244196</td>
351
+ </tr>
352
+ <tr>
353
+ <td>3060</td>
354
+ <td>SGTS-34842</td>
355
+ <td>1233490</td>
356
+ <td>+25 deg C</td>
357
+ <td>T=12M</td>
358
+ <td>N/A (Customer Sample)</td>
359
+ <td>4
360
+ :selected: 1 x 2mL</td>
361
+ <td>PP Tube</td>
362
+ <td>≤-65</td>
363
+ <td>1 TBA- :selected:</td>
364
+ <td>2244199</td>
365
+ </tr>
366
+ <tr>
367
+ <td>3060</td>
368
+ <td>SGTS-34842</td>
369
+ <td>1233490</td>
370
+ <td>+5 deg C</td>
371
+ <td>T=12M</td>
372
+ <td>N/A (Customer Sample)</td>
373
+ <td>:selected: 1 x 2mL V</td>
374
+ <td>PP Tube</td>
375
+ <td>≤-65</td>
376
+ <td>TBA- :selected:</td>
377
+ <td>2244200</td>
378
+ </tr>
379
+ </table>
380
+ <hr>
381
+ </div>
382
+ </body></html>
logs/di_content/di_content_20250618_142043_tables.html ADDED
@@ -0,0 +1,382 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>Azure DI Tables</title>
5
+ <style>
6
+ body { font-family: Arial, sans-serif; margin: 20px; }
7
+ .table-container { margin-bottom: 40px; }
8
+ h2 { color: #333; }
9
+ table { border-collapse: collapse; width: 100%; margin-bottom: 10px; }
10
+ th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
11
+ th { background-color: #f5f5f5; }
12
+ hr { border: none; border-top: 2px solid #ccc; margin: 20px 0; }
13
+ </style>
14
+ </head>
15
+ <body>
16
+ <h1>Azure Document Intelligence Tables</h1>
17
+
18
+ <div class="table-container">
19
+ <h2>Table 1</h2>
20
+ <table border="1">
21
+ <tr>
22
+ <td>Account # 0800011357</td>
23
+ <td>Billing reference LBT/PI/2025/481; BRU354089 (6300005106)</td>
24
+ <td>Billing reference LBT/PI/2025/481; BRU354089 (6300005106)</td>
25
+ <td>Rec'd by WC (name) MIN-2</td>
26
+ <td>Rec'd by WC (name) MIN-2</td>
27
+ </tr>
28
+ <tr>
29
+ <td>From (Shipper)</td>
30
+ <td>From (Shipper)</td>
31
+ <td>To (Consignee)</td>
32
+ <td>To (Consignee)</td>
33
+ <td>To (Consignee)</td>
34
+ </tr>
35
+ <tr>
36
+ <td>Lim Ngian Gin/Jesline Ang</td>
37
+ <td>+6565213671/+65213959</td>
38
+ <td>Michelle de Meyer</td>
39
+ <td>+32 9 310 34 00</td>
40
+ <td>+32 9 310 34 00</td>
41
+ </tr>
42
+ <tr>
43
+ <td>LONZA BIOLOGICS TUAS PTE LTD</td>
44
+ <td></td>
45
+ <td>ARGENX BV</td>
46
+ <td></td>
47
+ <td></td>
48
+ </tr>
49
+ <tr>
50
+ <td>35 TUAS SOUTH AVE 6</td>
51
+ <td></td>
52
+ <td>INDUSTRIEPARK ZWIJNAARDE 7</td>
53
+ <td></td>
54
+ <td></td>
55
+ </tr>
56
+ <tr>
57
+ <td>TUAS 637377 SG</td>
58
+ <td></td>
59
+ <td>ZWIJNAARDE 9052 BE</td>
60
+ <td></td>
61
+ <td></td>
62
+ </tr>
63
+ <tr>
64
+ <td>Shipment information</td>
65
+ <td></td>
66
+ <td></td>
67
+ <td></td>
68
+ <td></td>
69
+ </tr>
70
+ <tr>
71
+ <td>Full description of contents</td>
72
+ <td></td>
73
+ <td>Special handling</td>
74
+ <td></td>
75
+ <td></td>
76
+ </tr>
77
+ <tr>
78
+ <td>PROTEIN SAMPLES, Deep Frozen Dry Ice -70C [+/-10C]</td>
79
+ <td>PROTEIN SAMPLES, Deep Frozen Dry Ice -70C [+/-10C]</td>
80
+ <td></td>
81
+ <td></td>
82
+ <td></td>
83
+ </tr>
84
+ </table>
85
+ <hr>
86
+ </div>
87
+
88
+ <div class="table-container">
89
+ <h2>Table 2</h2>
90
+ <table border="1">
91
+ <tr>
92
+ <td>Number of pieces</td>
93
+ <td>:unselected: Weight LBS</td>
94
+ <td>Dimensions</td>
95
+ <td>:selected: CM</td>
96
+ <td>Does this shipment contain dangerous goods?</td>
97
+ <td>Does this shipment contain dangerous goods?</td>
98
+ <td></td>
99
+ </tr>
100
+ <tr>
101
+ <td>1</td>
102
+ <td>:selected: 22 KGS</td>
103
+ <td>53 X 36 X 44</td>
104
+ <td>:unselected: IN</td>
105
+ <td>:unselected: NO</td>
106
+ <td>:unselected: YES (Per attached shipper's declaration)</td>
107
+ <td>:selected:
108
+ YES (Shipper's declaration not required)</td>
109
+ </tr>
110
+ </table>
111
+ <hr>
112
+ </div>
113
+
114
+ <div class="table-container">
115
+ <h2>Table 3</h2>
116
+ <table border="1">
117
+ <tr>
118
+ <td>Country of origin</td>
119
+ <td>Declared value for customs</td>
120
+ <td>Declared value for carriage Check if surcharge elected</td>
121
+ </tr>
122
+ <tr>
123
+ <td></td>
124
+ <td>10.00 USD</td>
125
+ <td>:unselected:</td>
126
+ </tr>
127
+ </table>
128
+ <hr>
129
+ </div>
130
+
131
+ <div class="table-container">
132
+ <h2>Table 4</h2>
133
+ <table border="1">
134
+ <tr>
135
+ <td>Print name of shipper or shipper's agent Jesline Ang</td>
136
+ <td>Date 19 Mag25</td>
137
+ <td>Print name of consignee or consignee's agent Gavein Vanden Albeck</td>
138
+ <td>Date</td>
139
+ </tr>
140
+ <tr>
141
+ <td>Print name of shipper or shipper's agent Jesline Ang</td>
142
+ <td>Date 19 Mag25</td>
143
+ <td>Print name of consignee or consignee's agent Gavein Vanden Albeck</td>
144
+ <td>27/05/2025</td>
145
+ </tr>
146
+ <tr>
147
+ <td>Signature of shipper or shipper's agent
148
+ :selected:</td>
149
+ <td>Time</td>
150
+ <td>Signature of consignee or consignee's agent</td>
151
+ <td>Time</td>
152
+ </tr>
153
+ <tr>
154
+ <td>$
155
+ :selected:</td>
156
+ <td>1230</td>
157
+ <td>Estudia</td>
158
+ <td>gu 25</td>
159
+ </tr>
160
+ </table>
161
+ <hr>
162
+ </div>
163
+
164
+ <div class="table-container">
165
+ <h2>Table 5</h2>
166
+ <table border="1">
167
+ <tr>
168
+ <td>Company Reg. No</td>
169
+ <td>:200614708M</td>
170
+ </tr>
171
+ <tr>
172
+ <td>MGST Reg. No.</td>
173
+ <td>:20-0614708-M</td>
174
+ </tr>
175
+ </table>
176
+ <hr>
177
+ </div>
178
+
179
+ <div class="table-container">
180
+ <h2>Table 6</h2>
181
+ <table border="1">
182
+ <tr>
183
+ <td>Shipping Invoice no:</td>
184
+ <td>LBT/PI/2025/481</td>
185
+ </tr>
186
+ <tr>
187
+ <td>Dated:</td>
188
+ <td>5/19/2025</td>
189
+ </tr>
190
+ </table>
191
+ <hr>
192
+ </div>
193
+
194
+ <div class="table-container">
195
+ <h2>Table 7</h2>
196
+ <table border="1">
197
+ <tr>
198
+ <td>Contact Person :</td>
199
+ <td>Lim Ngian Gin/Jesline Ang</td>
200
+ </tr>
201
+ <tr>
202
+ <td>Telephone:</td>
203
+ <td>+6565213671/+65213959</td>
204
+ </tr>
205
+ <tr>
206
+ <td>Email:</td>
207
+ <td>Lbtshippingops.singapore@lonza.com</td>
208
+ </tr>
209
+ <tr>
210
+ <td>Freight charges</td>
211
+ <td>WC acct # 354089 (6300005106)</td>
212
+ </tr>
213
+ </table>
214
+ <hr>
215
+ </div>
216
+
217
+ <div class="table-container">
218
+ <h2>Table 8</h2>
219
+ <table border="1">
220
+ <tr>
221
+ <td>Contact Person :</td>
222
+ <td>Michelle de Meyer</td>
223
+ </tr>
224
+ <tr>
225
+ <td>Telephone:</td>
226
+ <td>+32 9 310 34 00</td>
227
+ </tr>
228
+ <tr>
229
+ <td>Email:</td>
230
+ <td>CMC.shipping@argenx.com</td>
231
+ </tr>
232
+ </table>
233
+ <hr>
234
+ </div>
235
+
236
+ <div class="table-container">
237
+ <h2>Table 9</h2>
238
+ <table border="1">
239
+ <tr>
240
+ <td>Shipper's Reference:</td>
241
+ <td>LBT/PI/2025/481</td>
242
+ </tr>
243
+ <tr>
244
+ <td>Shipping Terms:</td>
245
+ <td>Ex work</td>
246
+ </tr>
247
+ <tr>
248
+ <td>Dimension of Box (LXWXH)</td>
249
+ <td>E89 (53x35.5x44cm)</td>
250
+ </tr>
251
+ <tr>
252
+ <td>Gross Weight:</td>
253
+ <td>22 KG</td>
254
+ </tr>
255
+ <tr>
256
+ <td>No of Boxes:</td>
257
+ <td>1</td>
258
+ </tr>
259
+ <tr>
260
+ <td>Country of Origin:</td>
261
+ <td>Singapore</td>
262
+ </tr>
263
+ </table>
264
+ <hr>
265
+ </div>
266
+
267
+ <div class="table-container">
268
+ <h2>Table 10</h2>
269
+ <table border="1">
270
+ <tr>
271
+ <td>HAWB:</td>
272
+ <td>716450106</td>
273
+ </tr>
274
+ <tr>
275
+ <td>Shipment condition:</td>
276
+ <td>Dry ice</td>
277
+ </tr>
278
+ <tr>
279
+ <td>NET WT:</td>
280
+ <td>20 KG</td>
281
+ </tr>
282
+ </table>
283
+ <hr>
284
+ </div>
285
+
286
+ <div class="table-container">
287
+ <h2>Table 11</h2>
288
+ <table border="1">
289
+ <tr>
290
+ <td>Description of Goods</td>
291
+ <td>Quantity</td>
292
+ <td>Value of Goods</td>
293
+ </tr>
294
+ <tr>
295
+ <td>3060 Stability Timepoint Sample, T=12M Lot Number - 1233490 HS Code : 3002.00.00</td>
296
+ <td>4 x 2mL</td>
297
+ <td>10</td>
298
+ </tr>
299
+ <tr>
300
+ <td>Origin: CHO Genus/Species: Cricetulus Griseus The samples are mixture of highly purified Protien samples and Cell Culture fluids. The intended use of these samples is for laboratory analysis only. Material is recombinant, but contains no genes or expresses no products of exotic livestock or poultry disease agents. These samples do not come from a facility where work with exotic viruses affecting livestock and avian species is conducted .. The product was highly purified to remove all cell material, DNA and animal substances. The samples do not contain any active pharmaceutical/drug</td>
301
+ <td></td>
302
+ <td></td>
303
+ </tr>
304
+ </table>
305
+ <hr>
306
+ </div>
307
+
308
+ <div class="table-container">
309
+ <h2>Table 12</h2>
310
+ <table border="1">
311
+ <tr>
312
+ <td>Customer Code</td>
313
+ <td>Stability Protocol</td>
314
+ <td>Lot #</td>
315
+ <td>Storage Condition</td>
316
+ <td>Timepoint</td>
317
+ <td>Test</td>
318
+ <td>Aliquot Volume</td>
319
+ <td>Aliquot Container</td>
320
+ <td>Shipping Temperature (deg C)</td>
321
+ <td>LIMS ID</td>
322
+ <td></td>
323
+ </tr>
324
+ <tr>
325
+ <td>3060</td>
326
+ <td>SGTS-34842</td>
327
+ <td>1233490</td>
328
+ <td>-70 deg C</td>
329
+ <td>T=12M</td>
330
+ <td>N/A (Customer Sample)</td>
331
+ <td>:selected: 1 x 2mL</td>
332
+ <td>PP Tube</td>
333
+ <td>≤-65</td>
334
+ <td>1 BA- :selected:</td>
335
+ <td>2244197</td>
336
+ </tr>
337
+ <tr>
338
+ <td>3060</td>
339
+ <td>SGTS-34842</td>
340
+ <td>1233490</td>
341
+ <td>-40 deg C</td>
342
+ <td>T=12M</td>
343
+ <td>N/A (Customer Sample)</td>
344
+ <td>:selected: 1 x 2mL
345
+ Y</td>
346
+ <td>PP Tube</td>
347
+ <td>≤-65</td>
348
+ <td>1 FBA-
349
+ :selected:</td>
350
+ <td>2244196</td>
351
+ </tr>
352
+ <tr>
353
+ <td>3060</td>
354
+ <td>SGTS-34842</td>
355
+ <td>1233490</td>
356
+ <td>+25 deg C</td>
357
+ <td>T=12M</td>
358
+ <td>N/A (Customer Sample)</td>
359
+ <td>4
360
+ :selected: 1 x 2mL</td>
361
+ <td>PP Tube</td>
362
+ <td>≤-65</td>
363
+ <td>1 TBA- :selected:</td>
364
+ <td>2244199</td>
365
+ </tr>
366
+ <tr>
367
+ <td>3060</td>
368
+ <td>SGTS-34842</td>
369
+ <td>1233490</td>
370
+ <td>+5 deg C</td>
371
+ <td>T=12M</td>
372
+ <td>N/A (Customer Sample)</td>
373
+ <td>:selected: 1 x 2mL V</td>
374
+ <td>PP Tube</td>
375
+ <td>≤-65</td>
376
+ <td>TBA- :selected:</td>
377
+ <td>2244200</td>
378
+ </tr>
379
+ </table>
380
+ <hr>
381
+ </div>
382
+ </body></html>
logs/di_content/di_content_20250618_142701_tables.html ADDED
@@ -0,0 +1,1441 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>Azure DI Tables</title>
5
+ <style>
6
+ body { font-family: Arial, sans-serif; margin: 20px; }
7
+ .table-container { margin-bottom: 40px; }
8
+ h2 { color: #333; }
9
+ table { border-collapse: collapse; width: 100%; margin-bottom: 10px; }
10
+ th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
11
+ th { background-color: #f5f5f5; }
12
+ hr { border: none; border-top: 2px solid #ccc; margin: 20px 0; }
13
+ </style>
14
+ </head>
15
+ <body>
16
+ <h1>Azure Document Intelligence Tables</h1>
17
+
18
+ <div class="table-container">
19
+ <h2>Table 1</h2>
20
+ <table border="1">
21
+ <tr>
22
+ <td>l Sales quote:</td>
23
+ <td>SQ20202722</td>
24
+ </tr>
25
+ <tr>
26
+ <td>l Project code:</td>
27
+ <td>P3016</td>
28
+ </tr>
29
+ <tr>
30
+ <td>l LNB number:</td>
31
+ <td>2023.050</td>
32
+ </tr>
33
+ <tr>
34
+ <td>l Project responsible:</td>
35
+ <td>Nathan Cardon</td>
36
+ </tr>
37
+ <tr>
38
+ <td>l Report name:</td>
39
+ <td>P3016_R11_v00</td>
40
+ </tr>
41
+ </table>
42
+ <hr>
43
+ </div>
44
+
45
+ <div class="table-container">
46
+ <h2>Table 2</h2>
47
+ <table border="1">
48
+ <tr>
49
+ <td>Test sample ID client</td>
50
+ <td>Test sample ID RIC</td>
51
+ <td>Protein concentration (mg/ML)</td>
52
+ </tr>
53
+ <tr>
54
+ <td>P066_FH0.7-0-hulgG-LALAPG-FJB</td>
55
+ <td>aFH0.7_T0</td>
56
+ <td>1.0</td>
57
+ </tr>
58
+ <tr>
59
+ <td>P066_FH0.7-0-hulgG-LALAPG-FJB</td>
60
+ <td>aFH.07_T4W</td>
61
+ <td>1.0</td>
62
+ </tr>
63
+ <tr>
64
+ <td>P066_FHR-1.3B4_0-hulgG-LALAPG-FJB</td>
65
+ <td>FHR-1.3B4_T0</td>
66
+ <td>1.0</td>
67
+ </tr>
68
+ <tr>
69
+ <td>P066_FHR-1.3B4_0-hulgG-LALAPG-FJB</td>
70
+ <td>FHR-1.3B4_T4W</td>
71
+ <td>1.0</td>
72
+ </tr>
73
+ <tr>
74
+ <td>P066_L5_H12_0-hulgG-LALAPG-FJB</td>
75
+ <td>L5_H12_T0</td>
76
+ <td>1.0</td>
77
+ </tr>
78
+ <tr>
79
+ <td>P066_L5_H12_0-hulgG-LALAPG-FJB</td>
80
+ <td>L5_H12_T4W</td>
81
+ <td>1.0</td>
82
+ </tr>
83
+ <tr>
84
+ <td>P066_L5_H31-0-hulgG-LALAPG-FJB</td>
85
+ <td>L5_H31_T0</td>
86
+ <td>1.0</td>
87
+ </tr>
88
+ <tr>
89
+ <td>P066_L5_H31-0-hulgG-LALAPG-FJB</td>
90
+ <td>L5_H31_T4W</td>
91
+ <td>1.0</td>
92
+ </tr>
93
+ <tr>
94
+ <td>P066_L14_H12_0-hulgG-LALAPG-FJB</td>
95
+ <td>L14_H12_T0</td>
96
+ <td>1.0</td>
97
+ </tr>
98
+ <tr>
99
+ <td>P066_L14_H12_0-hulgG-LALAPG-FJB</td>
100
+ <td>L14_H12_T4W</td>
101
+ <td>1.0</td>
102
+ </tr>
103
+ <tr>
104
+ <td>P066_L14_H31_0-hulgG-LALAPG-FJB</td>
105
+ <td>L14_H31_T0</td>
106
+ <td>1.0</td>
107
+ </tr>
108
+ <tr>
109
+ <td>P066_L14_H31_0-hulgG-LALAPG-FJB</td>
110
+ <td>L14-H31_T4W</td>
111
+ <td>1.0</td>
112
+ </tr>
113
+ </table>
114
+ <hr>
115
+ </div>
116
+
117
+ <div class="table-container">
118
+ <h2>Table 3</h2>
119
+ <table border="1">
120
+ <tr>
121
+ <td></td>
122
+ <td>aFH.07_T0</td>
123
+ <td>aFH.07_T4W</td>
124
+ </tr>
125
+ <tr>
126
+ <td>G0-GlcNAc</td>
127
+ <td>5.0%</td>
128
+ <td>4.5%</td>
129
+ </tr>
130
+ <tr>
131
+ <td>Man5</td>
132
+ <td>56.1%</td>
133
+ <td>56.3%</td>
134
+ </tr>
135
+ <tr>
136
+ <td>Man6</td>
137
+ <td>17.6%</td>
138
+ <td>17.4%</td>
139
+ </tr>
140
+ <tr>
141
+ <td>Man7</td>
142
+ <td>20.7%</td>
143
+ <td>21.6%</td>
144
+ </tr>
145
+ <tr>
146
+ <td>Man8</td>
147
+ <td>0.6%</td>
148
+ <td>0.2%</td>
149
+ </tr>
150
+ </table>
151
+ <hr>
152
+ </div>
153
+
154
+ <div class="table-container">
155
+ <h2>Table 4</h2>
156
+ <table border="1">
157
+ <tr>
158
+ <td></td>
159
+ <td>aFH.07_T0</td>
160
+ <td>aFH.07_T4W</td>
161
+ </tr>
162
+ <tr>
163
+ <td>Unknown peak</td>
164
+ <td>0.6%</td>
165
+ <td>1.3%</td>
166
+ </tr>
167
+ <tr>
168
+ <td>HC [G0F/G0] - 2*GlcNAc</td>
169
+ <td>1.5%</td>
170
+ <td>2.0%</td>
171
+ </tr>
172
+ <tr>
173
+ <td>HC [Man5-Man5]</td>
174
+ <td>16.7%</td>
175
+ <td>16.5%</td>
176
+ </tr>
177
+ <tr>
178
+ <td>HC [G0F-Man5]</td>
179
+ <td>10.9%</td>
180
+ <td>11.9%</td>
181
+ </tr>
182
+ <tr>
183
+ <td>HC [G0F/G0] - GlcNAc</td>
184
+ <td>16.5%</td>
185
+ <td>17.2%</td>
186
+ </tr>
187
+ <tr>
188
+ <td>HC [G0F/G0]</td>
189
+ <td>6.5%</td>
190
+ <td>6.0%</td>
191
+ </tr>
192
+ <tr>
193
+ <td>HC [G0F/G0F]</td>
194
+ <td>35.5%</td>
195
+ <td>33.8%</td>
196
+ </tr>
197
+ <tr>
198
+ <td>HC [G0F/G1F]</td>
199
+ <td>6.5%</td>
200
+ <td>5.9%</td>
201
+ </tr>
202
+ <tr>
203
+ <td>HC [G1F/G1F] or HC [G0F/G2F]</td>
204
+ <td>5.0%</td>
205
+ <td>4.8%</td>
206
+ </tr>
207
+ <tr>
208
+ <td>HC [G1F/G2F]</td>
209
+ <td>0.3%</td>
210
+ <td>0.6%</td>
211
+ </tr>
212
+ </table>
213
+ <hr>
214
+ </div>
215
+
216
+ <div class="table-container">
217
+ <h2>Table 5</h2>
218
+ <table border="1">
219
+ <tr>
220
+ <td>Sequence</td>
221
+ <td>Sequence location</td>
222
+ <td>Modification</td>
223
+ <td>Relative abundance</td>
224
+ <td>Relative abundance</td>
225
+ </tr>
226
+ <tr>
227
+ <td>Sequence</td>
228
+ <td>Sequence location</td>
229
+ <td>Modification</td>
230
+ <td>aFH.07_T0</td>
231
+ <td>aFH.07_T4W</td>
232
+ </tr>
233
+ <tr>
234
+ <td>QIVLSQSPTFLSASPGEK</td>
235
+ <td>LC (001-018)</td>
236
+ <td>pyroQ</td>
237
+ <td>86.8%</td>
238
+ <td>99.7%</td>
239
+ </tr>
240
+ <tr>
241
+ <td>QIVLSQSPTFLSASPGEK</td>
242
+ <td>LC (001-018)</td>
243
+ <td></td>
244
+ <td>13.2%</td>
245
+ <td>0.3%</td>
246
+ </tr>
247
+ <tr>
248
+ <td>QVQLQQSGPGLVQPSQSLSITCTVSDFSLAR</td>
249
+ <td>HC (001-031)</td>
250
+ <td>pyroQ</td>
251
+ <td>90.0%</td>
252
+ <td>100.0%</td>
253
+ </tr>
254
+ <tr>
255
+ <td>QVQLQQSGPGLVQPSQSLSITCTVSDFSLAR</td>
256
+ <td>HC (001-031)</td>
257
+ <td></td>
258
+ <td>10.0%</td>
259
+ <td>n.d</td>
260
+ </tr>
261
+ </table>
262
+ <hr>
263
+ </div>
264
+
265
+ <div class="table-container">
266
+ <h2>Table 6</h2>
267
+ <table border="1">
268
+ <tr>
269
+ <td>Sequence</td>
270
+ <td>Sequence location</td>
271
+ <td>Modification</td>
272
+ <td>Relative abundance</td>
273
+ <td>Relative abundance</td>
274
+ </tr>
275
+ <tr>
276
+ <td>Sequence</td>
277
+ <td>Sequence location</td>
278
+ <td>Modification</td>
279
+ <td>aFH.07_T0</td>
280
+ <td>aFH.07_T4W</td>
281
+ </tr>
282
+ <tr>
283
+ <td>YMHWYQQKPGASPKPWIFATSNLASGVPAR</td>
284
+ <td>LC (31-60)</td>
285
+ <td>Oxidation [+16 Da]</td>
286
+ <td>0.9%</td>
287
+ <td>1.0%</td>
288
+ </tr>
289
+ <tr>
290
+ <td>YMHWYQQKPGASPKPWIFATSNLASGVPAR</td>
291
+ <td>LC (31-60)</td>
292
+ <td></td>
293
+ <td>99.1%</td>
294
+ <td>99.0%</td>
295
+ </tr>
296
+ </table>
297
+ <hr>
298
+ </div>
299
+
300
+ <div class="table-container">
301
+ <h2>Table 7</h2>
302
+ <table border="1">
303
+ <tr>
304
+ <td>Sequence</td>
305
+ <td>Sequence location</td>
306
+ <td>Modification</td>
307
+ <td>Relative abundance</td>
308
+ <td>Relative abundance</td>
309
+ </tr>
310
+ <tr>
311
+ <td>Sequence</td>
312
+ <td>Sequence location</td>
313
+ <td>Modification</td>
314
+ <td>aFH.07_T0</td>
315
+ <td>aFH.07_T4W</td>
316
+ </tr>
317
+ <tr>
318
+ <td>LNINKDNSK</td>
319
+ <td>HC (72-75)</td>
320
+ <td></td>
321
+ <td>99.5%</td>
322
+ <td>98.9%</td>
323
+ </tr>
324
+ <tr>
325
+ <td>LNINKDNSK</td>
326
+ <td>HC (72-75)</td>
327
+ <td>Deamidation</td>
328
+ <td>0.5%</td>
329
+ <td>1.1%</td>
330
+ </tr>
331
+ </table>
332
+ <hr>
333
+ </div>
334
+
335
+ <div class="table-container">
336
+ <h2>Table 8</h2>
337
+ <table border="1">
338
+ <tr>
339
+ <td>Sequence</td>
340
+ <td>Sequence location</td>
341
+ <td>Modification</td>
342
+ <td>Relative abundance</td>
343
+ <td>Relative abundance</td>
344
+ </tr>
345
+ <tr>
346
+ <td>Sequence</td>
347
+ <td>Sequence location</td>
348
+ <td>Modification</td>
349
+ <td>aFH.07_T0</td>
350
+ <td>aFH.07_T4W</td>
351
+ </tr>
352
+ <tr>
353
+ <td>VEAEDAATYYCQQWSIIPPTFGNGTK</td>
354
+ <td>LC (77-102)</td>
355
+ <td>GO-GICNAc</td>
356
+ <td>2.6%</td>
357
+ <td>4.0%</td>
358
+ </tr>
359
+ <tr>
360
+ <td>VEAEDAATYYCQQWSIIPPTFGNGTK</td>
361
+ <td>LC (77-102)</td>
362
+ <td>Man5</td>
363
+ <td>54.9%</td>
364
+ <td>57.3%</td>
365
+ </tr>
366
+ <tr>
367
+ <td>VEAEDAATYYCQQWSIIPPTFGNGTK</td>
368
+ <td>LC (77-102)</td>
369
+ <td>Man6</td>
370
+ <td>21.1%</td>
371
+ <td>18.8%</td>
372
+ </tr>
373
+ <tr>
374
+ <td>VEAEDAATYYCQQWSIIPPTFGNGTK</td>
375
+ <td>LC (77-102)</td>
376
+ <td>Man7</td>
377
+ <td>21.4%</td>
378
+ <td>20.0%</td>
379
+ </tr>
380
+ </table>
381
+ <hr>
382
+ </div>
383
+
384
+ <div class="table-container">
385
+ <h2>Table 9</h2>
386
+ <table border="1">
387
+ <tr>
388
+ <td>Sequence</td>
389
+ <td>Sequence location</td>
390
+ <td>Modification</td>
391
+ <td>Relative abundance</td>
392
+ <td>Relative abundance</td>
393
+ </tr>
394
+ <tr>
395
+ <td>Sequence</td>
396
+ <td>Sequence location</td>
397
+ <td>Modification</td>
398
+ <td>aFH.07_T0</td>
399
+ <td>aFH.07_T4W</td>
400
+ </tr>
401
+ <tr>
402
+ <td>MNSLQANDTAIYYCAR</td>
403
+ <td>HC (82-97)</td>
404
+ <td>Non glycosylated</td>
405
+ <td>n.d</td>
406
+ <td>n.d</td>
407
+ </tr>
408
+ <tr>
409
+ <td>MNSLQANDTAIYYCAR</td>
410
+ <td>HC (82-97)</td>
411
+ <td>G0F-GlcNAc</td>
412
+ <td>16.3%</td>
413
+ <td>20.8%</td>
414
+ </tr>
415
+ <tr>
416
+ <td>MNSLQANDTAIYYCAR</td>
417
+ <td>HC (82-97)</td>
418
+ <td>G0</td>
419
+ <td>4.2%</td>
420
+ <td>3.7%</td>
421
+ </tr>
422
+ <tr>
423
+ <td>MNSLQANDTAIYYCAR</td>
424
+ <td>HC (82-97)</td>
425
+ <td>G0F</td>
426
+ <td>36.5%</td>
427
+ <td>34.0%</td>
428
+ </tr>
429
+ <tr>
430
+ <td>MNSLQANDTAIYYCAR</td>
431
+ <td>HC (82-97)</td>
432
+ <td>G1F</td>
433
+ <td>4.9%</td>
434
+ <td>5.1%</td>
435
+ </tr>
436
+ <tr>
437
+ <td>MNSLQANDTAIYYCAR</td>
438
+ <td>HC (82-97)</td>
439
+ <td>G2F</td>
440
+ <td>5.7%</td>
441
+ <td>4.8%</td>
442
+ </tr>
443
+ <tr>
444
+ <td>MNSLQANDTAIYYCAR</td>
445
+ <td>HC (82-97)</td>
446
+ <td>Man5</td>
447
+ <td>32.4%</td>
448
+ <td>31.5%</td>
449
+ </tr>
450
+ </table>
451
+ <hr>
452
+ </div>
453
+
454
+ <div class="table-container">
455
+ <h2>Table 10</h2>
456
+ <table border="1">
457
+ <tr>
458
+ <td>Sequence</td>
459
+ <td>Sequence location</td>
460
+ <td>Modification</td>
461
+ <td>Relative abundance</td>
462
+ <td>Relative abundance</td>
463
+ </tr>
464
+ <tr>
465
+ <td>Sequence</td>
466
+ <td>Sequence location</td>
467
+ <td>Modification</td>
468
+ <td>aFH.07_T0</td>
469
+ <td>aFH.07_T4W</td>
470
+ </tr>
471
+ <tr>
472
+ <td>EEQYNSTYR</td>
473
+ <td>HC (293-301)</td>
474
+ <td>Non glycosylated</td>
475
+ <td>n.d</td>
476
+ <td>n.d</td>
477
+ </tr>
478
+ <tr>
479
+ <td>EEQYNSTYR</td>
480
+ <td>HC (293-301)</td>
481
+ <td>Man5</td>
482
+ <td>20.9%</td>
483
+ <td>22.5%</td>
484
+ </tr>
485
+ <tr>
486
+ <td>EEQYNSTYR</td>
487
+ <td>HC (293-301)</td>
488
+ <td>G0</td>
489
+ <td>n.D</td>
490
+ <td>n.d</td>
491
+ </tr>
492
+ <tr>
493
+ <td>EEQYNSTYR</td>
494
+ <td>HC (293-301)</td>
495
+ <td>G0F</td>
496
+ <td>79.1%</td>
497
+ <td>77.5%</td>
498
+ </tr>
499
+ <tr>
500
+ <td>EEQYNSTYR</td>
501
+ <td>HC (293-301)</td>
502
+ <td>G1F</td>
503
+ <td>n.d</td>
504
+ <td>n.d</td>
505
+ </tr>
506
+ <tr>
507
+ <td>EEQYNSTYR</td>
508
+ <td>HC (293-301)</td>
509
+ <td>G2F</td>
510
+ <td>n.d</td>
511
+ <td>n.d</td>
512
+ </tr>
513
+ </table>
514
+ <hr>
515
+ </div>
516
+
517
+ <div class="table-container">
518
+ <h2>Table 11</h2>
519
+ <table border="1">
520
+ <tr>
521
+ <td>Sequence</td>
522
+ <td>Sequence location</td>
523
+ <td>Modification</td>
524
+ <td>Relative abundance*</td>
525
+ <td>Relative abundance*</td>
526
+ </tr>
527
+ <tr>
528
+ <td>Sequence</td>
529
+ <td>Sequence location</td>
530
+ <td>Modification</td>
531
+ <td>aFH.07_T0</td>
532
+ <td>aFH.07_T4W</td>
533
+ </tr>
534
+ <tr>
535
+ <td>STSGGTAALGCLVK</td>
536
+ <td>HC (134-147)</td>
537
+ <td></td>
538
+ <td>99.9%</td>
539
+ <td>98.8%</td>
540
+ </tr>
541
+ <tr>
542
+ <td>GTAALGCLVK</td>
543
+ <td>HC (134-147)</td>
544
+ <td>Clipping</td>
545
+ <td>0.1%</td>
546
+ <td>1.2%</td>
547
+ </tr>
548
+ </table>
549
+ <hr>
550
+ </div>
551
+
552
+ <div class="table-container">
553
+ <h2>Table 12</h2>
554
+ <table border="1">
555
+ <tr>
556
+ <td>Blue:</td>
557
+ <td>VH and VL</td>
558
+ </tr>
559
+ <tr>
560
+ <td>Blue:</td>
561
+ <td>CDR</td>
562
+ </tr>
563
+ <tr>
564
+ <td>Green:</td>
565
+ <td>N-glycosylation site</td>
566
+ </tr>
567
+ </table>
568
+ <hr>
569
+ </div>
570
+
571
+ <div class="table-container">
572
+ <h2>Table 13</h2>
573
+ <table border="1">
574
+ <tr>
575
+ <td>Sequence</td>
576
+ <td>Sequence location</td>
577
+ <td>Modification</td>
578
+ <td>Relative abundance</td>
579
+ <td>Relative abundance</td>
580
+ </tr>
581
+ <tr>
582
+ <td>Sequence</td>
583
+ <td>Sequence location</td>
584
+ <td>Modification</td>
585
+ <td>FHR-1.3B4_T0</td>
586
+ <td>FHR-1.3B4_T4W</td>
587
+ </tr>
588
+ <tr>
589
+ <td>QIVLSQSPTILSASPGEK</td>
590
+ <td>LC (1-18)</td>
591
+ <td>pyro Q</td>
592
+ <td>96.1%</td>
593
+ <td>100.0%</td>
594
+ </tr>
595
+ <tr>
596
+ <td>QIVLSQSPTILSASPGEK</td>
597
+ <td>LC (1-18)</td>
598
+ <td></td>
599
+ <td>3.9%</td>
600
+ <td>n.d</td>
601
+ </tr>
602
+ <tr>
603
+ <td>QVQLR</td>
604
+ <td>HC (1-5)</td>
605
+ <td>pyro Q</td>
606
+ <td>96.7%</td>
607
+ <td>100.0%</td>
608
+ </tr>
609
+ <tr>
610
+ <td>QVQLR</td>
611
+ <td>HC (1-5)</td>
612
+ <td></td>
613
+ <td>3.3%</td>
614
+ <td>n.d</td>
615
+ </tr>
616
+ </table>
617
+ <hr>
618
+ </div>
619
+
620
+ <div class="table-container">
621
+ <h2>Table 14</h2>
622
+ <table border="1">
623
+ <tr>
624
+ <td>Sequence</td>
625
+ <td>Sequence location</td>
626
+ <td>Modification</td>
627
+ <td>Relative abundance</td>
628
+ <td>Relative abundance</td>
629
+ </tr>
630
+ <tr>
631
+ <td>Sequence</td>
632
+ <td>Sequence location</td>
633
+ <td>Modification</td>
634
+ <td>FHR-1.3B4_T0</td>
635
+ <td>FHR-1.3B4_T4W</td>
636
+ </tr>
637
+ <tr>
638
+ <td>MNSLQADDTAIYYCAR</td>
639
+ <td>HC (82-97)</td>
640
+ <td></td>
641
+ <td>99.3%</td>
642
+ <td>99.0%</td>
643
+ </tr>
644
+ <tr>
645
+ <td>MNSLQADDTAIYYCAR</td>
646
+ <td>HC (82-97)</td>
647
+ <td>Ox [+ 16 Da]</td>
648
+ <td>0.7%</td>
649
+ <td>1.0%</td>
650
+ </tr>
651
+ </table>
652
+ <hr>
653
+ </div>
654
+
655
+ <div class="table-container">
656
+ <h2>Table 15</h2>
657
+ <table border="1">
658
+ <tr>
659
+ <td>Sequence</td>
660
+ <td>Sequence location</td>
661
+ <td>Modification</td>
662
+ <td>Relative abundance</td>
663
+ <td>Relative abundance</td>
664
+ </tr>
665
+ <tr>
666
+ <td>Sequence</td>
667
+ <td>Sequence location</td>
668
+ <td>Modification</td>
669
+ <td>FHR-1.3B4_T0</td>
670
+ <td>FHR-1.3B4_T4W</td>
671
+ </tr>
672
+ <tr>
673
+ <td>MNSLQADDTAIYYCAR</td>
674
+ <td>HC (82-97)</td>
675
+ <td></td>
676
+ <td>97.6%</td>
677
+ <td>79.7%</td>
678
+ </tr>
679
+ <tr>
680
+ <td>MNSLQADDTAIYYCAR</td>
681
+ <td>HC (82-97)</td>
682
+ <td>Deamidation</td>
683
+ <td>2.4%</td>
684
+ <td>20.3%</td>
685
+ </tr>
686
+ </table>
687
+ <hr>
688
+ </div>
689
+
690
+ <div class="table-container">
691
+ <h2>Table 16</h2>
692
+ <table border="1">
693
+ <tr>
694
+ <td>Sequence</td>
695
+ <td>Sequence location</td>
696
+ <td>Modification</td>
697
+ <td>Relative abundance*</td>
698
+ <td>Relative abundance*</td>
699
+ </tr>
700
+ <tr>
701
+ <td>Sequence</td>
702
+ <td>Sequence location</td>
703
+ <td>Modification</td>
704
+ <td>FHR-1.3B4_T0</td>
705
+ <td>FHR-1.3B4_T4W</td>
706
+ </tr>
707
+ <tr>
708
+ <td>STSGGTAALGCLVK</td>
709
+ <td>HC (134-147)</td>
710
+ <td></td>
711
+ <td>99.9%</td>
712
+ <td>98.7%</td>
713
+ </tr>
714
+ <tr>
715
+ <td>GTAALGCLVK</td>
716
+ <td>HC (134-147)</td>
717
+ <td>Clipping</td>
718
+ <td>0.1%</td>
719
+ <td>1.3%</td>
720
+ </tr>
721
+ <tr>
722
+ <td>SSSNPLTFGAGTK</td>
723
+ <td>LC (91-103)</td>
724
+ <td></td>
725
+ <td>99.5%</td>
726
+ <td>97.3%</td>
727
+ </tr>
728
+ <tr>
729
+ <td>PLTFGAGTK</td>
730
+ <td>LC (91-103)</td>
731
+ <td>Clipping</td>
732
+ <td>0.5%</td>
733
+ <td>2.7%</td>
734
+ </tr>
735
+ </table>
736
+ <hr>
737
+ </div>
738
+
739
+ <div class="table-container">
740
+ <h2>Table 17</h2>
741
+ <table border="1">
742
+ <tr>
743
+ <td>Blue:</td>
744
+ <td>VH and VL</td>
745
+ </tr>
746
+ <tr>
747
+ <td>Blue:</td>
748
+ <td>CDR</td>
749
+ </tr>
750
+ <tr>
751
+ <td>Green:</td>
752
+ <td>N-glycosylation site</td>
753
+ </tr>
754
+ </table>
755
+ <hr>
756
+ </div>
757
+
758
+ <div class="table-container">
759
+ <h2>Table 18</h2>
760
+ <table border="1">
761
+ <tr>
762
+ <td>Sequence</td>
763
+ <td>Sequence location</td>
764
+ <td>Modification</td>
765
+ <td>Relative abundance</td>
766
+ <td>Relative abundance</td>
767
+ </tr>
768
+ <tr>
769
+ <td>Sequence</td>
770
+ <td>Sequence location</td>
771
+ <td>Modification</td>
772
+ <td>L5-H12_T0</td>
773
+ <td>L5-H12_T4w</td>
774
+ </tr>
775
+ <tr>
776
+ <td>QVQLQESGPGLVKPSQTLSLTCTVSGFSLTNYGVYWIR</td>
777
+ <td>HC (001-038)</td>
778
+ <td>pyro Q</td>
779
+ <td>85.5%</td>
780
+ <td>99.3%</td>
781
+ </tr>
782
+ <tr>
783
+ <td>QVQLQESGPGLVKPSQTLSLTCTVSGFSLTNYGVYWIR</td>
784
+ <td>HC (001-038)</td>
785
+ <td></td>
786
+ <td>14.5%</td>
787
+ <td>0.7%</td>
788
+ </tr>
789
+ </table>
790
+ <hr>
791
+ </div>
792
+
793
+ <div class="table-container">
794
+ <h2>Table 19</h2>
795
+ <table border="1">
796
+ <tr>
797
+ <td>Sequence</td>
798
+ <td>Sequence location</td>
799
+ <td>Modification</td>
800
+ <td>Relative abundance*</td>
801
+ <td>Relative abundance*</td>
802
+ </tr>
803
+ <tr>
804
+ <td>Sequence</td>
805
+ <td>Sequence location</td>
806
+ <td>Modification</td>
807
+ <td>L5-H12_T0</td>
808
+ <td>L5-H12_T4w</td>
809
+ </tr>
810
+ <tr>
811
+ <td>STSGGTAALGCLVK</td>
812
+ <td>HC (134-147)</td>
813
+ <td></td>
814
+ <td>99.9%</td>
815
+ <td>98.7%</td>
816
+ </tr>
817
+ <tr>
818
+ <td>GTAALGCLVK</td>
819
+ <td>HC (134-147)</td>
820
+ <td>Clipping</td>
821
+ <td>0.1%</td>
822
+ <td>1.3%</td>
823
+ </tr>
824
+ <tr>
825
+ <td>SSSNPLTFGAGTK</td>
826
+ <td>LC (91-103)</td>
827
+ <td></td>
828
+ <td>99.8%</td>
829
+ <td>98.9%</td>
830
+ </tr>
831
+ <tr>
832
+ <td>PLTFGAGTK</td>
833
+ <td>LC (91-103)</td>
834
+ <td>Clipping</td>
835
+ <td>0.2%</td>
836
+ <td>1.1%</td>
837
+ </tr>
838
+ </table>
839
+ <hr>
840
+ </div>
841
+
842
+ <div class="table-container">
843
+ <h2>Table 20</h2>
844
+ <table border="1">
845
+ <tr>
846
+ <td>Blue:</td>
847
+ <td>VH and VL</td>
848
+ </tr>
849
+ <tr>
850
+ <td>Blue:</td>
851
+ <td>CDR</td>
852
+ </tr>
853
+ <tr>
854
+ <td>Green:</td>
855
+ <td>N-glycosylation site</td>
856
+ </tr>
857
+ </table>
858
+ <hr>
859
+ </div>
860
+
861
+ <div class="table-container">
862
+ <h2>Table 21</h2>
863
+ <table border="1">
864
+ <tr>
865
+ <td>Sequence</td>
866
+ <td>Sequence location</td>
867
+ <td>Modification</td>
868
+ <td>Relative abundance</td>
869
+ <td>Relative abundance</td>
870
+ </tr>
871
+ <tr>
872
+ <td>Sequence</td>
873
+ <td>Sequence location</td>
874
+ <td>Modification</td>
875
+ <td>L5-H31_T0</td>
876
+ <td>L5-H31_T4w</td>
877
+ </tr>
878
+ <tr>
879
+ <td>QVQLQESGPGLVKPSQTLSLTCTVSGFSLTNYGVYWIR</td>
880
+ <td>HC (001-038)</td>
881
+ <td>pyro Q</td>
882
+ <td>83.5%</td>
883
+ <td>99.5%</td>
884
+ </tr>
885
+ <tr>
886
+ <td>QVQLQESGPGLVKPSQTLSLTCTVSGFSLTNYGVYWIR</td>
887
+ <td>HC (001-038)</td>
888
+ <td></td>
889
+ <td>16.5%</td>
890
+ <td>0.5%</td>
891
+ </tr>
892
+ </table>
893
+ <hr>
894
+ </div>
895
+
896
+ <div class="table-container">
897
+ <h2>Table 22</h2>
898
+ <table border="1">
899
+ <tr>
900
+ <td>Sequence</td>
901
+ <td>Sequence location</td>
902
+ <td>Modification</td>
903
+ <td>Relative abundance</td>
904
+ <td>Relative abundance</td>
905
+ </tr>
906
+ <tr>
907
+ <td>Sequence</td>
908
+ <td>Sequence location</td>
909
+ <td>Modification</td>
910
+ <td>L5-H31_T0</td>
911
+ <td>L5-H31_T4w</td>
912
+ </tr>
913
+ <tr>
914
+ <td>NFGNYAMDFWGQGTSVTVSSASTK</td>
915
+ <td>HC(98-121)</td>
916
+ <td>Ox. [+ 16 Da]</td>
917
+ <td>4.9%</td>
918
+ <td>1.9%</td>
919
+ </tr>
920
+ <tr>
921
+ <td>NFGNYAMDFWGQGTSVTVSSASTK</td>
922
+ <td>HC(98-121)</td>
923
+ <td></td>
924
+ <td>95.1%</td>
925
+ <td>98.1%</td>
926
+ </tr>
927
+ </table>
928
+ <hr>
929
+ </div>
930
+
931
+ <div class="table-container">
932
+ <h2>Table 23</h2>
933
+ <table border="1">
934
+ <tr>
935
+ <td>Sequence</td>
936
+ <td>Sequence location</td>
937
+ <td>Modification</td>
938
+ <td>Relative abundance</td>
939
+ <td>Relative abundance</td>
940
+ </tr>
941
+ <tr>
942
+ <td>Sequence</td>
943
+ <td>Sequence location</td>
944
+ <td>Modification</td>
945
+ <td>L5-H31_T0</td>
946
+ <td>L5-H31_T4w</td>
947
+ </tr>
948
+ <tr>
949
+ <td>SSSNPLTFGAGTK</td>
950
+ <td>LC (91-103)</td>
951
+ <td></td>
952
+ <td>99.8%</td>
953
+ <td>99.5%</td>
954
+ </tr>
955
+ <tr>
956
+ <td>SSSNPLTFGAGTK</td>
957
+ <td>LC (91-103)</td>
958
+ <td>deamidation</td>
959
+ <td>0.2%</td>
960
+ <td>0.5%</td>
961
+ </tr>
962
+ </table>
963
+ <hr>
964
+ </div>
965
+
966
+ <div class="table-container">
967
+ <h2>Table 24</h2>
968
+ <table border="1">
969
+ <tr>
970
+ <td>Sequence</td>
971
+ <td>Sequence location</td>
972
+ <td>Modification</td>
973
+ <td>Relative abundance*</td>
974
+ <td>Relative abundance*</td>
975
+ </tr>
976
+ <tr>
977
+ <td>Sequence</td>
978
+ <td>Sequence location</td>
979
+ <td>Modification</td>
980
+ <td>L5-H31_T0</td>
981
+ <td>L5-H31_T4w</td>
982
+ </tr>
983
+ <tr>
984
+ <td>STSGGTAALGCLVK</td>
985
+ <td>HC (134-147)</td>
986
+ <td></td>
987
+ <td>99.9%</td>
988
+ <td>98.8%</td>
989
+ </tr>
990
+ <tr>
991
+ <td>GTAALGCLVK</td>
992
+ <td>HC (134-147)</td>
993
+ <td>Clipping</td>
994
+ <td>0.1%</td>
995
+ <td>1.2%</td>
996
+ </tr>
997
+ <tr>
998
+ <td>SSSNPLTFGAGTK</td>
999
+ <td>LC (91-103)</td>
1000
+ <td></td>
1001
+ <td>99.9%</td>
1002
+ <td>98.8%</td>
1003
+ </tr>
1004
+ <tr>
1005
+ <td>PLTFGAGTK</td>
1006
+ <td>LC (91-103)</td>
1007
+ <td>Clipping</td>
1008
+ <td>0.1%</td>
1009
+ <td>1.2%</td>
1010
+ </tr>
1011
+ </table>
1012
+ <hr>
1013
+ </div>
1014
+
1015
+ <div class="table-container">
1016
+ <h2>Table 25</h2>
1017
+ <table border="1">
1018
+ <tr>
1019
+ <td>Blue:</td>
1020
+ <td>VH and VL</td>
1021
+ </tr>
1022
+ <tr>
1023
+ <td>Blue:</td>
1024
+ <td>CDR</td>
1025
+ </tr>
1026
+ <tr>
1027
+ <td>Green:</td>
1028
+ <td>N-glycosylation site</td>
1029
+ </tr>
1030
+ </table>
1031
+ <hr>
1032
+ </div>
1033
+
1034
+ <div class="table-container">
1035
+ <h2>Table 26</h2>
1036
+ <table border="1">
1037
+ <tr>
1038
+ <td>Sequence</td>
1039
+ <td>Sequence location</td>
1040
+ <td>Modification</td>
1041
+ <td>Relative abundance</td>
1042
+ <td>Relative abundance</td>
1043
+ </tr>
1044
+ <tr>
1045
+ <td>Sequence</td>
1046
+ <td>Sequence location</td>
1047
+ <td>Modification</td>
1048
+ <td>L14-H12_T0</td>
1049
+ <td>L14-H12_T4w</td>
1050
+ </tr>
1051
+ <tr>
1052
+ <td>QVQLQESGPGLVKPSQTLSLTCTVSGFSLTNYGVYWIR</td>
1053
+ <td>HC(001-038)</td>
1054
+ <td>pyroQ</td>
1055
+ <td>85.9%</td>
1056
+ <td>99.3%</td>
1057
+ </tr>
1058
+ <tr>
1059
+ <td>QVQLQESGPGLVKPSQTLSLTCTVSGFSLTNYGVYWIR</td>
1060
+ <td>HC(001-038)</td>
1061
+ <td></td>
1062
+ <td>14.1%</td>
1063
+ <td>0.7%</td>
1064
+ </tr>
1065
+ </table>
1066
+ <hr>
1067
+ </div>
1068
+
1069
+ <div class="table-container">
1070
+ <h2>Table 27</h2>
1071
+ <table border="1">
1072
+ <tr>
1073
+ <td>Sequence</td>
1074
+ <td>Sequence location</td>
1075
+ <td>Modification</td>
1076
+ <td>Relative abundance</td>
1077
+ <td>Relative abundance</td>
1078
+ </tr>
1079
+ <tr>
1080
+ <td>Sequence</td>
1081
+ <td>Sequence location</td>
1082
+ <td>Modification</td>
1083
+ <td>L14-H12_T0</td>
1084
+ <td>L14-H12_T4w</td>
1085
+ </tr>
1086
+ <tr>
1087
+ <td>ASTSVTYMHWYQQKPGK</td>
1088
+ <td>LC(25-41)</td>
1089
+ <td>Ox. [+16 Da]</td>
1090
+ <td>0.3%</td>
1091
+ <td>0.3%</td>
1092
+ </tr>
1093
+ <tr>
1094
+ <td>ASTSVTYMHWYQQKPGK</td>
1095
+ <td>LC(25-41)</td>
1096
+ <td></td>
1097
+ <td>99.7%</td>
1098
+ <td>99.7%</td>
1099
+ </tr>
1100
+ </table>
1101
+ <hr>
1102
+ </div>
1103
+
1104
+ <div class="table-container">
1105
+ <h2>Table 28</h2>
1106
+ <table border="1">
1107
+ <tr>
1108
+ <td>Sequence</td>
1109
+ <td>Sequence location</td>
1110
+ <td>Modification</td>
1111
+ <td>Relative abundance</td>
1112
+ <td>Relative abundance</td>
1113
+ </tr>
1114
+ <tr>
1115
+ <td>Sequence</td>
1116
+ <td>Sequence location</td>
1117
+ <td>Modification</td>
1118
+ <td>L14-H12_T0</td>
1119
+ <td>L14-H12_T4w</td>
1120
+ </tr>
1121
+ <tr>
1122
+ <td>SSSNPLTFGAGTK</td>
1123
+ <td>LC (91-103)</td>
1124
+ <td></td>
1125
+ <td>99.9%</td>
1126
+ <td>99.4%</td>
1127
+ </tr>
1128
+ <tr>
1129
+ <td>SSSNPLTFGAGTK</td>
1130
+ <td>LC (91-103)</td>
1131
+ <td>deamidation</td>
1132
+ <td>0.1%</td>
1133
+ <td>0.6%</td>
1134
+ </tr>
1135
+ </table>
1136
+ <hr>
1137
+ </div>
1138
+
1139
+ <div class="table-container">
1140
+ <h2>Table 29</h2>
1141
+ <table border="1">
1142
+ <tr>
1143
+ <td>Sequence</td>
1144
+ <td>Sequence location</td>
1145
+ <td>Modification</td>
1146
+ <td>Relative abundance*</td>
1147
+ <td>Relative abundance*</td>
1148
+ </tr>
1149
+ <tr>
1150
+ <td>Sequence</td>
1151
+ <td>Sequence location</td>
1152
+ <td>Modification</td>
1153
+ <td>L14-H12_T0</td>
1154
+ <td>L14-H12_T4w</td>
1155
+ </tr>
1156
+ <tr>
1157
+ <td>STSGGTAALGCLVK</td>
1158
+ <td>HC (134-147)</td>
1159
+ <td></td>
1160
+ <td>99.9%</td>
1161
+ <td>98.9%</td>
1162
+ </tr>
1163
+ <tr>
1164
+ <td>GTAALGCLVK</td>
1165
+ <td>HC (134-147)</td>
1166
+ <td>Clipping</td>
1167
+ <td>0.1%</td>
1168
+ <td>1.1%</td>
1169
+ </tr>
1170
+ <tr>
1171
+ <td>SSSNPLTFGAGTK</td>
1172
+ <td>LC (91-103)</td>
1173
+ <td></td>
1174
+ <td>99.7%</td>
1175
+ <td>98.6%</td>
1176
+ </tr>
1177
+ <tr>
1178
+ <td>PLTFGAGTK</td>
1179
+ <td>LC (91-103)</td>
1180
+ <td>Clipping</td>
1181
+ <td>0.3%</td>
1182
+ <td>1.4%</td>
1183
+ </tr>
1184
+ </table>
1185
+ <hr>
1186
+ </div>
1187
+
1188
+ <div class="table-container">
1189
+ <h2>Table 30</h2>
1190
+ <table border="1">
1191
+ <tr>
1192
+ <td>Blue:</td>
1193
+ <td>VH and VL</td>
1194
+ </tr>
1195
+ <tr>
1196
+ <td>Blue:</td>
1197
+ <td>CDR</td>
1198
+ </tr>
1199
+ <tr>
1200
+ <td>Green:</td>
1201
+ <td>N-glycosylation site</td>
1202
+ </tr>
1203
+ </table>
1204
+ <hr>
1205
+ </div>
1206
+
1207
+ <div class="table-container">
1208
+ <h2>Table 31</h2>
1209
+ <table border="1">
1210
+ <tr>
1211
+ <td>Sequence</td>
1212
+ <td>Sequence location</td>
1213
+ <td>Modification</td>
1214
+ <td>Relative abundance</td>
1215
+ <td>Relative abundance</td>
1216
+ </tr>
1217
+ <tr>
1218
+ <td>Sequence</td>
1219
+ <td>Sequence location</td>
1220
+ <td>Modification</td>
1221
+ <td>L14-H31_T0</td>
1222
+ <td>L14-H31_T4w</td>
1223
+ </tr>
1224
+ <tr>
1225
+ <td>QVQLQESGPGLVKPSQTLSLTCTVSGFSLTNYGVYWIR</td>
1226
+ <td>HC(001-038)</td>
1227
+ <td>pyroQ</td>
1228
+ <td>82.6%</td>
1229
+ <td>100.0%</td>
1230
+ </tr>
1231
+ <tr>
1232
+ <td>QVQLQESGPGLVKPSQTLSLTCTVSGFSLTNYGVYWIR</td>
1233
+ <td>HC(001-038)</td>
1234
+ <td></td>
1235
+ <td>17.4%</td>
1236
+ <td>n.d</td>
1237
+ </tr>
1238
+ </table>
1239
+ <hr>
1240
+ </div>
1241
+
1242
+ <div class="table-container">
1243
+ <h2>Table 32</h2>
1244
+ <table border="1">
1245
+ <tr>
1246
+ <td>Sequence</td>
1247
+ <td>Sequence location</td>
1248
+ <td>Modification</td>
1249
+ <td>Relative abundance</td>
1250
+ <td>Relative abundance</td>
1251
+ </tr>
1252
+ <tr>
1253
+ <td>Sequence</td>
1254
+ <td>Sequence location</td>
1255
+ <td>Modification</td>
1256
+ <td>L14-H31_T0</td>
1257
+ <td>L14-H31_T4w</td>
1258
+ </tr>
1259
+ <tr>
1260
+ <td>ASTSVTYMHWYQQKPGK</td>
1261
+ <td>LC(25-41)</td>
1262
+ <td>Ox. [+16 Da]</td>
1263
+ <td>0.5%</td>
1264
+ <td>0.4%</td>
1265
+ </tr>
1266
+ <tr>
1267
+ <td>ASTSVTYMHWYQQKPGK</td>
1268
+ <td>LC(25-41)</td>
1269
+ <td></td>
1270
+ <td>99.5%</td>
1271
+ <td>99.6%</td>
1272
+ </tr>
1273
+ </table>
1274
+ <hr>
1275
+ </div>
1276
+
1277
+ <div class="table-container">
1278
+ <h2>Table 33</h2>
1279
+ <table border="1">
1280
+ <tr>
1281
+ <td>Sequence</td>
1282
+ <td>Sequence location</td>
1283
+ <td>Modification</td>
1284
+ <td>Relative abundance</td>
1285
+ <td>Relative abundance</td>
1286
+ </tr>
1287
+ <tr>
1288
+ <td>Sequence</td>
1289
+ <td>Sequence location</td>
1290
+ <td>Modification</td>
1291
+ <td>L14-H31_T0</td>
1292
+ <td>L14-H31_T4w</td>
1293
+ </tr>
1294
+ <tr>
1295
+ <td>SSSNPLTFGAGTK</td>
1296
+ <td>LC (91-103)</td>
1297
+ <td></td>
1298
+ <td>99.9%</td>
1299
+ <td>99.5%</td>
1300
+ </tr>
1301
+ <tr>
1302
+ <td>SSSNPLTFGAGTK</td>
1303
+ <td>LC (91-103)</td>
1304
+ <td>deamidation</td>
1305
+ <td>0.1%</td>
1306
+ <td>0.5%</td>
1307
+ </tr>
1308
+ </table>
1309
+ <hr>
1310
+ </div>
1311
+
1312
+ <div class="table-container">
1313
+ <h2>Table 34</h2>
1314
+ <table border="1">
1315
+ <tr>
1316
+ <td>Sequence</td>
1317
+ <td>Sequence location</td>
1318
+ <td>Modification</td>
1319
+ <td>Relative abundance*</td>
1320
+ <td>Relative abundance*</td>
1321
+ </tr>
1322
+ <tr>
1323
+ <td>Sequence</td>
1324
+ <td>Sequence location</td>
1325
+ <td>Modification</td>
1326
+ <td>L14-H31_T0</td>
1327
+ <td>L14-H31_T4w</td>
1328
+ </tr>
1329
+ <tr>
1330
+ <td>STSGGTAALGCLVK</td>
1331
+ <td>HC (134-147)</td>
1332
+ <td></td>
1333
+ <td>99.9%</td>
1334
+ <td>98.9%</td>
1335
+ </tr>
1336
+ <tr>
1337
+ <td>GTAALGCLVK</td>
1338
+ <td>HC (134-147)</td>
1339
+ <td>Clipping</td>
1340
+ <td>0.1%</td>
1341
+ <td>1.1%</td>
1342
+ </tr>
1343
+ <tr>
1344
+ <td>SSSNPLTFGAGTK</td>
1345
+ <td>LC (91-103)</td>
1346
+ <td></td>
1347
+ <td>99.7%</td>
1348
+ <td>98.4%</td>
1349
+ </tr>
1350
+ <tr>
1351
+ <td>PLTFGAGTK</td>
1352
+ <td>LC (91-103)</td>
1353
+ <td>Clipping</td>
1354
+ <td>0.3%</td>
1355
+ <td>1.6%</td>
1356
+ </tr>
1357
+ </table>
1358
+ <hr>
1359
+ </div>
1360
+
1361
+ <div class="table-container">
1362
+ <h2>Table 35</h2>
1363
+ <table border="1">
1364
+ <tr>
1365
+ <td>Blue:</td>
1366
+ <td>VH and VL</td>
1367
+ </tr>
1368
+ <tr>
1369
+ <td>Blue:</td>
1370
+ <td>CDR</td>
1371
+ </tr>
1372
+ <tr>
1373
+ <td>Green:</td>
1374
+ <td>N-glycosylation site</td>
1375
+ </tr>
1376
+ </table>
1377
+ <hr>
1378
+ </div>
1379
+
1380
+ <div class="table-container">
1381
+ <h2>Table 36</h2>
1382
+ <table border="1">
1383
+ <tr>
1384
+ <td>Nathan Cardon</td>
1385
+ <td>Date:</td>
1386
+ </tr>
1387
+ <tr>
1388
+ <td>Sr Research Associate</td>
1389
+ <td>Signature:</td>
1390
+ </tr>
1391
+ <tr>
1392
+ <td>Mabelle Meersseman</td>
1393
+ <td>Date:</td>
1394
+ </tr>
1395
+ <tr>
1396
+ <td>Group Leader</td>
1397
+ <td>Signature:</td>
1398
+ </tr>
1399
+ <tr>
1400
+ <td>Approver</td>
1401
+ <td></td>
1402
+ </tr>
1403
+ <tr>
1404
+ <td>Koen Sandra Ph.D.</td>
1405
+ <td>Date:</td>
1406
+ </tr>
1407
+ <tr>
1408
+ <td>CEO</td>
1409
+ <td>Signature:</td>
1410
+ </tr>
1411
+ </table>
1412
+ <hr>
1413
+ </div>
1414
+
1415
+ <div class="table-container">
1416
+ <h2>Table 37</h2>
1417
+ <table border="1">
1418
+ <tr>
1419
+ <td>Version</td>
1420
+ <td>Date of issue</td>
1421
+ <td>Reason for version update</td>
1422
+ </tr>
1423
+ <tr>
1424
+ <td>00</td>
1425
+ <td>25NOV24</td>
1426
+ <td>Draft</td>
1427
+ </tr>
1428
+ <tr>
1429
+ <td></td>
1430
+ <td></td>
1431
+ <td></td>
1432
+ </tr>
1433
+ <tr>
1434
+ <td></td>
1435
+ <td></td>
1436
+ <td></td>
1437
+ </tr>
1438
+ </table>
1439
+ <hr>
1440
+ </div>
1441
+ </body></html>
logs/di_content/di_content_20250618_143852_tables.html ADDED
@@ -0,0 +1,1441 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>Azure DI Tables</title>
5
+ <style>
6
+ body { font-family: Arial, sans-serif; margin: 20px; }
7
+ .table-container { margin-bottom: 40px; }
8
+ h2 { color: #333; }
9
+ table { border-collapse: collapse; width: 100%; margin-bottom: 10px; }
10
+ th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
11
+ th { background-color: #f5f5f5; }
12
+ hr { border: none; border-top: 2px solid #ccc; margin: 20px 0; }
13
+ </style>
14
+ </head>
15
+ <body>
16
+ <h1>Azure Document Intelligence Tables</h1>
17
+
18
+ <div class="table-container">
19
+ <h2>Table 1</h2>
20
+ <table border="1">
21
+ <tr>
22
+ <td>l Sales quote:</td>
23
+ <td>SQ20202722</td>
24
+ </tr>
25
+ <tr>
26
+ <td>l Project code:</td>
27
+ <td>P3016</td>
28
+ </tr>
29
+ <tr>
30
+ <td>l LNB number:</td>
31
+ <td>2023.050</td>
32
+ </tr>
33
+ <tr>
34
+ <td>l Project responsible:</td>
35
+ <td>Nathan Cardon</td>
36
+ </tr>
37
+ <tr>
38
+ <td>l Report name:</td>
39
+ <td>P3016_R11_v00</td>
40
+ </tr>
41
+ </table>
42
+ <hr>
43
+ </div>
44
+
45
+ <div class="table-container">
46
+ <h2>Table 2</h2>
47
+ <table border="1">
48
+ <tr>
49
+ <td>Test sample ID client</td>
50
+ <td>Test sample ID RIC</td>
51
+ <td>Protein concentration (mg/ML)</td>
52
+ </tr>
53
+ <tr>
54
+ <td>P066_FH0.7-0-hulgG-LALAPG-FJB</td>
55
+ <td>aFH0.7_T0</td>
56
+ <td>1.0</td>
57
+ </tr>
58
+ <tr>
59
+ <td>P066_FH0.7-0-hulgG-LALAPG-FJB</td>
60
+ <td>aFH.07_T4W</td>
61
+ <td>1.0</td>
62
+ </tr>
63
+ <tr>
64
+ <td>P066_FHR-1.3B4_0-hulgG-LALAPG-FJB</td>
65
+ <td>FHR-1.3B4_T0</td>
66
+ <td>1.0</td>
67
+ </tr>
68
+ <tr>
69
+ <td>P066_FHR-1.3B4_0-hulgG-LALAPG-FJB</td>
70
+ <td>FHR-1.3B4_T4W</td>
71
+ <td>1.0</td>
72
+ </tr>
73
+ <tr>
74
+ <td>P066_L5_H12_0-hulgG-LALAPG-FJB</td>
75
+ <td>L5_H12_T0</td>
76
+ <td>1.0</td>
77
+ </tr>
78
+ <tr>
79
+ <td>P066_L5_H12_0-hulgG-LALAPG-FJB</td>
80
+ <td>L5_H12_T4W</td>
81
+ <td>1.0</td>
82
+ </tr>
83
+ <tr>
84
+ <td>P066_L5_H31-0-hulgG-LALAPG-FJB</td>
85
+ <td>L5_H31_T0</td>
86
+ <td>1.0</td>
87
+ </tr>
88
+ <tr>
89
+ <td>P066_L5_H31-0-hulgG-LALAPG-FJB</td>
90
+ <td>L5_H31_T4W</td>
91
+ <td>1.0</td>
92
+ </tr>
93
+ <tr>
94
+ <td>P066_L14_H12_0-hulgG-LALAPG-FJB</td>
95
+ <td>L14_H12_T0</td>
96
+ <td>1.0</td>
97
+ </tr>
98
+ <tr>
99
+ <td>P066_L14_H12_0-hulgG-LALAPG-FJB</td>
100
+ <td>L14_H12_T4W</td>
101
+ <td>1.0</td>
102
+ </tr>
103
+ <tr>
104
+ <td>P066_L14_H31_0-hulgG-LALAPG-FJB</td>
105
+ <td>L14_H31_T0</td>
106
+ <td>1.0</td>
107
+ </tr>
108
+ <tr>
109
+ <td>P066_L14_H31_0-hulgG-LALAPG-FJB</td>
110
+ <td>L14-H31_T4W</td>
111
+ <td>1.0</td>
112
+ </tr>
113
+ </table>
114
+ <hr>
115
+ </div>
116
+
117
+ <div class="table-container">
118
+ <h2>Table 3</h2>
119
+ <table border="1">
120
+ <tr>
121
+ <td></td>
122
+ <td>aFH.07_T0</td>
123
+ <td>aFH.07_T4W</td>
124
+ </tr>
125
+ <tr>
126
+ <td>G0-GlcNAc</td>
127
+ <td>5.0%</td>
128
+ <td>4.5%</td>
129
+ </tr>
130
+ <tr>
131
+ <td>Man5</td>
132
+ <td>56.1%</td>
133
+ <td>56.3%</td>
134
+ </tr>
135
+ <tr>
136
+ <td>Man6</td>
137
+ <td>17.6%</td>
138
+ <td>17.4%</td>
139
+ </tr>
140
+ <tr>
141
+ <td>Man7</td>
142
+ <td>20.7%</td>
143
+ <td>21.6%</td>
144
+ </tr>
145
+ <tr>
146
+ <td>Man8</td>
147
+ <td>0.6%</td>
148
+ <td>0.2%</td>
149
+ </tr>
150
+ </table>
151
+ <hr>
152
+ </div>
153
+
154
+ <div class="table-container">
155
+ <h2>Table 4</h2>
156
+ <table border="1">
157
+ <tr>
158
+ <td></td>
159
+ <td>aFH.07_T0</td>
160
+ <td>aFH.07_T4W</td>
161
+ </tr>
162
+ <tr>
163
+ <td>Unknown peak</td>
164
+ <td>0.6%</td>
165
+ <td>1.3%</td>
166
+ </tr>
167
+ <tr>
168
+ <td>HC [G0F/G0] - 2*GlcNAc</td>
169
+ <td>1.5%</td>
170
+ <td>2.0%</td>
171
+ </tr>
172
+ <tr>
173
+ <td>HC [Man5-Man5]</td>
174
+ <td>16.7%</td>
175
+ <td>16.5%</td>
176
+ </tr>
177
+ <tr>
178
+ <td>HC [G0F-Man5]</td>
179
+ <td>10.9%</td>
180
+ <td>11.9%</td>
181
+ </tr>
182
+ <tr>
183
+ <td>HC [G0F/G0] - GlcNAc</td>
184
+ <td>16.5%</td>
185
+ <td>17.2%</td>
186
+ </tr>
187
+ <tr>
188
+ <td>HC [G0F/G0]</td>
189
+ <td>6.5%</td>
190
+ <td>6.0%</td>
191
+ </tr>
192
+ <tr>
193
+ <td>HC [G0F/G0F]</td>
194
+ <td>35.5%</td>
195
+ <td>33.8%</td>
196
+ </tr>
197
+ <tr>
198
+ <td>HC [G0F/G1F]</td>
199
+ <td>6.5%</td>
200
+ <td>5.9%</td>
201
+ </tr>
202
+ <tr>
203
+ <td>HC [G1F/G1F] or HC [G0F/G2F]</td>
204
+ <td>5.0%</td>
205
+ <td>4.8%</td>
206
+ </tr>
207
+ <tr>
208
+ <td>HC [G1F/G2F]</td>
209
+ <td>0.3%</td>
210
+ <td>0.6%</td>
211
+ </tr>
212
+ </table>
213
+ <hr>
214
+ </div>
215
+
216
+ <div class="table-container">
217
+ <h2>Table 5</h2>
218
+ <table border="1">
219
+ <tr>
220
+ <td>Sequence</td>
221
+ <td>Sequence location</td>
222
+ <td>Modification</td>
223
+ <td>Relative abundance</td>
224
+ <td>Relative abundance</td>
225
+ </tr>
226
+ <tr>
227
+ <td>Sequence</td>
228
+ <td>Sequence location</td>
229
+ <td>Modification</td>
230
+ <td>aFH.07_T0</td>
231
+ <td>aFH.07_T4W</td>
232
+ </tr>
233
+ <tr>
234
+ <td>QIVLSQSPTFLSASPGEK</td>
235
+ <td>LC (001-018)</td>
236
+ <td>pyroQ</td>
237
+ <td>86.8%</td>
238
+ <td>99.7%</td>
239
+ </tr>
240
+ <tr>
241
+ <td>QIVLSQSPTFLSASPGEK</td>
242
+ <td>LC (001-018)</td>
243
+ <td></td>
244
+ <td>13.2%</td>
245
+ <td>0.3%</td>
246
+ </tr>
247
+ <tr>
248
+ <td>QVQLQQSGPGLVQPSQSLSITCTVSDFSLAR</td>
249
+ <td>HC (001-031)</td>
250
+ <td>pyroQ</td>
251
+ <td>90.0%</td>
252
+ <td>100.0%</td>
253
+ </tr>
254
+ <tr>
255
+ <td>QVQLQQSGPGLVQPSQSLSITCTVSDFSLAR</td>
256
+ <td>HC (001-031)</td>
257
+ <td></td>
258
+ <td>10.0%</td>
259
+ <td>n.d</td>
260
+ </tr>
261
+ </table>
262
+ <hr>
263
+ </div>
264
+
265
+ <div class="table-container">
266
+ <h2>Table 6</h2>
267
+ <table border="1">
268
+ <tr>
269
+ <td>Sequence</td>
270
+ <td>Sequence location</td>
271
+ <td>Modification</td>
272
+ <td>Relative abundance</td>
273
+ <td>Relative abundance</td>
274
+ </tr>
275
+ <tr>
276
+ <td>Sequence</td>
277
+ <td>Sequence location</td>
278
+ <td>Modification</td>
279
+ <td>aFH.07_T0</td>
280
+ <td>aFH.07_T4W</td>
281
+ </tr>
282
+ <tr>
283
+ <td>YMHWYQQKPGASPKPWIFATSNLASGVPAR</td>
284
+ <td>LC (31-60)</td>
285
+ <td>Oxidation [+16 Da]</td>
286
+ <td>0.9%</td>
287
+ <td>1.0%</td>
288
+ </tr>
289
+ <tr>
290
+ <td>YMHWYQQKPGASPKPWIFATSNLASGVPAR</td>
291
+ <td>LC (31-60)</td>
292
+ <td></td>
293
+ <td>99.1%</td>
294
+ <td>99.0%</td>
295
+ </tr>
296
+ </table>
297
+ <hr>
298
+ </div>
299
+
300
+ <div class="table-container">
301
+ <h2>Table 7</h2>
302
+ <table border="1">
303
+ <tr>
304
+ <td>Sequence</td>
305
+ <td>Sequence location</td>
306
+ <td>Modification</td>
307
+ <td>Relative abundance</td>
308
+ <td>Relative abundance</td>
309
+ </tr>
310
+ <tr>
311
+ <td>Sequence</td>
312
+ <td>Sequence location</td>
313
+ <td>Modification</td>
314
+ <td>aFH.07_T0</td>
315
+ <td>aFH.07_T4W</td>
316
+ </tr>
317
+ <tr>
318
+ <td>LNINKDNSK</td>
319
+ <td>HC (72-75)</td>
320
+ <td></td>
321
+ <td>99.5%</td>
322
+ <td>98.9%</td>
323
+ </tr>
324
+ <tr>
325
+ <td>LNINKDNSK</td>
326
+ <td>HC (72-75)</td>
327
+ <td>Deamidation</td>
328
+ <td>0.5%</td>
329
+ <td>1.1%</td>
330
+ </tr>
331
+ </table>
332
+ <hr>
333
+ </div>
334
+
335
+ <div class="table-container">
336
+ <h2>Table 8</h2>
337
+ <table border="1">
338
+ <tr>
339
+ <td>Sequence</td>
340
+ <td>Sequence location</td>
341
+ <td>Modification</td>
342
+ <td>Relative abundance</td>
343
+ <td>Relative abundance</td>
344
+ </tr>
345
+ <tr>
346
+ <td>Sequence</td>
347
+ <td>Sequence location</td>
348
+ <td>Modification</td>
349
+ <td>aFH.07_T0</td>
350
+ <td>aFH.07_T4W</td>
351
+ </tr>
352
+ <tr>
353
+ <td>VEAEDAATYYCQQWSIIPPTFGNGTK</td>
354
+ <td>LC (77-102)</td>
355
+ <td>GO-GICNAc</td>
356
+ <td>2.6%</td>
357
+ <td>4.0%</td>
358
+ </tr>
359
+ <tr>
360
+ <td>VEAEDAATYYCQQWSIIPPTFGNGTK</td>
361
+ <td>LC (77-102)</td>
362
+ <td>Man5</td>
363
+ <td>54.9%</td>
364
+ <td>57.3%</td>
365
+ </tr>
366
+ <tr>
367
+ <td>VEAEDAATYYCQQWSIIPPTFGNGTK</td>
368
+ <td>LC (77-102)</td>
369
+ <td>Man6</td>
370
+ <td>21.1%</td>
371
+ <td>18.8%</td>
372
+ </tr>
373
+ <tr>
374
+ <td>VEAEDAATYYCQQWSIIPPTFGNGTK</td>
375
+ <td>LC (77-102)</td>
376
+ <td>Man7</td>
377
+ <td>21.4%</td>
378
+ <td>20.0%</td>
379
+ </tr>
380
+ </table>
381
+ <hr>
382
+ </div>
383
+
384
+ <div class="table-container">
385
+ <h2>Table 9</h2>
386
+ <table border="1">
387
+ <tr>
388
+ <td>Sequence</td>
389
+ <td>Sequence location</td>
390
+ <td>Modification</td>
391
+ <td>Relative abundance</td>
392
+ <td>Relative abundance</td>
393
+ </tr>
394
+ <tr>
395
+ <td>Sequence</td>
396
+ <td>Sequence location</td>
397
+ <td>Modification</td>
398
+ <td>aFH.07_T0</td>
399
+ <td>aFH.07_T4W</td>
400
+ </tr>
401
+ <tr>
402
+ <td>MNSLQANDTAIYYCAR</td>
403
+ <td>HC (82-97)</td>
404
+ <td>Non glycosylated</td>
405
+ <td>n.d</td>
406
+ <td>n.d</td>
407
+ </tr>
408
+ <tr>
409
+ <td>MNSLQANDTAIYYCAR</td>
410
+ <td>HC (82-97)</td>
411
+ <td>G0F-GlcNAc</td>
412
+ <td>16.3%</td>
413
+ <td>20.8%</td>
414
+ </tr>
415
+ <tr>
416
+ <td>MNSLQANDTAIYYCAR</td>
417
+ <td>HC (82-97)</td>
418
+ <td>G0</td>
419
+ <td>4.2%</td>
420
+ <td>3.7%</td>
421
+ </tr>
422
+ <tr>
423
+ <td>MNSLQANDTAIYYCAR</td>
424
+ <td>HC (82-97)</td>
425
+ <td>G0F</td>
426
+ <td>36.5%</td>
427
+ <td>34.0%</td>
428
+ </tr>
429
+ <tr>
430
+ <td>MNSLQANDTAIYYCAR</td>
431
+ <td>HC (82-97)</td>
432
+ <td>G1F</td>
433
+ <td>4.9%</td>
434
+ <td>5.1%</td>
435
+ </tr>
436
+ <tr>
437
+ <td>MNSLQANDTAIYYCAR</td>
438
+ <td>HC (82-97)</td>
439
+ <td>G2F</td>
440
+ <td>5.7%</td>
441
+ <td>4.8%</td>
442
+ </tr>
443
+ <tr>
444
+ <td>MNSLQANDTAIYYCAR</td>
445
+ <td>HC (82-97)</td>
446
+ <td>Man5</td>
447
+ <td>32.4%</td>
448
+ <td>31.5%</td>
449
+ </tr>
450
+ </table>
451
+ <hr>
452
+ </div>
453
+
454
+ <div class="table-container">
455
+ <h2>Table 10</h2>
456
+ <table border="1">
457
+ <tr>
458
+ <td>Sequence</td>
459
+ <td>Sequence location</td>
460
+ <td>Modification</td>
461
+ <td>Relative abundance</td>
462
+ <td>Relative abundance</td>
463
+ </tr>
464
+ <tr>
465
+ <td>Sequence</td>
466
+ <td>Sequence location</td>
467
+ <td>Modification</td>
468
+ <td>aFH.07_T0</td>
469
+ <td>aFH.07_T4W</td>
470
+ </tr>
471
+ <tr>
472
+ <td>EEQYNSTYR</td>
473
+ <td>HC (293-301)</td>
474
+ <td>Non glycosylated</td>
475
+ <td>n.d</td>
476
+ <td>n.d</td>
477
+ </tr>
478
+ <tr>
479
+ <td>EEQYNSTYR</td>
480
+ <td>HC (293-301)</td>
481
+ <td>Man5</td>
482
+ <td>20.9%</td>
483
+ <td>22.5%</td>
484
+ </tr>
485
+ <tr>
486
+ <td>EEQYNSTYR</td>
487
+ <td>HC (293-301)</td>
488
+ <td>G0</td>
489
+ <td>n.D</td>
490
+ <td>n.d</td>
491
+ </tr>
492
+ <tr>
493
+ <td>EEQYNSTYR</td>
494
+ <td>HC (293-301)</td>
495
+ <td>G0F</td>
496
+ <td>79.1%</td>
497
+ <td>77.5%</td>
498
+ </tr>
499
+ <tr>
500
+ <td>EEQYNSTYR</td>
501
+ <td>HC (293-301)</td>
502
+ <td>G1F</td>
503
+ <td>n.d</td>
504
+ <td>n.d</td>
505
+ </tr>
506
+ <tr>
507
+ <td>EEQYNSTYR</td>
508
+ <td>HC (293-301)</td>
509
+ <td>G2F</td>
510
+ <td>n.d</td>
511
+ <td>n.d</td>
512
+ </tr>
513
+ </table>
514
+ <hr>
515
+ </div>
516
+
517
+ <div class="table-container">
518
+ <h2>Table 11</h2>
519
+ <table border="1">
520
+ <tr>
521
+ <td>Sequence</td>
522
+ <td>Sequence location</td>
523
+ <td>Modification</td>
524
+ <td>Relative abundance*</td>
525
+ <td>Relative abundance*</td>
526
+ </tr>
527
+ <tr>
528
+ <td>Sequence</td>
529
+ <td>Sequence location</td>
530
+ <td>Modification</td>
531
+ <td>aFH.07_T0</td>
532
+ <td>aFH.07_T4W</td>
533
+ </tr>
534
+ <tr>
535
+ <td>STSGGTAALGCLVK</td>
536
+ <td>HC (134-147)</td>
537
+ <td></td>
538
+ <td>99.9%</td>
539
+ <td>98.8%</td>
540
+ </tr>
541
+ <tr>
542
+ <td>GTAALGCLVK</td>
543
+ <td>HC (134-147)</td>
544
+ <td>Clipping</td>
545
+ <td>0.1%</td>
546
+ <td>1.2%</td>
547
+ </tr>
548
+ </table>
549
+ <hr>
550
+ </div>
551
+
552
+ <div class="table-container">
553
+ <h2>Table 12</h2>
554
+ <table border="1">
555
+ <tr>
556
+ <td>Blue:</td>
557
+ <td>VH and VL</td>
558
+ </tr>
559
+ <tr>
560
+ <td>Blue:</td>
561
+ <td>CDR</td>
562
+ </tr>
563
+ <tr>
564
+ <td>Green:</td>
565
+ <td>N-glycosylation site</td>
566
+ </tr>
567
+ </table>
568
+ <hr>
569
+ </div>
570
+
571
+ <div class="table-container">
572
+ <h2>Table 13</h2>
573
+ <table border="1">
574
+ <tr>
575
+ <td>Sequence</td>
576
+ <td>Sequence location</td>
577
+ <td>Modification</td>
578
+ <td>Relative abundance</td>
579
+ <td>Relative abundance</td>
580
+ </tr>
581
+ <tr>
582
+ <td>Sequence</td>
583
+ <td>Sequence location</td>
584
+ <td>Modification</td>
585
+ <td>FHR-1.3B4_T0</td>
586
+ <td>FHR-1.3B4_T4W</td>
587
+ </tr>
588
+ <tr>
589
+ <td>QIVLSQSPTILSASPGEK</td>
590
+ <td>LC (1-18)</td>
591
+ <td>pyro Q</td>
592
+ <td>96.1%</td>
593
+ <td>100.0%</td>
594
+ </tr>
595
+ <tr>
596
+ <td>QIVLSQSPTILSASPGEK</td>
597
+ <td>LC (1-18)</td>
598
+ <td></td>
599
+ <td>3.9%</td>
600
+ <td>n.d</td>
601
+ </tr>
602
+ <tr>
603
+ <td>QVQLR</td>
604
+ <td>HC (1-5)</td>
605
+ <td>pyro Q</td>
606
+ <td>96.7%</td>
607
+ <td>100.0%</td>
608
+ </tr>
609
+ <tr>
610
+ <td>QVQLR</td>
611
+ <td>HC (1-5)</td>
612
+ <td></td>
613
+ <td>3.3%</td>
614
+ <td>n.d</td>
615
+ </tr>
616
+ </table>
617
+ <hr>
618
+ </div>
619
+
620
+ <div class="table-container">
621
+ <h2>Table 14</h2>
622
+ <table border="1">
623
+ <tr>
624
+ <td>Sequence</td>
625
+ <td>Sequence location</td>
626
+ <td>Modification</td>
627
+ <td>Relative abundance</td>
628
+ <td>Relative abundance</td>
629
+ </tr>
630
+ <tr>
631
+ <td>Sequence</td>
632
+ <td>Sequence location</td>
633
+ <td>Modification</td>
634
+ <td>FHR-1.3B4_T0</td>
635
+ <td>FHR-1.3B4_T4W</td>
636
+ </tr>
637
+ <tr>
638
+ <td>MNSLQADDTAIYYCAR</td>
639
+ <td>HC (82-97)</td>
640
+ <td></td>
641
+ <td>99.3%</td>
642
+ <td>99.0%</td>
643
+ </tr>
644
+ <tr>
645
+ <td>MNSLQADDTAIYYCAR</td>
646
+ <td>HC (82-97)</td>
647
+ <td>Ox [+ 16 Da]</td>
648
+ <td>0.7%</td>
649
+ <td>1.0%</td>
650
+ </tr>
651
+ </table>
652
+ <hr>
653
+ </div>
654
+
655
+ <div class="table-container">
656
+ <h2>Table 15</h2>
657
+ <table border="1">
658
+ <tr>
659
+ <td>Sequence</td>
660
+ <td>Sequence location</td>
661
+ <td>Modification</td>
662
+ <td>Relative abundance</td>
663
+ <td>Relative abundance</td>
664
+ </tr>
665
+ <tr>
666
+ <td>Sequence</td>
667
+ <td>Sequence location</td>
668
+ <td>Modification</td>
669
+ <td>FHR-1.3B4_T0</td>
670
+ <td>FHR-1.3B4_T4W</td>
671
+ </tr>
672
+ <tr>
673
+ <td>MNSLQADDTAIYYCAR</td>
674
+ <td>HC (82-97)</td>
675
+ <td></td>
676
+ <td>97.6%</td>
677
+ <td>79.7%</td>
678
+ </tr>
679
+ <tr>
680
+ <td>MNSLQADDTAIYYCAR</td>
681
+ <td>HC (82-97)</td>
682
+ <td>Deamidation</td>
683
+ <td>2.4%</td>
684
+ <td>20.3%</td>
685
+ </tr>
686
+ </table>
687
+ <hr>
688
+ </div>
689
+
690
+ <div class="table-container">
691
+ <h2>Table 16</h2>
692
+ <table border="1">
693
+ <tr>
694
+ <td>Sequence</td>
695
+ <td>Sequence location</td>
696
+ <td>Modification</td>
697
+ <td>Relative abundance*</td>
698
+ <td>Relative abundance*</td>
699
+ </tr>
700
+ <tr>
701
+ <td>Sequence</td>
702
+ <td>Sequence location</td>
703
+ <td>Modification</td>
704
+ <td>FHR-1.3B4_T0</td>
705
+ <td>FHR-1.3B4_T4W</td>
706
+ </tr>
707
+ <tr>
708
+ <td>STSGGTAALGCLVK</td>
709
+ <td>HC (134-147)</td>
710
+ <td></td>
711
+ <td>99.9%</td>
712
+ <td>98.7%</td>
713
+ </tr>
714
+ <tr>
715
+ <td>GTAALGCLVK</td>
716
+ <td>HC (134-147)</td>
717
+ <td>Clipping</td>
718
+ <td>0.1%</td>
719
+ <td>1.3%</td>
720
+ </tr>
721
+ <tr>
722
+ <td>SSSNPLTFGAGTK</td>
723
+ <td>LC (91-103)</td>
724
+ <td></td>
725
+ <td>99.5%</td>
726
+ <td>97.3%</td>
727
+ </tr>
728
+ <tr>
729
+ <td>PLTFGAGTK</td>
730
+ <td>LC (91-103)</td>
731
+ <td>Clipping</td>
732
+ <td>0.5%</td>
733
+ <td>2.7%</td>
734
+ </tr>
735
+ </table>
736
+ <hr>
737
+ </div>
738
+
739
+ <div class="table-container">
740
+ <h2>Table 17</h2>
741
+ <table border="1">
742
+ <tr>
743
+ <td>Blue:</td>
744
+ <td>VH and VL</td>
745
+ </tr>
746
+ <tr>
747
+ <td>Blue:</td>
748
+ <td>CDR</td>
749
+ </tr>
750
+ <tr>
751
+ <td>Green:</td>
752
+ <td>N-glycosylation site</td>
753
+ </tr>
754
+ </table>
755
+ <hr>
756
+ </div>
757
+
758
+ <div class="table-container">
759
+ <h2>Table 18</h2>
760
+ <table border="1">
761
+ <tr>
762
+ <td>Sequence</td>
763
+ <td>Sequence location</td>
764
+ <td>Modification</td>
765
+ <td>Relative abundance</td>
766
+ <td>Relative abundance</td>
767
+ </tr>
768
+ <tr>
769
+ <td>Sequence</td>
770
+ <td>Sequence location</td>
771
+ <td>Modification</td>
772
+ <td>L5-H12_T0</td>
773
+ <td>L5-H12_T4w</td>
774
+ </tr>
775
+ <tr>
776
+ <td>QVQLQESGPGLVKPSQTLSLTCTVSGFSLTNYGVYWIR</td>
777
+ <td>HC (001-038)</td>
778
+ <td>pyro Q</td>
779
+ <td>85.5%</td>
780
+ <td>99.3%</td>
781
+ </tr>
782
+ <tr>
783
+ <td>QVQLQESGPGLVKPSQTLSLTCTVSGFSLTNYGVYWIR</td>
784
+ <td>HC (001-038)</td>
785
+ <td></td>
786
+ <td>14.5%</td>
787
+ <td>0.7%</td>
788
+ </tr>
789
+ </table>
790
+ <hr>
791
+ </div>
792
+
793
+ <div class="table-container">
794
+ <h2>Table 19</h2>
795
+ <table border="1">
796
+ <tr>
797
+ <td>Sequence</td>
798
+ <td>Sequence location</td>
799
+ <td>Modification</td>
800
+ <td>Relative abundance*</td>
801
+ <td>Relative abundance*</td>
802
+ </tr>
803
+ <tr>
804
+ <td>Sequence</td>
805
+ <td>Sequence location</td>
806
+ <td>Modification</td>
807
+ <td>L5-H12_T0</td>
808
+ <td>L5-H12_T4w</td>
809
+ </tr>
810
+ <tr>
811
+ <td>STSGGTAALGCLVK</td>
812
+ <td>HC (134-147)</td>
813
+ <td></td>
814
+ <td>99.9%</td>
815
+ <td>98.7%</td>
816
+ </tr>
817
+ <tr>
818
+ <td>GTAALGCLVK</td>
819
+ <td>HC (134-147)</td>
820
+ <td>Clipping</td>
821
+ <td>0.1%</td>
822
+ <td>1.3%</td>
823
+ </tr>
824
+ <tr>
825
+ <td>SSSNPLTFGAGTK</td>
826
+ <td>LC (91-103)</td>
827
+ <td></td>
828
+ <td>99.8%</td>
829
+ <td>98.9%</td>
830
+ </tr>
831
+ <tr>
832
+ <td>PLTFGAGTK</td>
833
+ <td>LC (91-103)</td>
834
+ <td>Clipping</td>
835
+ <td>0.2%</td>
836
+ <td>1.1%</td>
837
+ </tr>
838
+ </table>
839
+ <hr>
840
+ </div>
841
+
842
+ <div class="table-container">
843
+ <h2>Table 20</h2>
844
+ <table border="1">
845
+ <tr>
846
+ <td>Blue:</td>
847
+ <td>VH and VL</td>
848
+ </tr>
849
+ <tr>
850
+ <td>Blue:</td>
851
+ <td>CDR</td>
852
+ </tr>
853
+ <tr>
854
+ <td>Green:</td>
855
+ <td>N-glycosylation site</td>
856
+ </tr>
857
+ </table>
858
+ <hr>
859
+ </div>
860
+
861
+ <div class="table-container">
862
+ <h2>Table 21</h2>
863
+ <table border="1">
864
+ <tr>
865
+ <td>Sequence</td>
866
+ <td>Sequence location</td>
867
+ <td>Modification</td>
868
+ <td>Relative abundance</td>
869
+ <td>Relative abundance</td>
870
+ </tr>
871
+ <tr>
872
+ <td>Sequence</td>
873
+ <td>Sequence location</td>
874
+ <td>Modification</td>
875
+ <td>L5-H31_T0</td>
876
+ <td>L5-H31_T4w</td>
877
+ </tr>
878
+ <tr>
879
+ <td>QVQLQESGPGLVKPSQTLSLTCTVSGFSLTNYGVYWIR</td>
880
+ <td>HC (001-038)</td>
881
+ <td>pyro Q</td>
882
+ <td>83.5%</td>
883
+ <td>99.5%</td>
884
+ </tr>
885
+ <tr>
886
+ <td>QVQLQESGPGLVKPSQTLSLTCTVSGFSLTNYGVYWIR</td>
887
+ <td>HC (001-038)</td>
888
+ <td></td>
889
+ <td>16.5%</td>
890
+ <td>0.5%</td>
891
+ </tr>
892
+ </table>
893
+ <hr>
894
+ </div>
895
+
896
+ <div class="table-container">
897
+ <h2>Table 22</h2>
898
+ <table border="1">
899
+ <tr>
900
+ <td>Sequence</td>
901
+ <td>Sequence location</td>
902
+ <td>Modification</td>
903
+ <td>Relative abundance</td>
904
+ <td>Relative abundance</td>
905
+ </tr>
906
+ <tr>
907
+ <td>Sequence</td>
908
+ <td>Sequence location</td>
909
+ <td>Modification</td>
910
+ <td>L5-H31_T0</td>
911
+ <td>L5-H31_T4w</td>
912
+ </tr>
913
+ <tr>
914
+ <td>NFGNYAMDFWGQGTSVTVSSASTK</td>
915
+ <td>HC(98-121)</td>
916
+ <td>Ox. [+ 16 Da]</td>
917
+ <td>4.9%</td>
918
+ <td>1.9%</td>
919
+ </tr>
920
+ <tr>
921
+ <td>NFGNYAMDFWGQGTSVTVSSASTK</td>
922
+ <td>HC(98-121)</td>
923
+ <td></td>
924
+ <td>95.1%</td>
925
+ <td>98.1%</td>
926
+ </tr>
927
+ </table>
928
+ <hr>
929
+ </div>
930
+
931
+ <div class="table-container">
932
+ <h2>Table 23</h2>
933
+ <table border="1">
934
+ <tr>
935
+ <td>Sequence</td>
936
+ <td>Sequence location</td>
937
+ <td>Modification</td>
938
+ <td>Relative abundance</td>
939
+ <td>Relative abundance</td>
940
+ </tr>
941
+ <tr>
942
+ <td>Sequence</td>
943
+ <td>Sequence location</td>
944
+ <td>Modification</td>
945
+ <td>L5-H31_T0</td>
946
+ <td>L5-H31_T4w</td>
947
+ </tr>
948
+ <tr>
949
+ <td>SSSNPLTFGAGTK</td>
950
+ <td>LC (91-103)</td>
951
+ <td></td>
952
+ <td>99.8%</td>
953
+ <td>99.5%</td>
954
+ </tr>
955
+ <tr>
956
+ <td>SSSNPLTFGAGTK</td>
957
+ <td>LC (91-103)</td>
958
+ <td>deamidation</td>
959
+ <td>0.2%</td>
960
+ <td>0.5%</td>
961
+ </tr>
962
+ </table>
963
+ <hr>
964
+ </div>
965
+
966
+ <div class="table-container">
967
+ <h2>Table 24</h2>
968
+ <table border="1">
969
+ <tr>
970
+ <td>Sequence</td>
971
+ <td>Sequence location</td>
972
+ <td>Modification</td>
973
+ <td>Relative abundance*</td>
974
+ <td>Relative abundance*</td>
975
+ </tr>
976
+ <tr>
977
+ <td>Sequence</td>
978
+ <td>Sequence location</td>
979
+ <td>Modification</td>
980
+ <td>L5-H31_T0</td>
981
+ <td>L5-H31_T4w</td>
982
+ </tr>
983
+ <tr>
984
+ <td>STSGGTAALGCLVK</td>
985
+ <td>HC (134-147)</td>
986
+ <td></td>
987
+ <td>99.9%</td>
988
+ <td>98.8%</td>
989
+ </tr>
990
+ <tr>
991
+ <td>GTAALGCLVK</td>
992
+ <td>HC (134-147)</td>
993
+ <td>Clipping</td>
994
+ <td>0.1%</td>
995
+ <td>1.2%</td>
996
+ </tr>
997
+ <tr>
998
+ <td>SSSNPLTFGAGTK</td>
999
+ <td>LC (91-103)</td>
1000
+ <td></td>
1001
+ <td>99.9%</td>
1002
+ <td>98.8%</td>
1003
+ </tr>
1004
+ <tr>
1005
+ <td>PLTFGAGTK</td>
1006
+ <td>LC (91-103)</td>
1007
+ <td>Clipping</td>
1008
+ <td>0.1%</td>
1009
+ <td>1.2%</td>
1010
+ </tr>
1011
+ </table>
1012
+ <hr>
1013
+ </div>
1014
+
1015
+ <div class="table-container">
1016
+ <h2>Table 25</h2>
1017
+ <table border="1">
1018
+ <tr>
1019
+ <td>Blue:</td>
1020
+ <td>VH and VL</td>
1021
+ </tr>
1022
+ <tr>
1023
+ <td>Blue:</td>
1024
+ <td>CDR</td>
1025
+ </tr>
1026
+ <tr>
1027
+ <td>Green:</td>
1028
+ <td>N-glycosylation site</td>
1029
+ </tr>
1030
+ </table>
1031
+ <hr>
1032
+ </div>
1033
+
1034
+ <div class="table-container">
1035
+ <h2>Table 26</h2>
1036
+ <table border="1">
1037
+ <tr>
1038
+ <td>Sequence</td>
1039
+ <td>Sequence location</td>
1040
+ <td>Modification</td>
1041
+ <td>Relative abundance</td>
1042
+ <td>Relative abundance</td>
1043
+ </tr>
1044
+ <tr>
1045
+ <td>Sequence</td>
1046
+ <td>Sequence location</td>
1047
+ <td>Modification</td>
1048
+ <td>L14-H12_T0</td>
1049
+ <td>L14-H12_T4w</td>
1050
+ </tr>
1051
+ <tr>
1052
+ <td>QVQLQESGPGLVKPSQTLSLTCTVSGFSLTNYGVYWIR</td>
1053
+ <td>HC(001-038)</td>
1054
+ <td>pyroQ</td>
1055
+ <td>85.9%</td>
1056
+ <td>99.3%</td>
1057
+ </tr>
1058
+ <tr>
1059
+ <td>QVQLQESGPGLVKPSQTLSLTCTVSGFSLTNYGVYWIR</td>
1060
+ <td>HC(001-038)</td>
1061
+ <td></td>
1062
+ <td>14.1%</td>
1063
+ <td>0.7%</td>
1064
+ </tr>
1065
+ </table>
1066
+ <hr>
1067
+ </div>
1068
+
1069
+ <div class="table-container">
1070
+ <h2>Table 27</h2>
1071
+ <table border="1">
1072
+ <tr>
1073
+ <td>Sequence</td>
1074
+ <td>Sequence location</td>
1075
+ <td>Modification</td>
1076
+ <td>Relative abundance</td>
1077
+ <td>Relative abundance</td>
1078
+ </tr>
1079
+ <tr>
1080
+ <td>Sequence</td>
1081
+ <td>Sequence location</td>
1082
+ <td>Modification</td>
1083
+ <td>L14-H12_T0</td>
1084
+ <td>L14-H12_T4w</td>
1085
+ </tr>
1086
+ <tr>
1087
+ <td>ASTSVTYMHWYQQKPGK</td>
1088
+ <td>LC(25-41)</td>
1089
+ <td>Ox. [+16 Da]</td>
1090
+ <td>0.3%</td>
1091
+ <td>0.3%</td>
1092
+ </tr>
1093
+ <tr>
1094
+ <td>ASTSVTYMHWYQQKPGK</td>
1095
+ <td>LC(25-41)</td>
1096
+ <td></td>
1097
+ <td>99.7%</td>
1098
+ <td>99.7%</td>
1099
+ </tr>
1100
+ </table>
1101
+ <hr>
1102
+ </div>
1103
+
1104
+ <div class="table-container">
1105
+ <h2>Table 28</h2>
1106
+ <table border="1">
1107
+ <tr>
1108
+ <td>Sequence</td>
1109
+ <td>Sequence location</td>
1110
+ <td>Modification</td>
1111
+ <td>Relative abundance</td>
1112
+ <td>Relative abundance</td>
1113
+ </tr>
1114
+ <tr>
1115
+ <td>Sequence</td>
1116
+ <td>Sequence location</td>
1117
+ <td>Modification</td>
1118
+ <td>L14-H12_T0</td>
1119
+ <td>L14-H12_T4w</td>
1120
+ </tr>
1121
+ <tr>
1122
+ <td>SSSNPLTFGAGTK</td>
1123
+ <td>LC (91-103)</td>
1124
+ <td></td>
1125
+ <td>99.9%</td>
1126
+ <td>99.4%</td>
1127
+ </tr>
1128
+ <tr>
1129
+ <td>SSSNPLTFGAGTK</td>
1130
+ <td>LC (91-103)</td>
1131
+ <td>deamidation</td>
1132
+ <td>0.1%</td>
1133
+ <td>0.6%</td>
1134
+ </tr>
1135
+ </table>
1136
+ <hr>
1137
+ </div>
1138
+
1139
+ <div class="table-container">
1140
+ <h2>Table 29</h2>
1141
+ <table border="1">
1142
+ <tr>
1143
+ <td>Sequence</td>
1144
+ <td>Sequence location</td>
1145
+ <td>Modification</td>
1146
+ <td>Relative abundance*</td>
1147
+ <td>Relative abundance*</td>
1148
+ </tr>
1149
+ <tr>
1150
+ <td>Sequence</td>
1151
+ <td>Sequence location</td>
1152
+ <td>Modification</td>
1153
+ <td>L14-H12_T0</td>
1154
+ <td>L14-H12_T4w</td>
1155
+ </tr>
1156
+ <tr>
1157
+ <td>STSGGTAALGCLVK</td>
1158
+ <td>HC (134-147)</td>
1159
+ <td></td>
1160
+ <td>99.9%</td>
1161
+ <td>98.9%</td>
1162
+ </tr>
1163
+ <tr>
1164
+ <td>GTAALGCLVK</td>
1165
+ <td>HC (134-147)</td>
1166
+ <td>Clipping</td>
1167
+ <td>0.1%</td>
1168
+ <td>1.1%</td>
1169
+ </tr>
1170
+ <tr>
1171
+ <td>SSSNPLTFGAGTK</td>
1172
+ <td>LC (91-103)</td>
1173
+ <td></td>
1174
+ <td>99.7%</td>
1175
+ <td>98.6%</td>
1176
+ </tr>
1177
+ <tr>
1178
+ <td>PLTFGAGTK</td>
1179
+ <td>LC (91-103)</td>
1180
+ <td>Clipping</td>
1181
+ <td>0.3%</td>
1182
+ <td>1.4%</td>
1183
+ </tr>
1184
+ </table>
1185
+ <hr>
1186
+ </div>
1187
+
1188
+ <div class="table-container">
1189
+ <h2>Table 30</h2>
1190
+ <table border="1">
1191
+ <tr>
1192
+ <td>Blue:</td>
1193
+ <td>VH and VL</td>
1194
+ </tr>
1195
+ <tr>
1196
+ <td>Blue:</td>
1197
+ <td>CDR</td>
1198
+ </tr>
1199
+ <tr>
1200
+ <td>Green:</td>
1201
+ <td>N-glycosylation site</td>
1202
+ </tr>
1203
+ </table>
1204
+ <hr>
1205
+ </div>
1206
+
1207
+ <div class="table-container">
1208
+ <h2>Table 31</h2>
1209
+ <table border="1">
1210
+ <tr>
1211
+ <td>Sequence</td>
1212
+ <td>Sequence location</td>
1213
+ <td>Modification</td>
1214
+ <td>Relative abundance</td>
1215
+ <td>Relative abundance</td>
1216
+ </tr>
1217
+ <tr>
1218
+ <td>Sequence</td>
1219
+ <td>Sequence location</td>
1220
+ <td>Modification</td>
1221
+ <td>L14-H31_T0</td>
1222
+ <td>L14-H31_T4w</td>
1223
+ </tr>
1224
+ <tr>
1225
+ <td>QVQLQESGPGLVKPSQTLSLTCTVSGFSLTNYGVYWIR</td>
1226
+ <td>HC(001-038)</td>
1227
+ <td>pyroQ</td>
1228
+ <td>82.6%</td>
1229
+ <td>100.0%</td>
1230
+ </tr>
1231
+ <tr>
1232
+ <td>QVQLQESGPGLVKPSQTLSLTCTVSGFSLTNYGVYWIR</td>
1233
+ <td>HC(001-038)</td>
1234
+ <td></td>
1235
+ <td>17.4%</td>
1236
+ <td>n.d</td>
1237
+ </tr>
1238
+ </table>
1239
+ <hr>
1240
+ </div>
1241
+
1242
+ <div class="table-container">
1243
+ <h2>Table 32</h2>
1244
+ <table border="1">
1245
+ <tr>
1246
+ <td>Sequence</td>
1247
+ <td>Sequence location</td>
1248
+ <td>Modification</td>
1249
+ <td>Relative abundance</td>
1250
+ <td>Relative abundance</td>
1251
+ </tr>
1252
+ <tr>
1253
+ <td>Sequence</td>
1254
+ <td>Sequence location</td>
1255
+ <td>Modification</td>
1256
+ <td>L14-H31_T0</td>
1257
+ <td>L14-H31_T4w</td>
1258
+ </tr>
1259
+ <tr>
1260
+ <td>ASTSVTYMHWYQQKPGK</td>
1261
+ <td>LC(25-41)</td>
1262
+ <td>Ox. [+16 Da]</td>
1263
+ <td>0.5%</td>
1264
+ <td>0.4%</td>
1265
+ </tr>
1266
+ <tr>
1267
+ <td>ASTSVTYMHWYQQKPGK</td>
1268
+ <td>LC(25-41)</td>
1269
+ <td></td>
1270
+ <td>99.5%</td>
1271
+ <td>99.6%</td>
1272
+ </tr>
1273
+ </table>
1274
+ <hr>
1275
+ </div>
1276
+
1277
+ <div class="table-container">
1278
+ <h2>Table 33</h2>
1279
+ <table border="1">
1280
+ <tr>
1281
+ <td>Sequence</td>
1282
+ <td>Sequence location</td>
1283
+ <td>Modification</td>
1284
+ <td>Relative abundance</td>
1285
+ <td>Relative abundance</td>
1286
+ </tr>
1287
+ <tr>
1288
+ <td>Sequence</td>
1289
+ <td>Sequence location</td>
1290
+ <td>Modification</td>
1291
+ <td>L14-H31_T0</td>
1292
+ <td>L14-H31_T4w</td>
1293
+ </tr>
1294
+ <tr>
1295
+ <td>SSSNPLTFGAGTK</td>
1296
+ <td>LC (91-103)</td>
1297
+ <td></td>
1298
+ <td>99.9%</td>
1299
+ <td>99.5%</td>
1300
+ </tr>
1301
+ <tr>
1302
+ <td>SSSNPLTFGAGTK</td>
1303
+ <td>LC (91-103)</td>
1304
+ <td>deamidation</td>
1305
+ <td>0.1%</td>
1306
+ <td>0.5%</td>
1307
+ </tr>
1308
+ </table>
1309
+ <hr>
1310
+ </div>
1311
+
1312
+ <div class="table-container">
1313
+ <h2>Table 34</h2>
1314
+ <table border="1">
1315
+ <tr>
1316
+ <td>Sequence</td>
1317
+ <td>Sequence location</td>
1318
+ <td>Modification</td>
1319
+ <td>Relative abundance*</td>
1320
+ <td>Relative abundance*</td>
1321
+ </tr>
1322
+ <tr>
1323
+ <td>Sequence</td>
1324
+ <td>Sequence location</td>
1325
+ <td>Modification</td>
1326
+ <td>L14-H31_T0</td>
1327
+ <td>L14-H31_T4w</td>
1328
+ </tr>
1329
+ <tr>
1330
+ <td>STSGGTAALGCLVK</td>
1331
+ <td>HC (134-147)</td>
1332
+ <td></td>
1333
+ <td>99.9%</td>
1334
+ <td>98.9%</td>
1335
+ </tr>
1336
+ <tr>
1337
+ <td>GTAALGCLVK</td>
1338
+ <td>HC (134-147)</td>
1339
+ <td>Clipping</td>
1340
+ <td>0.1%</td>
1341
+ <td>1.1%</td>
1342
+ </tr>
1343
+ <tr>
1344
+ <td>SSSNPLTFGAGTK</td>
1345
+ <td>LC (91-103)</td>
1346
+ <td></td>
1347
+ <td>99.7%</td>
1348
+ <td>98.4%</td>
1349
+ </tr>
1350
+ <tr>
1351
+ <td>PLTFGAGTK</td>
1352
+ <td>LC (91-103)</td>
1353
+ <td>Clipping</td>
1354
+ <td>0.3%</td>
1355
+ <td>1.6%</td>
1356
+ </tr>
1357
+ </table>
1358
+ <hr>
1359
+ </div>
1360
+
1361
+ <div class="table-container">
1362
+ <h2>Table 35</h2>
1363
+ <table border="1">
1364
+ <tr>
1365
+ <td>Blue:</td>
1366
+ <td>VH and VL</td>
1367
+ </tr>
1368
+ <tr>
1369
+ <td>Blue:</td>
1370
+ <td>CDR</td>
1371
+ </tr>
1372
+ <tr>
1373
+ <td>Green:</td>
1374
+ <td>N-glycosylation site</td>
1375
+ </tr>
1376
+ </table>
1377
+ <hr>
1378
+ </div>
1379
+
1380
+ <div class="table-container">
1381
+ <h2>Table 36</h2>
1382
+ <table border="1">
1383
+ <tr>
1384
+ <td>Nathan Cardon</td>
1385
+ <td>Date:</td>
1386
+ </tr>
1387
+ <tr>
1388
+ <td>Sr Research Associate</td>
1389
+ <td>Signature:</td>
1390
+ </tr>
1391
+ <tr>
1392
+ <td>Mabelle Meersseman</td>
1393
+ <td>Date:</td>
1394
+ </tr>
1395
+ <tr>
1396
+ <td>Group Leader</td>
1397
+ <td>Signature:</td>
1398
+ </tr>
1399
+ <tr>
1400
+ <td>Approver</td>
1401
+ <td></td>
1402
+ </tr>
1403
+ <tr>
1404
+ <td>Koen Sandra Ph.D.</td>
1405
+ <td>Date:</td>
1406
+ </tr>
1407
+ <tr>
1408
+ <td>CEO</td>
1409
+ <td>Signature:</td>
1410
+ </tr>
1411
+ </table>
1412
+ <hr>
1413
+ </div>
1414
+
1415
+ <div class="table-container">
1416
+ <h2>Table 37</h2>
1417
+ <table border="1">
1418
+ <tr>
1419
+ <td>Version</td>
1420
+ <td>Date of issue</td>
1421
+ <td>Reason for version update</td>
1422
+ </tr>
1423
+ <tr>
1424
+ <td>00</td>
1425
+ <td>25NOV24</td>
1426
+ <td>Draft</td>
1427
+ </tr>
1428
+ <tr>
1429
+ <td></td>
1430
+ <td></td>
1431
+ <td></td>
1432
+ </tr>
1433
+ <tr>
1434
+ <td></td>
1435
+ <td></td>
1436
+ <td></td>
1437
+ </tr>
1438
+ </table>
1439
+ <hr>
1440
+ </div>
1441
+ </body></html>
src/agents/__pycache__/field_mapper_agent.cpython-312.pyc CHANGED
Binary files a/src/agents/__pycache__/field_mapper_agent.cpython-312.pyc and b/src/agents/__pycache__/field_mapper_agent.cpython-312.pyc differ
 
src/app.py CHANGED
@@ -7,6 +7,7 @@ from dotenv import load_dotenv
7
  from orchestrator.planner import Planner
8
  from orchestrator.executor import Executor
9
  from config.settings import settings
 
10
  import fitz # PyMuPDF local import to avoid heavy load on startup
11
  import pandas as pd
12
  from datetime import datetime
@@ -35,6 +36,18 @@ class LogCaptureHandler(logging.StreamHandler):
35
  if 'execution_history' not in st.session_state:
36
  st.session_state.execution_history = []
37
 
 
 
 
 
 
 
 
 
 
 
 
 
38
  # Set up logging capture
39
  log_capture = LogCaptureHandler()
40
  log_capture.setFormatter(logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s'))
@@ -231,160 +244,242 @@ elif page == "Traces":
231
  else: # page == "Execution"
232
  st.title("Deep‑Research PDF Field Extractor (POC)")
233
 
234
- pdf_file = st.file_uploader("Upload PDF", type=["pdf"])
235
- fields_str = st.text_input("Fields (comma‑separated)", "Chain, Percentage, Seq Loc")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
236
 
237
- # Replace YAML text area with table format for field descriptions
238
- st.subheader("Field Descriptions")
239
- st.markdown("""
240
- Add field descriptions to help the system better understand what to extract.
241
- You can add multiple rows to describe different aspects of each field.
242
- """)
243
 
244
- # Initialize session state for field descriptions table
245
- if 'field_descriptions_table' not in st.session_state:
246
- # Prefill with the provided JSON data for regular fields
247
- st.session_state.field_descriptions_table = [
248
- {
249
- 'field_name': 'Chain',
250
- 'field_description': 'Refers to either the heavy chain (HC) or light chain (LC) of an antibody or protein construct, each analyzed separately for structural integrity and chemical modifications.',
251
- 'format': 'String',
252
- 'examples': 'Heavy',
253
- 'possible_values': 'Heavy, Light'
254
- },
255
- {
256
- 'field_name': 'Percentage',
257
- 'field_description': 'The relative abundance of a specific modification or peptide, typically quantified using extracted ion chromatograms (EICs) and expressed as a percentage of the total signal.',
258
- 'format': 'Float',
259
- 'examples': '90.0',
260
- 'possible_values': ''
261
- },
262
- {
263
- 'field_name': 'Seq Loc',
264
- 'field_description': 'The specific amino acid position(s) within the protein sequence where a peptide or modification is located, often denoted by residue numbers and chain type (e.g., HC(88–125)).',
265
- 'format': 'String',
266
- 'examples': 'HC(1-31)',
267
- 'possible_values': ''
268
- }
269
- ]
270
-
271
- # Create the table interface
272
- col1, col2, col3, col4, col5, col6 = st.columns([2, 3, 2, 2, 2, 1])
273
-
274
- with col1:
275
- st.markdown("**Field Name**")
276
- with col2:
277
- st.markdown("**Field Description**")
278
- with col3:
279
- st.markdown("**Format**")
280
- with col4:
281
- st.markdown("**Examples**")
282
- with col5:
283
- st.markdown("**Possible Values**")
284
- with col6:
285
- st.markdown("**Actions**")
286
-
287
- # Display existing rows
288
- for i, row in enumerate(st.session_state.field_descriptions_table):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
289
  col1, col2, col3, col4, col5, col6 = st.columns([2, 3, 2, 2, 2, 1])
290
 
291
  with col1:
292
- field_name = st.text_input("", value=row.get('field_name', ''), key=f"field_name_{i}")
293
  with col2:
294
- field_desc = st.text_input("", value=row.get('field_description', ''), key=f"field_desc_{i}")
295
  with col3:
296
- field_format = st.text_input("", value=row.get('format', ''), key=f"field_format_{i}")
297
  with col4:
298
- field_examples = st.text_input("", value=row.get('examples', ''), key=f"field_examples_{i}")
299
  with col5:
300
- field_possible_values = st.text_input("", value=row.get('possible_values', ''), key=f"field_possible_values_{i}")
301
  with col6:
302
- if st.button("Delete", key=f"delete_{i}"):
303
- st.session_state.field_descriptions_table.pop(i)
304
- st.rerun()
305
 
306
- # Update the row in session state
307
- st.session_state.field_descriptions_table[i] = {
308
- 'field_name': field_name,
309
- 'field_description': field_desc,
310
- 'format': field_format,
311
- 'examples': field_examples,
312
- 'possible_values': field_possible_values
313
- }
314
-
315
- # Add new row button
316
- if st.button("Add Field Description Row"):
317
- st.session_state.field_descriptions_table.append({
318
- 'field_name': '',
319
- 'field_description': '',
320
- 'format': '',
321
- 'examples': '',
322
- 'possible_values': ''
323
- })
324
- st.rerun()
325
-
326
- # Convert table to JSON for processing
327
- field_descs = {}
328
- if st.session_state.field_descriptions_table:
329
- for row in st.session_state.field_descriptions_table:
330
- if row['field_name']: # Only include rows with field names
331
- field_descs[row['field_name']] = {
332
- 'description': row['field_description'],
333
- 'format': row['format'],
334
- 'examples': row['examples'],
335
- 'possible_values': row['possible_values']
336
- }
337
-
338
- # Add strategy selector
339
- strategy = st.radio(
340
- "Select Extraction Strategy",
341
- ["Original Strategy", "Unique Indices Strategy"],
342
- help="Original Strategy: Process document page by page. Unique Indices Strategy: Process entire document at once using unique indices."
343
- )
344
-
345
- # Add unique indices input if Unique Indices Strategy is selected
346
- unique_indices = None
347
- unique_indices_descriptions = None
348
- if strategy == "Unique Indices Strategy":
349
- # Add descriptions for each unique index using the same table format
350
- st.subheader("Unique Fields Descriptions")
351
- st.markdown("""
352
- Please provide a description for each unique field. This helps the system better understand what to look for.
353
- """)
354
 
355
- # Initialize session state for unique indices descriptions table
356
- if 'unique_indices_descriptions_table' not in st.session_state:
357
- # Prefill with the provided JSON data for unique indices fields
358
- st.session_state.unique_indices_descriptions_table = [
359
- {
360
- 'field_name': 'Protein Lot',
361
- 'field_description': 'Protein lots are batches of protein constructs analyzed to detect potential liabilities affecting stability, efficacy, and safety. Key liabilities include clipping events, deamidation, cyclization, oxidation, thioether bond formation, and glycation. Analytical methods such as reduced protein analysis by RPLC-UV-MS and peptide map analysis in reducing conditions are used to identify and quantify these modifications.',
362
- 'format': 'String',
363
- 'examples': 'P066_FH0.7-0-hulgG-LALAPG-FJB',
364
- 'possible_values': ''
365
- },
366
- {
367
- 'field_name': 'Peptide',
368
- 'field_description': 'A fragment of the protein sequence, typically derived from enzymatic digestion, used to detect and localize specific modifications or features.',
369
- 'format': 'String',
370
- 'examples': 'QVQLQQSGPGLVQPSQSLSITCTVSDFSLAR',
371
- 'possible_values': ''
372
- },
373
- {
374
- 'field_name': 'Timepoint',
375
- 'field_description': 'A designated sampling moment in a stability or stress study, used to track changes in the protein over time under specific conditions.',
376
- 'format': 'String',
377
- 'examples': '0w',
378
- 'possible_values': '0w, 2w, 4w, 6w'
379
- },
380
- {
381
- 'field_name': 'Modification',
382
- 'field_description': 'Any chemical or structural alteration to the protein or peptide, such as deamidation, oxidation, clipping, or glycation, which may affect function or stability.',
383
- 'format': 'String',
384
- 'examples': 'deamidation',
385
- 'possible_values': 'Deamidation, Oxidation, Truncation, pyroE, Isomerization, N-glycosylation, NonConforming, pyroQ, Thioether, Clipping, O-glycosylation, Double deamidation'
386
- }
387
- ]
388
 
389
  # Create the table interface for unique indices
390
  col1, col2, col3, col4, col5, col6 = st.columns([2, 3, 2, 2, 2, 1])
@@ -417,7 +512,7 @@ else: # page == "Execution"
417
  with col5:
418
  idx_field_possible_values = st.text_input("", value=row.get('possible_values', ''), key=f"unique_field_possible_values_{i}")
419
  with col6:
420
- if st.button("Delete", key=f"unique_delete_{i}"):
421
  st.session_state.unique_indices_descriptions_table.pop(i)
422
  st.rerun()
423
 
@@ -431,7 +526,7 @@ else: # page == "Execution"
431
  }
432
 
433
  # Add new row button for unique indices
434
- if st.button("Add Unique Field Description Row"):
435
  st.session_state.unique_indices_descriptions_table.append({
436
  'field_name': '',
437
  'field_description': '',
@@ -441,6 +536,104 @@ else: # page == "Execution"
441
  })
442
  st.rerun()
443
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
444
  # Convert unique indices table to JSON for processing and extract field names
445
  unique_indices_descriptions = {}
446
  unique_indices = []
@@ -454,210 +647,162 @@ else: # page == "Execution"
454
  'examples': row['examples'],
455
  'possible_values': row['possible_values']
456
  }
457
-
458
- def flatten_json_response(json_data, fields):
459
- """Flatten the nested JSON response into a tabular structure with dynamic columns."""
460
- logger = logging.getLogger(__name__)
461
- logger.info("Starting flatten_json_response")
462
- logger.info(f"Input fields: {fields}")
463
-
464
- # Handle the case where the response is a string
465
- if isinstance(json_data, str):
466
- logger.info("Input is a string, attempting to parse as JSON")
467
- try:
468
- json_data = json.loads(json_data)
469
- logger.info("Successfully parsed JSON string")
470
- except json.JSONDecodeError as e:
471
- logger.error(f"Failed to parse JSON string: {e}")
472
- return pd.DataFrame(columns=fields)
473
-
474
- # If the data is wrapped in an array, get the first item
475
- if isinstance(json_data, list) and len(json_data) > 0:
476
- logger.info("Data is wrapped in an array, extracting first item")
477
- json_data = json_data[0]
478
-
479
- # If the data is a dictionary with numeric keys, get the first value
480
- if isinstance(json_data, dict):
481
- keys = list(json_data.keys())
482
- logger.info(f"Checking dictionary keys: {keys}")
483
- # Check if all keys are integers or string representations of integers
484
- if all(isinstance(k, int) or (isinstance(k, str) and k.isdigit()) for k in keys):
485
- logger.info("Data has numeric keys, extracting first value")
486
- first_key = sorted(keys, key=lambda x: int(x) if isinstance(x, str) else x)[0]
487
- json_data = json_data[first_key]
488
- logger.info(f"Extracted data from key '{first_key}'")
489
-
490
- logger.info(f"JSON data keys: {list(json_data.keys()) if isinstance(json_data, dict) else 'Not a dict'}")
491
-
492
- # Create a list to store rows
493
- rows = []
494
-
495
- # Get the length of the first array to determine number of rows
496
- if isinstance(json_data, dict) and len(json_data) > 0:
497
- first_field = list(json_data.keys())[0]
498
- num_rows = len(json_data[first_field]) if isinstance(json_data[first_field], list) else 1
499
- logger.info(f"Number of rows to process: {num_rows}")
500
-
501
- # Create a row for each index
502
- for i in range(num_rows):
503
- logger.debug(f"Processing row {i}")
504
- row = {}
505
- for field in fields:
506
- if field in json_data and isinstance(json_data[field], list) and i < len(json_data[field]):
507
- row[field] = json_data[field][i]
508
- logger.debug(f"Field '{field}' value at index {i}: {json_data[field][i]}")
509
- else:
510
- row[field] = None
511
- logger.debug(f"Field '{field}' not found or index {i} out of bounds")
512
- rows.append(row)
513
  else:
514
- logger.error(f"Unexpected data structure: {type(json_data)}")
515
- return pd.DataFrame(columns=fields)
516
-
517
- # Create DataFrame with all requested fields as columns
518
- df = pd.DataFrame(rows)
519
- logger.info(f"Created DataFrame with shape: {df.shape}")
520
- logger.info(f"DataFrame columns: {df.columns.tolist()}")
521
-
522
- # Ensure columns are in the same order as the fields list
523
- df = df[fields]
524
- logger.info(f"Final DataFrame columns after reordering: {df.columns.tolist()}")
525
-
526
- return df
527
-
528
- if st.button("Run extraction") and pdf_file:
529
- field_list = [f.strip() for f in fields_str.split(",") if f.strip()]
530
- field_descs = field_descs
531
-
532
- try:
533
- with st.spinner("Planning …"):
534
- # quick first-page text preview to give LLM document context
535
- doc = fitz.open(stream=pdf_file.getvalue(), filetype="pdf") # type: ignore[arg-type]
536
- preview = "\n".join(page.get_text() for page in doc[:10])[:20000] # first 2 pages, 2k chars
537
-
538
- # Create a cost tracker for this run
539
- cost_tracker = CostTracker()
540
 
541
- planner = Planner(cost_tracker=cost_tracker)
542
- plan = planner.build_plan(
543
- pdf_meta={"filename": pdf_file.name},
544
- doc_preview=preview,
545
- fields=field_list,
546
- field_descs=field_descs,
547
- strategy=strategy,
548
- unique_indices=unique_indices,
549
- unique_indices_descriptions=unique_indices_descriptions
550
- )
551
-
552
- # Add a visual separator
553
- st.markdown("---")
554
 
555
- with st.spinner("Executing …"):
556
- executor = Executor(settings=settings, cost_tracker=cost_tracker)
557
- results, logs = executor.run(plan, pdf_file)
558
 
559
- # Get detailed costs
560
- costs = executor.cost_tracker.calculate_current_file_costs()
561
- model_cost = costs["openai"]["total_cost"]
562
- di_cost = costs["document_intelligence"]["total_cost"]
 
 
 
 
 
 
 
 
 
563
 
564
- # Add debug logging for cost tracking
565
- logger.info(f"Cost tracker debug info:")
566
- logger.info(f" LLM input tokens: {executor.cost_tracker.llm_input_tokens}")
567
- logger.info(f" LLM output tokens: {executor.cost_tracker.llm_output_tokens}")
568
- logger.info(f" DI pages: {executor.cost_tracker.di_pages}")
569
- logger.info(f" LLM calls count: {len(executor.cost_tracker.llm_calls)}")
570
- logger.info(f" Current file costs: {executor.cost_tracker.current_file_costs}")
571
- logger.info(f" Calculated costs: {costs}")
572
 
573
- # Display detailed costs table
574
- st.subheader("Detailed Costs")
575
- costs_df = executor.cost_tracker.get_detailed_costs_table()
576
- st.dataframe(costs_df, use_container_width=True)
577
 
578
- st.info(
579
- f"LLM input tokens: {executor.cost_tracker.llm_input_tokens}, "
580
- f"LLM output tokens: {executor.cost_tracker.llm_output_tokens}, "
581
- f"DI pages: {executor.cost_tracker.di_pages}, "
582
- f"Model cost: ${model_cost:.4f}, "
583
- f"DI cost: ${di_cost:.4f}, "
584
- f"Total cost: ${model_cost + di_cost:.4f}"
585
- )
586
 
587
- # Add detailed logging about what executor returned
588
- logger.info(f"Executor returned results of type: {type(results)}")
589
- logger.info(f"Results content: {results}")
590
-
591
- # Check if results is already a DataFrame
592
- if isinstance(results, pd.DataFrame):
593
- logger.info(f"Results is already a DataFrame with shape: {results.shape}")
594
- logger.info(f"DataFrame columns: {results.columns.tolist()}")
595
- logger.info(f"DataFrame head: {results.head()}")
596
- df = results
597
- else:
598
- logger.info("Results is not a DataFrame, calling flatten_json_response")
599
- # Process results using flatten_json_response
600
- df = flatten_json_response(results, field_list)
601
-
602
- # Log final DataFrame info
603
- logger.info(f"Final DataFrame shape: {df.shape}")
604
- logger.info(f"Final DataFrame columns: {df.columns.tolist()}")
605
- if not df.empty:
606
- logger.info(f"Final DataFrame sample: {df.head()}")
607
 
608
- # Store execution in history
609
- execution_record = {
610
- "filename": pdf_file.name,
611
- "datetime": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
612
- "fields": field_list,
613
- "logs": log_capture.get_logs(), # Store the actual logs
614
- "results": df.to_dict() if not df.empty else None
615
- }
616
- st.session_state.execution_history.append(execution_record)
617
- log_capture.clear() # Clear logs after storing them
618
 
619
- # ----------------- UI: show execution tree -----------------
620
- st.subheader("Execution trace")
621
- for log in logs:
622
- indent = "&nbsp;" * 4 * log["depth"]
623
- # Add error indicator if there was an error
624
- error_indicator = "❌ " if log.get("error") else "✓ "
625
- # Use a fixed preview text instead of the result
626
- with st.expander(f"{indent}{error_indicator}{log['tool']} – Click to view result"):
627
- st.markdown(f"**Args**: `{log['args']}`", unsafe_allow_html=True)
628
- if log.get("error"):
629
- st.error(f"Error: {log['error']}")
630
 
631
- # Special handling for IndexAgent output
632
- if log['tool'] == "IndexAgent" and isinstance(log["result"], dict):
633
- # Display chunk statistics if available
634
- if "chunk_stats" in log["result"]:
635
- st.markdown("### Chunk Statistics")
636
- # Create a DataFrame for better visualization
637
- stats_df = pd.DataFrame(log["result"]["chunk_stats"])
638
- st.dataframe(stats_df)
639
-
640
- # Add summary statistics
641
- st.markdown("### Summary")
642
- st.markdown(f"""
643
- - Total chunks: {len(stats_df)}
644
- - Average chunk length: {stats_df['length'].mean():.0f} characters
645
- - Shortest chunk: {stats_df['length'].min()} characters
646
- - Longest chunk: {stats_df['length'].max()} characters
647
- """)
648
-
649
- # Add a bar chart of chunk lengths
650
- st.markdown("### Chunk Length Distribution")
651
- st.bar_chart(stats_df.set_index('chunk_number')['length'])
652
  else:
653
- st.code(log["result"])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
654
 
655
- if not df.empty:
656
- st.success("Done ✓")
657
- st.dataframe(df)
658
- st.download_button("Download CSV", df.to_csv(index=False), "results.csv")
659
- else:
660
- st.warning("No results were extracted. Check the execution trace for errors.")
661
- except Exception as e:
662
- logging.exception("App error:")
663
- st.error(f"An error occurred: {e}")
 
7
  from orchestrator.planner import Planner
8
  from orchestrator.executor import Executor
9
  from config.settings import settings
10
+ from config.config_manager import config_manager
11
  import fitz # PyMuPDF local import to avoid heavy load on startup
12
  import pandas as pd
13
  from datetime import datetime
 
36
  if 'execution_history' not in st.session_state:
37
  st.session_state.execution_history = []
38
 
39
+ # Initialize session state for field descriptions tables
40
+ if 'field_descriptions_table' not in st.session_state:
41
+ st.session_state.field_descriptions_table = []
42
+
43
+ # Initialize session state for unique indices descriptions table
44
+ if 'unique_indices_descriptions_table' not in st.session_state:
45
+ st.session_state.unique_indices_descriptions_table = []
46
+
47
+ # Initialize session state for fields string
48
+ if 'fields_str' not in st.session_state:
49
+ st.session_state.fields_str = "Chain, Percentage, Seq Loc"
50
+
51
  # Set up logging capture
52
  log_capture = LogCaptureHandler()
53
  log_capture.setFormatter(logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s'))
 
244
  else: # page == "Execution"
245
  st.title("Deep‑Research PDF Field Extractor (POC)")
246
 
247
+ def flatten_json_response(json_data, fields):
248
+ """Flatten the nested JSON response into a tabular structure with dynamic columns."""
249
+ logger = logging.getLogger(__name__)
250
+ logger.info("Starting flatten_json_response")
251
+ logger.info(f"Input fields: {fields}")
252
+
253
+ # Handle the case where the response is a string
254
+ if isinstance(json_data, str):
255
+ logger.info("Input is a string, attempting to parse as JSON")
256
+ try:
257
+ json_data = json.loads(json_data)
258
+ logger.info("Successfully parsed JSON string")
259
+ except json.JSONDecodeError as e:
260
+ logger.error(f"Failed to parse JSON string: {e}")
261
+ return pd.DataFrame(columns=fields)
262
+
263
+ # If the data is wrapped in an array, get the first item
264
+ if isinstance(json_data, list) and len(json_data) > 0:
265
+ logger.info("Data is wrapped in an array, extracting first item")
266
+ json_data = json_data[0]
267
+
268
+ # If the data is a dictionary with numeric keys, get the first value
269
+ if isinstance(json_data, dict):
270
+ keys = list(json_data.keys())
271
+ logger.info(f"Checking dictionary keys: {keys}")
272
+ # Check if all keys are integers or string representations of integers
273
+ if all(isinstance(k, int) or (isinstance(k, str) and k.isdigit()) for k in keys):
274
+ logger.info("Data has numeric keys, extracting first value")
275
+ first_key = sorted(keys, key=lambda x: int(x) if isinstance(x, str) else x)[0]
276
+ json_data = json_data[first_key]
277
+ logger.info(f"Extracted data from key '{first_key}'")
278
+
279
+ logger.info(f"JSON data keys: {list(json_data.keys()) if isinstance(json_data, dict) else 'Not a dict'}")
280
+
281
+ # Create a list to store rows
282
+ rows = []
283
+
284
+ # Get the length of the first array to determine number of rows
285
+ if isinstance(json_data, dict) and len(json_data) > 0:
286
+ first_field = list(json_data.keys())[0]
287
+ num_rows = len(json_data[first_field]) if isinstance(json_data[first_field], list) else 1
288
+ logger.info(f"Number of rows to process: {num_rows}")
289
+
290
+ # Create a row for each index
291
+ for i in range(num_rows):
292
+ logger.debug(f"Processing row {i}")
293
+ row = {}
294
+ for field in fields:
295
+ if field in json_data and isinstance(json_data[field], list) and i < len(json_data[field]):
296
+ row[field] = json_data[field][i]
297
+ logger.debug(f"Field '{field}' value at index {i}: {json_data[field][i]}")
298
+ else:
299
+ row[field] = None
300
+ logger.debug(f"Field '{field}' not found or index {i} out of bounds")
301
+ rows.append(row)
302
+ else:
303
+ logger.error(f"Unexpected data structure: {type(json_data)}")
304
+ return pd.DataFrame(columns=fields)
305
+
306
+ # Create DataFrame with all requested fields as columns
307
+ df = pd.DataFrame(rows)
308
+ logger.info(f"Created DataFrame with shape: {df.shape}")
309
+ logger.info(f"DataFrame columns: {df.columns.tolist()}")
310
+
311
+ # Ensure columns are in the same order as the fields list
312
+ df = df[fields]
313
+ logger.info(f"Final DataFrame columns after reordering: {df.columns.tolist()}")
314
+
315
+ return df
316
+
317
+ # ============================================================================
318
+ # SECTION 1: FILE UPLOAD
319
+ # ============================================================================
320
+ st.header("📄 Step 1: Upload Document")
321
+ pdf_file = st.file_uploader("Upload PDF", type=["pdf"], help="Select a PDF file to process")
322
 
323
+ if pdf_file:
324
+ st.success(f" File uploaded: {pdf_file.name}")
 
 
 
 
325
 
326
+ # ============================================================================
327
+ # SECTION 2: STRATEGY SELECTION
328
+ # ============================================================================
329
+ st.header("🎯 Step 2: Select Extraction Strategy")
330
+
331
+ strategy = st.radio(
332
+ "Choose your extraction approach:",
333
+ ["Original Strategy", "Unique Indices Strategy"],
334
+ help="**Original Strategy**: Process document page by page, extracting each field individually. **Unique Indices Strategy**: Process entire document at once using unique combinations of indices.",
335
+ horizontal=True
336
+ )
337
+
338
+ if strategy == "Original Strategy":
339
+ st.info("📋 **Original Strategy**: Will extract fields one by one from the document pages.")
340
+ else:
341
+ st.info("🔍 **Unique Indices Strategy**: Will find unique combinations and extract additional fields for each.")
342
+
343
+ # ============================================================================
344
+ # SECTION 3: CONFIGURATION (Only for Unique Indices Strategy)
345
+ # ============================================================================
346
+ if strategy == "Unique Indices Strategy":
347
+ st.header("⚙️ Step 3: Configuration")
348
+
349
+ # File Type Selection
350
+ col1, col2 = st.columns([3, 1])
351
+ with col1:
352
+ # Get available configurations
353
+ config_names = config_manager.get_config_names()
354
+
355
+ selected_config_name = st.selectbox(
356
+ "Select File Type Configuration:",
357
+ config_names,
358
+ format_func=lambda x: config_manager.get_config(x)['name'] if config_manager.get_config(x) else x,
359
+ help="Choose a predefined configuration or create a new one"
360
+ )
361
+ with col2:
362
+ if st.button("🔄 Load Config", help="Load the selected configuration"):
363
+ config = config_manager.get_config(selected_config_name)
364
+ if config:
365
+ # Update fields
366
+ st.session_state.fields_str = config.get('fields', '')
367
+
368
+ # Update field descriptions table
369
+ field_descs = config.get('field_descriptions', {})
370
+ st.session_state.field_descriptions_table = []
371
+ for field_name, field_info in field_descs.items():
372
+ st.session_state.field_descriptions_table.append({
373
+ 'field_name': field_name,
374
+ 'field_description': field_info.get('description', ''),
375
+ 'format': field_info.get('format', ''),
376
+ 'examples': field_info.get('examples', ''),
377
+ 'possible_values': field_info.get('possible_values', '')
378
+ })
379
+
380
+ # Update unique indices descriptions table
381
+ unique_descs = config.get('unique_indices_descriptions', {})
382
+ st.session_state.unique_indices_descriptions_table = []
383
+ for field_name, field_info in unique_descs.items():
384
+ st.session_state.unique_indices_descriptions_table.append({
385
+ 'field_name': field_name,
386
+ 'field_description': field_info.get('description', ''),
387
+ 'format': field_info.get('format', ''),
388
+ 'examples': field_info.get('examples', ''),
389
+ 'possible_values': field_info.get('possible_values', '')
390
+ })
391
+
392
+ st.session_state.last_selected_config = selected_config_name
393
+ st.success(f"✅ Configuration '{config['name']}' loaded successfully!")
394
+ st.rerun()
395
+ else:
396
+ st.error("❌ Failed to load configuration")
397
+
398
+ # Clear Configuration Button
399
+ if st.button("🗑️ Clear All Configuration", help="Clear all configuration and start fresh"):
400
+ st.session_state.field_descriptions_table = []
401
+ st.session_state.unique_indices_descriptions_table = []
402
+ st.session_state.fields_str = ""
403
+ st.session_state.last_selected_config = ""
404
+ st.success("✅ Configuration cleared!")
405
+ st.rerun()
406
+
407
+ # ============================================================================
408
+ # SECTION 4: FIELD DESCRIPTIONS
409
+ # ============================================================================
410
+ st.subheader("📝 Field Descriptions")
411
+ st.markdown("""
412
+ <div style="background-color: #e8f4fd; padding: 1rem; border-radius: 0.5rem; border-left: 4px solid #1f77b4; color: #333;">
413
+ <strong>Field Descriptions</strong><br>
414
+ Add descriptions for the fields you want to extract. These help the system understand what to look for.
415
+ </div>
416
+ """, unsafe_allow_html=True)
417
+
418
+ # Create the table interface
419
  col1, col2, col3, col4, col5, col6 = st.columns([2, 3, 2, 2, 2, 1])
420
 
421
  with col1:
422
+ st.markdown("**Field Name**")
423
  with col2:
424
+ st.markdown("**Field Description**")
425
  with col3:
426
+ st.markdown("**Format**")
427
  with col4:
428
+ st.markdown("**Examples**")
429
  with col5:
430
+ st.markdown("**Possible Values**")
431
  with col6:
432
+ st.markdown("**Actions**")
 
 
433
 
434
+ # Display existing rows
435
+ for i, row in enumerate(st.session_state.field_descriptions_table):
436
+ col1, col2, col3, col4, col5, col6 = st.columns([2, 3, 2, 2, 2, 1])
437
+
438
+ with col1:
439
+ field_name = st.text_input("", value=row.get('field_name', ''), key=f"field_name_{i}")
440
+ with col2:
441
+ field_desc = st.text_input("", value=row.get('field_description', ''), key=f"field_desc_{i}")
442
+ with col3:
443
+ field_format = st.text_input("", value=row.get('format', ''), key=f"field_format_{i}")
444
+ with col4:
445
+ field_examples = st.text_input("", value=row.get('examples', ''), key=f"field_examples_{i}")
446
+ with col5:
447
+ field_possible_values = st.text_input("", value=row.get('possible_values', ''), key=f"field_possible_values_{i}")
448
+ with col6:
449
+ if st.button("🗑️", key=f"delete_{i}", help="Delete this row"):
450
+ st.session_state.field_descriptions_table.pop(i)
451
+ st.rerun()
452
+
453
+ # Update the row in session state
454
+ st.session_state.field_descriptions_table[i] = {
455
+ 'field_name': field_name,
456
+ 'field_description': field_desc,
457
+ 'format': field_format,
458
+ 'examples': field_examples,
459
+ 'possible_values': field_possible_values
460
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
461
 
462
+ # Add new row button
463
+ if st.button("➕ Add Field Description Row"):
464
+ st.session_state.field_descriptions_table.append({
465
+ 'field_name': '',
466
+ 'field_description': '',
467
+ 'format': '',
468
+ 'examples': '',
469
+ 'possible_values': ''
470
+ })
471
+ st.rerun()
472
+
473
+ # ============================================================================
474
+ # SECTION 5: UNIQUE FIELD DESCRIPTIONS
475
+ # ============================================================================
476
+ st.subheader("🔑 Unique Field Descriptions")
477
+ st.markdown("""
478
+ <div style="background-color: #fff8e1; padding: 1rem; border-radius: 0.5rem; border-left: 4px solid #ffc107; color: #333;">
479
+ <strong>Unique Field Descriptions</strong><br>
480
+ Add descriptions for the unique fields that will be used to identify different combinations in the document.
481
+ </div>
482
+ """, unsafe_allow_html=True)
 
 
 
 
 
 
 
 
 
 
 
 
483
 
484
  # Create the table interface for unique indices
485
  col1, col2, col3, col4, col5, col6 = st.columns([2, 3, 2, 2, 2, 1])
 
512
  with col5:
513
  idx_field_possible_values = st.text_input("", value=row.get('possible_values', ''), key=f"unique_field_possible_values_{i}")
514
  with col6:
515
+ if st.button("🗑️", key=f"unique_delete_{i}", help="Delete this row"):
516
  st.session_state.unique_indices_descriptions_table.pop(i)
517
  st.rerun()
518
 
 
526
  }
527
 
528
  # Add new row button for unique indices
529
+ if st.button("Add Unique Field Description Row"):
530
  st.session_state.unique_indices_descriptions_table.append({
531
  'field_name': '',
532
  'field_description': '',
 
536
  })
537
  st.rerun()
538
 
539
+ # ============================================================================
540
+ # SECTION 6: SAVE CONFIGURATION
541
+ # ============================================================================
542
+ st.subheader("💾 Save Configuration")
543
+ st.markdown("""
544
+ <div style="background-color: #e1f5fe; padding: 1rem; border-radius: 0.5rem; border-left: 4px solid #17a2b8; color: #333;">
545
+ <strong>Save Current Configuration</strong><br>
546
+ Save your current configuration as a new file type for future use.
547
+ </div>
548
+ """, unsafe_allow_html=True)
549
+
550
+ col1, col2 = st.columns([3, 1])
551
+ with col1:
552
+ save_config_name = st.text_input(
553
+ "Configuration Name:",
554
+ placeholder="Enter a name for this configuration (e.g., 'Biotech Report', 'Clinical Data')",
555
+ help="Choose a descriptive name that will appear in the dropdown"
556
+ )
557
+ with col2:
558
+ if st.button("💾 Save Config", help="Save the current configuration"):
559
+ if save_config_name:
560
+ # Prepare configuration data
561
+ field_descs = {}
562
+ for row in st.session_state.field_descriptions_table:
563
+ if row['field_name']: # Only include rows with field names
564
+ field_descs[row['field_name']] = {
565
+ 'description': row['field_description'],
566
+ 'format': row['format'],
567
+ 'examples': row['examples'],
568
+ 'possible_values': row['possible_values']
569
+ }
570
+
571
+ # Get unique indices descriptions
572
+ unique_indices_descs = {}
573
+ for row in st.session_state.unique_indices_descriptions_table:
574
+ if row['field_name']: # Only include rows with field names
575
+ unique_indices_descs[row['field_name']] = {
576
+ 'description': row['field_description'],
577
+ 'format': row['format'],
578
+ 'examples': row['examples'],
579
+ 'possible_values': row['possible_values']
580
+ }
581
+
582
+ # Get fields from unique indices
583
+ fields_str = ", ".join([row['field_name'] for row in st.session_state.unique_indices_descriptions_table if row['field_name']])
584
+
585
+ config_data = {
586
+ 'name': save_config_name,
587
+ 'description': f"Configuration for {save_config_name}",
588
+ 'fields': fields_str,
589
+ 'field_descriptions': field_descs,
590
+ 'unique_indices_descriptions': unique_indices_descs
591
+ }
592
+
593
+ if config_manager.save_config(save_config_name, config_data):
594
+ st.success(f"✅ Configuration '{save_config_name}' saved successfully!")
595
+ config_manager.reload_configs()
596
+ st.rerun()
597
+ else:
598
+ st.error("❌ Failed to save configuration")
599
+ else:
600
+ st.error("❌ Please enter a configuration name")
601
+
602
+ # ============================================================================
603
+ # SECTION 7: ORIGINAL STRATEGY CONFIGURATION
604
+ # ============================================================================
605
+ else: # Original Strategy
606
+ st.header("⚙️ Step 3: Field Configuration")
607
+
608
+ fields_str = st.text_input(
609
+ "Fields to Extract (comma-separated):",
610
+ value=st.session_state.fields_str,
611
+ key="fields_input",
612
+ help="Enter the field names you want to extract, separated by commas"
613
+ )
614
+ st.session_state.fields_str = fields_str
615
+
616
+ # ============================================================================
617
+ # SECTION 8: EXECUTION
618
+ # ============================================================================
619
+ st.header("🚀 Step 4: Run Extraction")
620
+
621
+ # Convert table to JSON for processing
622
+ field_descs = {}
623
+ if st.session_state.field_descriptions_table:
624
+ for row in st.session_state.field_descriptions_table:
625
+ if row['field_name']: # Only include rows with field names
626
+ field_descs[row['field_name']] = {
627
+ 'description': row['field_description'],
628
+ 'format': row['format'],
629
+ 'examples': row['examples'],
630
+ 'possible_values': row['possible_values']
631
+ }
632
+
633
+ # Prepare unique indices for Unique Indices Strategy
634
+ unique_indices = None
635
+ unique_indices_descriptions = None
636
+ if strategy == "Unique Indices Strategy":
637
  # Convert unique indices table to JSON for processing and extract field names
638
  unique_indices_descriptions = {}
639
  unique_indices = []
 
647
  'examples': row['examples'],
648
  'possible_values': row['possible_values']
649
  }
650
+
651
+ # Status indicator
652
+ if pdf_file:
653
+ if strategy == "Original Strategy":
654
+ field_count = len([f.strip() for f in st.session_state.fields_str.split(",") if f.strip()])
655
+ st.info(f"📊 Ready to extract {field_count} fields using Original Strategy")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
656
  else:
657
+ unique_count = len(unique_indices) if unique_indices else 0
658
+ field_count = len(field_descs)
659
+ st.info(f"📊 Ready to extract {field_count} additional fields for {unique_count} unique combinations using Unique Indices Strategy")
660
+
661
+ # Run button
662
+ if st.button("🚀 Run Extraction", type="primary", disabled=not pdf_file):
663
+ if not pdf_file:
664
+ st.error("❌ Please upload a PDF file first")
665
+ else:
666
+ # Prepare field list based on strategy
667
+ if strategy == "Original Strategy":
668
+ field_list = [f.strip() for f in st.session_state.fields_str.split(",") if f.strip()]
669
+ else: # Unique Indices Strategy
670
+ # For Unique Indices Strategy, get fields from the unique indices descriptions table
671
+ field_list = []
672
+ if st.session_state.unique_indices_descriptions_table:
673
+ for row in st.session_state.unique_indices_descriptions_table:
674
+ if row['field_name']: # Only include rows with field names
675
+ field_list.append(row['field_name'])
 
 
 
 
 
 
 
676
 
677
+ try:
678
+ with st.spinner("Planning …"):
679
+ # quick first-page text preview to give LLM document context
680
+ doc = fitz.open(stream=pdf_file.getvalue(), filetype="pdf") # type: ignore[arg-type]
681
+ preview = "\n".join(page.get_text() for page in doc[:10])[:20000] # first 2 pages, 2k chars
 
 
 
 
 
 
 
 
682
 
683
+ # Create a cost tracker for this run
684
+ cost_tracker = CostTracker()
 
685
 
686
+ planner = Planner(cost_tracker=cost_tracker)
687
+ plan = planner.build_plan(
688
+ pdf_meta={"filename": pdf_file.name},
689
+ doc_preview=preview,
690
+ fields=field_list,
691
+ field_descs=field_descs,
692
+ strategy=strategy,
693
+ unique_indices=unique_indices,
694
+ unique_indices_descriptions=unique_indices_descriptions
695
+ )
696
+
697
+ # Add a visual separator
698
+ st.markdown("---")
699
 
700
+ with st.spinner("Executing …"):
701
+ executor = Executor(settings=settings, cost_tracker=cost_tracker)
702
+ results, logs = executor.run(plan, pdf_file)
 
 
 
 
 
703
 
704
+ # Get detailed costs
705
+ costs = executor.cost_tracker.calculate_current_file_costs()
706
+ model_cost = costs["openai"]["total_cost"]
707
+ di_cost = costs["document_intelligence"]["total_cost"]
708
 
709
+ # Add debug logging for cost tracking
710
+ logger.info(f"Cost tracker debug info:")
711
+ logger.info(f" LLM input tokens: {executor.cost_tracker.llm_input_tokens}")
712
+ logger.info(f" LLM output tokens: {executor.cost_tracker.llm_output_tokens}")
713
+ logger.info(f" DI pages: {executor.cost_tracker.di_pages}")
714
+ logger.info(f" LLM calls count: {len(executor.cost_tracker.llm_calls)}")
715
+ logger.info(f" Current file costs: {executor.cost_tracker.current_file_costs}")
716
+ logger.info(f" Calculated costs: {costs}")
717
 
718
+ # Display detailed costs table
719
+ st.subheader("Detailed Costs")
720
+ costs_df = executor.cost_tracker.get_detailed_costs_table()
721
+ st.dataframe(costs_df, use_container_width=True)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
722
 
723
+ st.info(
724
+ f"LLM input tokens: {executor.cost_tracker.llm_input_tokens}, "
725
+ f"LLM output tokens: {executor.cost_tracker.llm_output_tokens}, "
726
+ f"DI pages: {executor.cost_tracker.di_pages}, "
727
+ f"Model cost: ${model_cost:.4f}, "
728
+ f"DI cost: ${di_cost:.4f}, "
729
+ f"Total cost: ${model_cost + di_cost:.4f}"
730
+ )
 
 
731
 
732
+ # Add detailed logging about what executor returned
733
+ logger.info(f"Executor returned results of type: {type(results)}")
734
+ logger.info(f"Results content: {results}")
 
 
 
 
 
 
 
 
735
 
736
+ # Check if results is already a DataFrame
737
+ if isinstance(results, pd.DataFrame):
738
+ logger.info(f"Results is already a DataFrame with shape: {results.shape}")
739
+ logger.info(f"DataFrame columns: {results.columns.tolist()}")
740
+ logger.info(f"DataFrame head: {results.head()}")
741
+ df = results
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
742
  else:
743
+ logger.info("Results is not a DataFrame, calling flatten_json_response")
744
+ # Process results using flatten_json_response
745
+ df = flatten_json_response(results, field_list)
746
+
747
+ # Log final DataFrame info
748
+ logger.info(f"Final DataFrame shape: {df.shape}")
749
+ logger.info(f"Final DataFrame columns: {df.columns.tolist()}")
750
+ if not df.empty:
751
+ logger.info(f"Final DataFrame sample: {df.head()}")
752
+
753
+ # Store execution in history
754
+ execution_record = {
755
+ "filename": pdf_file.name,
756
+ "datetime": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
757
+ "fields": field_list,
758
+ "logs": log_capture.get_logs(), # Store the actual logs
759
+ "results": df.to_dict() if not df.empty else None
760
+ }
761
+ st.session_state.execution_history.append(execution_record)
762
+ log_capture.clear() # Clear logs after storing them
763
+
764
+ # ----------------- UI: show execution tree -----------------
765
+ st.subheader("Execution trace")
766
+ for log in logs:
767
+ indent = "&nbsp;" * 4 * log["depth"]
768
+ # Add error indicator if there was an error
769
+ error_indicator = "❌ " if log.get("error") else "✓ "
770
+ # Use a fixed preview text instead of the result
771
+ with st.expander(f"{indent}{error_indicator}{log['tool']} – Click to view result"):
772
+ st.markdown(f"**Args**: `{log['args']}`", unsafe_allow_html=True)
773
+ if log.get("error"):
774
+ st.error(f"Error: {log['error']}")
775
+
776
+ # Special handling for IndexAgent output
777
+ if log['tool'] == "IndexAgent" and isinstance(log["result"], dict):
778
+ # Display chunk statistics if available
779
+ if "chunk_stats" in log["result"]:
780
+ st.markdown("### Chunk Statistics")
781
+ # Create a DataFrame for better visualization
782
+ stats_df = pd.DataFrame(log["result"]["chunk_stats"])
783
+ st.dataframe(stats_df)
784
+
785
+ # Add summary statistics
786
+ st.markdown("### Summary")
787
+ st.markdown(f"""
788
+ - Total chunks: {len(stats_df)}
789
+ - Average chunk length: {stats_df['length'].mean():.0f} characters
790
+ - Shortest chunk: {stats_df['length'].min()} characters
791
+ - Longest chunk: {stats_df['length'].max()} characters
792
+ """)
793
+
794
+ # Add a bar chart of chunk lengths
795
+ st.markdown("### Chunk Length Distribution")
796
+ st.bar_chart(stats_df.set_index('chunk_number')['length'])
797
+ else:
798
+ st.code(log["result"])
799
 
800
+ if not df.empty:
801
+ st.success("Done ✓")
802
+ st.dataframe(df)
803
+ st.download_button("Download CSV", df.to_csv(index=False), "results.csv")
804
+ else:
805
+ st.warning("No results were extracted. Check the execution trace for errors.")
806
+ except Exception as e:
807
+ logging.exception("App error:")
808
+ st.error(f"An error occurred: {e}")
src/config/config_manager.py ADDED
@@ -0,0 +1,148 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Configuration manager for file type configurations."""
2
+ import yaml
3
+ import os
4
+ from pathlib import Path
5
+ from typing import Dict, Any, List, Optional
6
+ import logging
7
+
8
+ logger = logging.getLogger(__name__)
9
+
10
+ class ConfigManager:
11
+ """Manages file type configurations."""
12
+
13
+ def __init__(self, config_file: str = "file_types.yaml"):
14
+ self.config_file = Path(__file__).parent / config_file
15
+ self.configs = self._load_configs()
16
+
17
+ def _load_configs(self) -> Dict[str, Any]:
18
+ """Load configurations from YAML file."""
19
+ try:
20
+ if self.config_file.exists():
21
+ with open(self.config_file, 'r', encoding='utf-8') as f:
22
+ configs = yaml.safe_load(f) or {}
23
+ logger.info(f"Loaded {len(configs)} configurations from {self.config_file}")
24
+ return configs
25
+ else:
26
+ logger.warning(f"Configuration file {self.config_file} not found, creating default")
27
+ return self._create_default_config()
28
+ except Exception as e:
29
+ logger.error(f"Error loading configurations: {e}")
30
+ return self._create_default_config()
31
+
32
+ def _create_default_config(self) -> Dict[str, Any]:
33
+ """Create default configuration if file doesn't exist."""
34
+ default_config = {
35
+ "default_type": {
36
+ "name": "Default Type",
37
+ "description": "Default configuration for biotech documents",
38
+ "fields": "Chain, Percentage, Seq Loc",
39
+ "field_descriptions": {
40
+ "Chain": {
41
+ "description": "Refers to either the heavy chain (HC) or light chain (LC) of an antibody or protein construct, each analyzed separately for structural integrity and chemical modifications.",
42
+ "format": "String",
43
+ "examples": "Heavy",
44
+ "possible_values": "Heavy, Light"
45
+ },
46
+ "Percentage": {
47
+ "description": "The relative abundance of a specific modification or peptide, typically quantified using extracted ion chromatograms (EICs) and expressed as a percentage of the total signal.",
48
+ "format": "Float",
49
+ "examples": "90.0",
50
+ "possible_values": ""
51
+ },
52
+ "Seq Loc": {
53
+ "description": "The specific amino acid position(s) within the protein sequence where a peptide or modification is located, often denoted by residue numbers and chain type (e.g., HC(88–125)).",
54
+ "format": "String",
55
+ "examples": "HC(1-31)",
56
+ "possible_values": ""
57
+ }
58
+ },
59
+ "unique_indices_descriptions": {
60
+ "Protein Lot": {
61
+ "description": "Protein lots are batches of protein constructs analyzed to detect potential liabilities affecting stability, efficacy, and safety. Key liabilities include clipping events, deamidation, cyclization, oxidation, thioether bond formation, and glycation. Analytical methods such as reduced protein analysis by RPLC-UV-MS and peptide map analysis in reducing conditions are used to identify and quantify these modifications.",
62
+ "format": "String",
63
+ "examples": "P066_FH0.7-0-hulgG-LALAPG-FJB",
64
+ "possible_values": ""
65
+ },
66
+ "Peptide": {
67
+ "description": "A fragment of the protein sequence, typically derived from enzymatic digestion, used to detect and localize specific modifications or features.",
68
+ "format": "String",
69
+ "examples": "QVQLQQSGPGLVQPSQSLSITCTVSDFSLAR",
70
+ "possible_values": ""
71
+ },
72
+ "Timepoint": {
73
+ "description": "A designated sampling moment in a stability or stress study, used to track changes in the protein over time under specific conditions.",
74
+ "format": "String",
75
+ "examples": "0w",
76
+ "possible_values": "0w, 2w, 4w, 6w"
77
+ },
78
+ "Modification": {
79
+ "description": "Any chemical or structural alteration to the protein or peptide, such as deamidation, oxidation, clipping, or glycation, which may affect function or stability.",
80
+ "format": "String",
81
+ "examples": "deamidation",
82
+ "possible_values": "Deamidation, Oxidation, Truncation, pyroE, Isomerization, N-glycosylation, NonConforming, pyroQ, Thioether, Clipping, O-glycosylation, Double deamidation"
83
+ }
84
+ }
85
+ }
86
+ }
87
+
88
+ # Save the default configuration
89
+ self._save_configs(default_config)
90
+ return default_config
91
+
92
+ def _save_configs(self, configs: Dict[str, Any]) -> None:
93
+ """Save configurations to YAML file."""
94
+ try:
95
+ with open(self.config_file, 'w', encoding='utf-8') as f:
96
+ yaml.dump(configs, f, default_flow_style=False, allow_unicode=True, sort_keys=False)
97
+ logger.info(f"Saved {len(configs)} configurations to {self.config_file}")
98
+ except Exception as e:
99
+ logger.error(f"Error saving configurations: {e}")
100
+
101
+ def get_config_names(self) -> List[str]:
102
+ """Get list of available configuration names."""
103
+ return list(self.configs.keys())
104
+
105
+ def get_config(self, config_name: str) -> Optional[Dict[str, Any]]:
106
+ """Get a specific configuration by name."""
107
+ return self.configs.get(config_name)
108
+
109
+ def save_config(self, config_name: str, config_data: Dict[str, Any]) -> bool:
110
+ """Save a new configuration."""
111
+ try:
112
+ # Validate required fields
113
+ required_fields = ['name', 'fields', 'field_descriptions', 'unique_indices_descriptions']
114
+ for field in required_fields:
115
+ if field not in config_data:
116
+ logger.error(f"Missing required field: {field}")
117
+ return False
118
+
119
+ # Save the configuration
120
+ self.configs[config_name] = config_data
121
+ self._save_configs(self.configs)
122
+ logger.info(f"Saved configuration: {config_name}")
123
+ return True
124
+ except Exception as e:
125
+ logger.error(f"Error saving configuration {config_name}: {e}")
126
+ return False
127
+
128
+ def delete_config(self, config_name: str) -> bool:
129
+ """Delete a configuration."""
130
+ try:
131
+ if config_name in self.configs:
132
+ del self.configs[config_name]
133
+ self._save_configs(self.configs)
134
+ logger.info(f"Deleted configuration: {config_name}")
135
+ return True
136
+ else:
137
+ logger.warning(f"Configuration {config_name} not found")
138
+ return False
139
+ except Exception as e:
140
+ logger.error(f"Error deleting configuration {config_name}: {e}")
141
+ return False
142
+
143
+ def reload_configs(self) -> None:
144
+ """Reload configurations from file."""
145
+ self.configs = self._load_configs()
146
+
147
+ # Global instance
148
+ config_manager = ConfigManager()
src/config/file_types.yaml ADDED
@@ -0,0 +1,170 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ default_type:
2
+ name: Default Type
3
+ description: Default configuration for biotech documents
4
+ fields: Chain, Percentage, Seq Loc
5
+ field_descriptions:
6
+ Chain:
7
+ description: Refers to either the heavy chain (HC) or light chain (LC) of an
8
+ antibody or protein construct, each analyzed separately for structural integrity
9
+ and chemical modifications.
10
+ format: String
11
+ examples: Heavy
12
+ possible_values: Heavy, Light
13
+ Percentage:
14
+ description: The relative abundance of a specific modification or peptide, typically
15
+ quantified using extracted ion chromatograms (EICs) and expressed as a percentage
16
+ of the total signal.
17
+ format: Float
18
+ examples: '90.0'
19
+ possible_values: ''
20
+ Seq Loc:
21
+ description: The specific amino acid position(s) within the protein sequence
22
+ where a peptide or modification is located, often denoted by residue numbers
23
+ and chain type (e.g., HC(88–125)).
24
+ format: String
25
+ examples: HC(1-31)
26
+ possible_values: ''
27
+ unique_indices_descriptions:
28
+ Protein Lot:
29
+ description: Protein lots are batches of protein constructs analyzed to detect
30
+ potential liabilities affecting stability, efficacy, and safety. Key liabilities
31
+ include clipping events, deamidation, cyclization, oxidation, thioether bond
32
+ formation, and glycation. Analytical methods such as reduced protein analysis
33
+ by RPLC-UV-MS and peptide map analysis in reducing conditions are used to
34
+ identify and quantify these modifications.
35
+ format: String
36
+ examples: P066_FH0.7-0-hulgG-LALAPG-FJB
37
+ possible_values: ''
38
+ Peptide:
39
+ description: A fragment of the protein sequence, typically derived from enzymatic
40
+ digestion, used to detect and localize specific modifications or features.
41
+ format: String
42
+ examples: QVQLQQSGPGLVQPSQSLSITCTVSDFSLAR
43
+ possible_values: ''
44
+ Timepoint:
45
+ description: A designated sampling moment in a stability or stress study, used
46
+ to track changes in the protein over time under specific conditions.
47
+ format: String
48
+ examples: 0w
49
+ possible_values: 0w, 2w, 4w, 6w
50
+ Modification:
51
+ description: Any chemical or structural alteration to the protein or peptide,
52
+ such as deamidation, oxidation, clipping, or glycation, which may affect function
53
+ or stability.
54
+ format: String
55
+ examples: deamidation
56
+ possible_values: Deamidation, Oxidation, Truncation, pyroE, Isomerization, N-glycosylation,
57
+ NonConforming, pyroQ, Thioether, Clipping, O-glycosylation, Double deamidation
58
+ default 2:
59
+ name: default 2
60
+ description: Configuration for default 2
61
+ fields: Protein Lot, Peptide, Timepoint, Modification
62
+ field_descriptions:
63
+ Chain:
64
+ description: Refers to either the heavy chain (HC) or light chain (LC) of an
65
+ antibody or protein construct, each analyzed separately for structural integrity
66
+ and chemical modifications.
67
+ format: String
68
+ examples: Heavy
69
+ possible_values: Heavy, Light
70
+ Percentage:
71
+ description: The relative abundance of a specific modification or peptide, typically
72
+ quantified using extracted ion chromatograms (EICs) and expressed as a percentage
73
+ of the total signal.
74
+ format: Float
75
+ examples: '90.0'
76
+ possible_values: ''
77
+ Seq Loc:
78
+ description: The specific amino acid position(s) within the protein sequence
79
+ where a peptide or modification is located, often denoted by residue numbers
80
+ and chain type (e.g., HC(88–125)).
81
+ format: String
82
+ examples: HC(1-31)
83
+ possible_values: ''
84
+ unique_indices_descriptions:
85
+ Protein Lot:
86
+ description: Protein lots are batches of protein constructs analyzed to detect
87
+ potential liabilities affecting stability, efficacy, and safety. Key liabilities
88
+ include clipping events, deamidation, cyclization, oxidation, thioether bond
89
+ formation, and glycation. Analytical methods such as reduced protein analysis
90
+ by RPLC-UV-MS and peptide map analysis in reducing conditions are used to
91
+ identify and quantify these modifications.
92
+ format: String
93
+ examples: P066_FH0.7-0-hulgG-LALAPG-FJB
94
+ possible_values: ''
95
+ Peptide:
96
+ description: A fragment of the protein sequence, typically derived from enzymatic
97
+ digestion, used to detect and localize specific modifications or features.
98
+ format: String
99
+ examples: QVQLQQSGPGLVQPSQSLSITCTVSDFSLAR
100
+ possible_values: ''
101
+ Timepoint:
102
+ description: A designated sampling moment in a stability or stress study, used
103
+ to track changes in the protein over time under specific conditions.
104
+ format: String
105
+ examples: 0w
106
+ possible_values: 0w, 2w, 4w, 6w
107
+ Modification:
108
+ description: Any chemical or structural alteration to the protein or peptide,
109
+ such as deamidation, oxidation, clipping, or glycation, which may affect function
110
+ or stability.
111
+ format: String
112
+ examples: deamidation
113
+ possible_values: Deamidation, Oxidation, Truncation, pyroE, Isomerization, N-glycosylation,
114
+ NonConforming, pyroQ, Thioether, Clipping, O-glycosylation, Double deamidation
115
+ Shipping DOcument:
116
+ name: Shipping DOcument
117
+ description: Configuration for Shipping DOcument
118
+ fields: 'Storage Condition, Aliquot Volume, lot #'
119
+ field_descriptions:
120
+ Customer Code:
121
+ description: ''
122
+ format: Integer
123
+ examples: '3060'
124
+ possible_values: ''
125
+ Stability Protocol:
126
+ description: ''
127
+ format: String
128
+ examples: SGTS-38321
129
+ possible_values: ''
130
+ Timepoint:
131
+ description: ''
132
+ format: String
133
+ examples: T=12M
134
+ possible_values: ''
135
+ Test:
136
+ description: ''
137
+ format: String
138
+ examples: ''
139
+ possible_values: ''
140
+ Aliquot Container:
141
+ description: ''
142
+ format: String
143
+ examples: PP Tube
144
+ possible_values: ''
145
+ Shipping Temperature:
146
+ description: ''
147
+ format: String
148
+ examples: <=65
149
+ possible_values: ''
150
+ LIMS ID:
151
+ description: ''
152
+ format: String
153
+ examples: '2244197'
154
+ possible_values: ''
155
+ unique_indices_descriptions:
156
+ Storage Condition:
157
+ description: The degrees on which the product is stored
158
+ format: String
159
+ examples: -70 deg C, +5 degC
160
+ possible_values: ''
161
+ Aliquot Volume:
162
+ description: ''
163
+ format: String
164
+ examples: 1 x 2mL
165
+ possible_values: ''
166
+ 'lot #':
167
+ description: ''
168
+ format: Integer
169
+ examples: '2244197'
170
+ possible_values: ''
src/config/settings.py CHANGED
@@ -17,7 +17,7 @@ class Settings(BaseSettings):
17
  AZURE_OPENAI_EMBEDDING_MODEL: str = Field("text-embedding-3-small", env="AZURE_OPENAI_EMBEDDING_MODEL")
18
 
19
  # Retry configuration
20
- LLM_MAX_RETRIES: int = Field(5, env="LLM_MAX_RETRIES")
21
  LLM_BASE_DELAY: float = Field(1.0, env="LLM_BASE_DELAY")
22
  LLM_MAX_DELAY: float = Field(60.0, env="LLM_MAX_DELAY")
23
 
 
17
  AZURE_OPENAI_EMBEDDING_MODEL: str = Field("text-embedding-3-small", env="AZURE_OPENAI_EMBEDDING_MODEL")
18
 
19
  # Retry configuration
20
+ LLM_MAX_RETRIES: int = Field(=, env="LLM_MAX_RETRIES")
21
  LLM_BASE_DELAY: float = Field(1.0, env="LLM_BASE_DELAY")
22
  LLM_MAX_DELAY: float = Field(60.0, env="LLM_MAX_DELAY")
23
 
src/orchestrator/__pycache__/planner.cpython-312.pyc CHANGED
Binary files a/src/orchestrator/__pycache__/planner.cpython-312.pyc and b/src/orchestrator/__pycache__/planner.cpython-312.pyc differ
 
src/services/__pycache__/llm_client.cpython-312.pyc CHANGED
Binary files a/src/services/__pycache__/llm_client.cpython-312.pyc and b/src/services/__pycache__/llm_client.cpython-312.pyc differ