vectorvein 0.1.80__py3-none-any.whl → 0.1.82__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,668 @@
1
+ from typing import Optional
2
+
3
+ from ..graph.node import Node
4
+ from ..graph.port import PortType, InputPort, OutputPort
5
+
6
+
7
+ class AudioEditing(Node):
8
+ def __init__(self, id: Optional[str] = None):
9
+ super().__init__(
10
+ node_type="AudioEditing",
11
+ category="media_editing",
12
+ task_name="media_editing.audio_editing",
13
+ node_id=id,
14
+ ports={
15
+ "input_audio": InputPort(
16
+ name="input_audio",
17
+ port_type=PortType.FILE,
18
+ value=list(),
19
+ support_file_types=[".mp3", ".wav", ".ogg", ".m4a"],
20
+ ),
21
+ "audio_processing_logic": InputPort(
22
+ name="audio_processing_logic",
23
+ port_type=PortType.SELECT,
24
+ value="process_each",
25
+ options=[
26
+ {"value": "process_each", "label": "process_each"},
27
+ {"value": "mix", "label": "mix"},
28
+ {"value": "concat", "label": "concat"},
29
+ ],
30
+ ),
31
+ "trim": InputPort(
32
+ name="trim",
33
+ port_type=PortType.CHECKBOX,
34
+ value=False,
35
+ ),
36
+ "trim_method": InputPort(
37
+ name="trim_method",
38
+ port_type=PortType.SELECT,
39
+ value="start_duration",
40
+ options=[
41
+ {"value": "start_duration", "label": "start_duration"},
42
+ {"value": "end_duration", "label": "end_duration"},
43
+ {"value": "start_end_time", "label": "start_end_time"},
44
+ ],
45
+ condition="return fieldsData.trim.value",
46
+ ),
47
+ "trim_length": InputPort(
48
+ name="trim_length",
49
+ port_type=PortType.NUMBER,
50
+ value=0,
51
+ condition="return fieldsData.trim.value && (fieldsData.trim_method.value === 'start_duration' || fieldsData.trim_method.value === 'end_duration')",
52
+ ),
53
+ "trim_start_time": InputPort(
54
+ name="trim_start_time",
55
+ port_type=PortType.INPUT,
56
+ value="00:00:00",
57
+ condition="return fieldsData.trim.value && fieldsData.trim_method.value === 'start_end_time'",
58
+ ),
59
+ "trim_end_time": InputPort(
60
+ name="trim_end_time",
61
+ port_type=PortType.INPUT,
62
+ value="00:01:00",
63
+ condition="return fieldsData.trim.value && fieldsData.trim_method.value === 'start_end_time'",
64
+ ),
65
+ "adjust_volume": InputPort(
66
+ name="adjust_volume",
67
+ port_type=PortType.CHECKBOX,
68
+ value=False,
69
+ ),
70
+ "volume_adjustment_ratio": InputPort(
71
+ name="volume_adjustment_ratio",
72
+ port_type=PortType.NUMBER,
73
+ value=1.0,
74
+ condition="return fieldsData.adjust_volume.value",
75
+ ),
76
+ "fade_in_out": InputPort(
77
+ name="fade_in_out",
78
+ port_type=PortType.CHECKBOX,
79
+ value=False,
80
+ ),
81
+ "fade_in_out_duration": InputPort(
82
+ name="fade_in_out_duration",
83
+ port_type=PortType.NUMBER,
84
+ value=1,
85
+ condition="return fieldsData.fade_in_out.value",
86
+ ),
87
+ "adjust_speed": InputPort(
88
+ name="adjust_speed",
89
+ port_type=PortType.CHECKBOX,
90
+ value=False,
91
+ ),
92
+ "speed_adjustment_method": InputPort(
93
+ name="speed_adjustment_method",
94
+ port_type=PortType.SELECT,
95
+ value="specified_speed",
96
+ options=[
97
+ {"value": "specified_speed", "label": "specified_speed"},
98
+ {"value": "specified_final_length", "label": "specified_final_length"},
99
+ ],
100
+ condition="return fieldsData.adjust_speed.value",
101
+ ),
102
+ "specified_speed": InputPort(
103
+ name="specified_speed",
104
+ port_type=PortType.NUMBER,
105
+ value=1.0,
106
+ condition="return fieldsData.adjust_speed.value && fieldsData.speed_adjustment_method.value === 'specified_speed'",
107
+ ),
108
+ "specified_final_length": InputPort(
109
+ name="specified_final_length",
110
+ port_type=PortType.NUMBER,
111
+ value=10,
112
+ condition="return fieldsData.adjust_speed.value && fieldsData.speed_adjustment_method.value === 'specified_final_length'",
113
+ ),
114
+ "adjust_channels": InputPort(
115
+ name="adjust_channels",
116
+ port_type=PortType.CHECKBOX,
117
+ value=False,
118
+ ),
119
+ "channel_adjustment_method": InputPort(
120
+ name="channel_adjustment_method",
121
+ port_type=PortType.SELECT,
122
+ value="stereo_to_mono",
123
+ options=[
124
+ {"value": "stereo_to_mono", "label": "stereo_to_mono"},
125
+ {"value": "mono_to_stereo", "label": "mono_to_stereo"},
126
+ ],
127
+ condition="return fieldsData.adjust_channels.value",
128
+ ),
129
+ "output_audio_format": InputPort(
130
+ name="output_audio_format",
131
+ port_type=PortType.SELECT,
132
+ value="mp3",
133
+ options=[
134
+ {"value": "mp3", "label": "mp3"},
135
+ {"value": "wav", "label": "wav"},
136
+ {"value": "m4a", "label": "m4a"},
137
+ ],
138
+ ),
139
+ "output_type": InputPort(
140
+ name="output_type",
141
+ port_type=PortType.SELECT,
142
+ value="only_link",
143
+ options=[
144
+ {"value": "only_link", "label": "only_link"},
145
+ {"value": "markdown", "label": "markdown"},
146
+ {"value": "html", "label": "html"},
147
+ ],
148
+ ),
149
+ "output": OutputPort(),
150
+ },
151
+ )
152
+
153
+
154
+ class ImageBackgroundRemoval(Node):
155
+ def __init__(self, id: Optional[str] = None):
156
+ super().__init__(
157
+ node_type="ImageBackgroundRemoval",
158
+ category="media_editing",
159
+ task_name="media_editing.image_background_removal",
160
+ node_id=id,
161
+ ports={
162
+ "input_image": InputPort(
163
+ name="input_image",
164
+ port_type=PortType.FILE,
165
+ value=list(),
166
+ support_file_types=[".jpg", ".jpeg", ".png", ".webp"],
167
+ multiple=True,
168
+ ),
169
+ "remove_background_method": InputPort(
170
+ name="remove_background_method",
171
+ port_type=PortType.SELECT,
172
+ value="accurate",
173
+ options=[
174
+ {"value": "fast", "label": "fast"},
175
+ {"value": "accurate", "label": "accurate"},
176
+ {"value": "portrait", "label": "portrait"},
177
+ {"value": "birefnet", "label": "birefnet"},
178
+ ],
179
+ ),
180
+ "transparent_background": InputPort(
181
+ name="transparent_background",
182
+ port_type=PortType.CHECKBOX,
183
+ value=True,
184
+ ),
185
+ "background_color": InputPort(
186
+ name="background_color",
187
+ port_type=PortType.INPUT,
188
+ value="#ffffff",
189
+ condition="return !fieldsData.transparent_background.value",
190
+ ),
191
+ "crop_to_subject": InputPort(
192
+ name="crop_to_subject",
193
+ port_type=PortType.CHECKBOX,
194
+ value=False,
195
+ ),
196
+ "output_type": InputPort(
197
+ name="output_type",
198
+ port_type=PortType.SELECT,
199
+ value="markdown",
200
+ options=[
201
+ {"value": "only_link", "label": "only_link"},
202
+ {"value": "markdown", "label": "markdown"},
203
+ {"value": "html", "label": "html"},
204
+ ],
205
+ ),
206
+ "output": OutputPort(),
207
+ },
208
+ )
209
+
210
+
211
+ class ImageEditing(Node):
212
+ def __init__(self, id: Optional[str] = None):
213
+ super().__init__(
214
+ node_type="ImageEditing",
215
+ category="media_editing",
216
+ task_name="media_editing.image_editing",
217
+ node_id=id,
218
+ ports={
219
+ "input_image": InputPort(
220
+ name="input_image",
221
+ port_type=PortType.FILE,
222
+ value=list(),
223
+ support_file_types=[".jpg", ".jpeg", ".png", ".webp"],
224
+ ),
225
+ "crop": InputPort(
226
+ name="crop",
227
+ port_type=PortType.CHECKBOX,
228
+ value=False,
229
+ ),
230
+ "crop_method": InputPort(
231
+ name="crop_method",
232
+ port_type=PortType.SELECT,
233
+ value="proportional",
234
+ options=[
235
+ {"value": "proportional", "label": "proportional"},
236
+ {"value": "fixed", "label": "fixed"},
237
+ ],
238
+ condition="return fieldsData.crop.value",
239
+ ),
240
+ "crop_position": InputPort(
241
+ name="crop_position",
242
+ port_type=PortType.SELECT,
243
+ value="center",
244
+ options=[
245
+ {"value": "center", "label": "center"},
246
+ {"value": "top_left", "label": "top_left"},
247
+ {"value": "top", "label": "top"},
248
+ {"value": "top_right", "label": "top_right"},
249
+ {"value": "right", "label": "right"},
250
+ {"value": "bottom_right", "label": "bottom_right"},
251
+ {"value": "bottom", "label": "bottom"},
252
+ {"value": "bottom_left", "label": "bottom_left"},
253
+ {"value": "left", "label": "left"},
254
+ {"value": "absolute", "label": "absolute"},
255
+ ],
256
+ condition="return fieldsData.crop.value",
257
+ ),
258
+ "crop_x": InputPort(
259
+ name="crop_x",
260
+ port_type=PortType.NUMBER,
261
+ value=1,
262
+ condition="return fieldsData.crop_position.value == 'absolute' && fieldsData.crop.value",
263
+ ),
264
+ "crop_y": InputPort(
265
+ name="crop_y",
266
+ port_type=PortType.NUMBER,
267
+ value=1,
268
+ condition="return fieldsData.crop_position.value == 'absolute' && fieldsData.crop.value",
269
+ ),
270
+ "crop_width": InputPort(
271
+ name="crop_width",
272
+ port_type=PortType.NUMBER,
273
+ value=300,
274
+ condition="return fieldsData.crop.value && fieldsData.crop_method.value == 'fixed'",
275
+ ),
276
+ "crop_height": InputPort(
277
+ name="crop_height",
278
+ port_type=PortType.NUMBER,
279
+ value=300,
280
+ condition="return fieldsData.crop.value && fieldsData.crop_method.value == 'fixed'",
281
+ ),
282
+ "crop_width_ratio": InputPort(
283
+ name="crop_width_ratio",
284
+ port_type=PortType.NUMBER,
285
+ value=1,
286
+ condition="return fieldsData.crop.value && fieldsData.crop_method.value == 'proportional'",
287
+ ),
288
+ "crop_height_ratio": InputPort(
289
+ name="crop_height_ratio",
290
+ port_type=PortType.NUMBER,
291
+ value=1,
292
+ condition="return fieldsData.crop.value && fieldsData.crop_method.value == 'proportional'",
293
+ ),
294
+ "scale": InputPort(
295
+ name="scale",
296
+ port_type=PortType.CHECKBOX,
297
+ value=False,
298
+ ),
299
+ "scale_method": InputPort(
300
+ name="scale_method",
301
+ port_type=PortType.SELECT,
302
+ value="proportional_scale",
303
+ options=[
304
+ {"value": "proportional_scale", "label": "proportional_scale"},
305
+ {"value": "fixed_width_height", "label": "fixed_width_height"},
306
+ ],
307
+ condition="return fieldsData.scale.value",
308
+ ),
309
+ "scale_ratio": InputPort(
310
+ name="scale_ratio",
311
+ port_type=PortType.NUMBER,
312
+ value=1,
313
+ condition="return fieldsData.scale.value && fieldsData.scale_method.value == 'proportional_scale'",
314
+ ),
315
+ "scale_width": InputPort(
316
+ name="scale_width",
317
+ port_type=PortType.NUMBER,
318
+ value=0,
319
+ condition="return fieldsData.scale.value && fieldsData.scale_method.value == 'fixed_width_height'",
320
+ ),
321
+ "scale_height": InputPort(
322
+ name="scale_height",
323
+ port_type=PortType.NUMBER,
324
+ value=0,
325
+ condition="return fieldsData.scale.value && fieldsData.scale_method.value == 'fixed_width_height'",
326
+ ),
327
+ "compress": InputPort(
328
+ name="compress",
329
+ port_type=PortType.NUMBER,
330
+ value=100,
331
+ ),
332
+ "rotate": InputPort(
333
+ name="rotate",
334
+ port_type=PortType.NUMBER,
335
+ value=0,
336
+ ),
337
+ "output_type": InputPort(
338
+ name="output_type",
339
+ port_type=PortType.SELECT,
340
+ value="markdown",
341
+ options=[
342
+ {"value": "only_link", "label": "only_link"},
343
+ {"value": "markdown", "label": "markdown"},
344
+ {"value": "html", "label": "html"},
345
+ ],
346
+ ),
347
+ "output": OutputPort(),
348
+ },
349
+ )
350
+
351
+
352
+ class ImageSegmentation(Node):
353
+ def __init__(self, id: Optional[str] = None):
354
+ super().__init__(
355
+ node_type="ImageSegmentation",
356
+ category="media_editing",
357
+ task_name="media_editing.image_segmentation",
358
+ node_id=id,
359
+ ports={
360
+ "input_image": InputPort(
361
+ name="input_image",
362
+ port_type=PortType.FILE,
363
+ value=list(),
364
+ support_file_types=[".jpg", ".jpeg", ".png", ".webp"],
365
+ ),
366
+ "selection_method": InputPort(
367
+ name="selection_method",
368
+ port_type=PortType.SELECT,
369
+ value="prompt",
370
+ options=[
371
+ {"value": "prompt", "label": "prompt"},
372
+ {"value": "coordinates", "label": "coordinates"},
373
+ ],
374
+ ),
375
+ "prompt": InputPort(
376
+ name="prompt",
377
+ port_type=PortType.TEXTAREA,
378
+ value="",
379
+ condition="return fieldsData.selection_method.value === 'prompt'",
380
+ ),
381
+ "coordinates": InputPort(
382
+ name="coordinates",
383
+ port_type=PortType.TEXTAREA,
384
+ value="",
385
+ condition="return fieldsData.selection_method.value === 'coordinates'",
386
+ ),
387
+ "remove_coordinates": InputPort(
388
+ name="remove_coordinates",
389
+ port_type=PortType.TEXTAREA,
390
+ value="",
391
+ ),
392
+ "overlay_mask": InputPort(
393
+ name="overlay_mask",
394
+ port_type=PortType.CHECKBOX,
395
+ value=False,
396
+ ),
397
+ "output_type": InputPort(
398
+ name="output_type",
399
+ port_type=PortType.SELECT,
400
+ value="markdown",
401
+ options=[
402
+ {"value": "only_link", "label": "only_link"},
403
+ {"value": "markdown", "label": "markdown"},
404
+ {"value": "html", "label": "html"},
405
+ ],
406
+ ),
407
+ "output": OutputPort(),
408
+ },
409
+ )
410
+
411
+
412
+ class ImageWatermark(Node):
413
+ def __init__(self, id: Optional[str] = None):
414
+ super().__init__(
415
+ node_type="ImageWatermark",
416
+ category="media_editing",
417
+ task_name="media_editing.image_watermark",
418
+ node_id=id,
419
+ ports={
420
+ "input_image": InputPort(
421
+ name="input_image",
422
+ port_type=PortType.FILE,
423
+ value=list(),
424
+ support_file_types=[".jpg", ".jpeg", ".png", ".webp"],
425
+ ),
426
+ "image_or_text": InputPort(
427
+ name="image_or_text",
428
+ port_type=PortType.SELECT,
429
+ value="text",
430
+ options=[
431
+ {"value": "text", "label": "text"},
432
+ {"value": "image", "label": "image"},
433
+ ],
434
+ ),
435
+ "watermark_image": InputPort(
436
+ name="watermark_image",
437
+ port_type=PortType.FILE,
438
+ value=list(),
439
+ support_file_types=[".jpg", ".jpeg", ".png", ".webp"],
440
+ condition="return fieldsData.image_or_text.value == 'image'",
441
+ ),
442
+ "watermark_image_width_ratio": InputPort(
443
+ name="watermark_image_width_ratio",
444
+ port_type=PortType.NUMBER,
445
+ value=0.3,
446
+ condition="return fieldsData.image_or_text.value == 'image'",
447
+ ),
448
+ "watermark_image_height_ratio": InputPort(
449
+ name="watermark_image_height_ratio",
450
+ port_type=PortType.NUMBER,
451
+ value=0,
452
+ condition="return fieldsData.image_or_text.value == 'image'",
453
+ ),
454
+ "watermark_text": InputPort(
455
+ name="watermark_text",
456
+ port_type=PortType.TEXTAREA,
457
+ value="",
458
+ condition="return fieldsData.image_or_text.value == 'text'",
459
+ ),
460
+ "watermark_text_font": InputPort(
461
+ name="watermark_text_font",
462
+ port_type=PortType.SELECT,
463
+ value="source_han_sans_sc",
464
+ options=[
465
+ {"value": "source_han_sans_sc", "label": "source_han_sans_sc"},
466
+ {"value": "source_han_sans_tc", "label": "source_han_sans_tc"},
467
+ {"value": "source_han_sans_jp", "label": "source_han_sans_jp"},
468
+ {"value": "source_han_sans_kr", "label": "source_han_sans_kr"},
469
+ {"value": "you_she_biao_ti_hei", "label": "you_she_biao_ti_hei"},
470
+ {"value": "zi_hun_bian_tao_ti", "label": "zi_hun_bian_tao_ti"},
471
+ {"value": "ckt_king_kong", "label": "ckt_king_kong"},
472
+ {"value": "douyin_sans", "label": "douyin_sans"},
473
+ {"value": "alimama_dong_fang_da_kai", "label": "alimama_dong_fang_da_kai"},
474
+ {"value": "inter", "label": "inter"},
475
+ {"value": "custom", "label": "custom"},
476
+ ],
477
+ condition="return fieldsData.image_or_text.value == 'text'",
478
+ ),
479
+ "watermark_text_font_custom": InputPort(
480
+ name="watermark_text_font_custom",
481
+ port_type=PortType.FILE,
482
+ value=list(),
483
+ support_file_types=[".otf", ".ttf", ".ttc", ".otc"],
484
+ condition="return fieldsData.image_or_text.value == 'text' && fieldsData.watermark_text_font.value == 'custom'",
485
+ ),
486
+ "watermark_text_font_size": InputPort(
487
+ name="watermark_text_font_size",
488
+ port_type=PortType.NUMBER,
489
+ value=20,
490
+ condition="return fieldsData.image_or_text.value == 'text'",
491
+ ),
492
+ "watermark_text_font_color": InputPort(
493
+ name="watermark_text_font_color",
494
+ port_type=PortType.INPUT,
495
+ value="#ffffff",
496
+ condition="return fieldsData.image_or_text.value == 'text'",
497
+ ),
498
+ "opacity": InputPort(
499
+ name="opacity",
500
+ port_type=PortType.NUMBER,
501
+ value=0.8,
502
+ ),
503
+ "position": InputPort(
504
+ name="position",
505
+ port_type=PortType.SELECT,
506
+ value="bottom_right",
507
+ options=[
508
+ {"value": "center", "label": "center"},
509
+ {"value": "top_left", "label": "top_left"},
510
+ {"value": "top", "label": "top"},
511
+ {"value": "top_right", "label": "top_right"},
512
+ {"value": "right", "label": "right"},
513
+ {"value": "bottom_right", "label": "bottom_right"},
514
+ {"value": "bottom", "label": "bottom"},
515
+ {"value": "bottom_left", "label": "bottom_left"},
516
+ {"value": "left", "label": "left"},
517
+ ],
518
+ ),
519
+ "vertical_gap": InputPort(
520
+ name="vertical_gap",
521
+ port_type=PortType.NUMBER,
522
+ value=10,
523
+ ),
524
+ "horizontal_gap": InputPort(
525
+ name="horizontal_gap",
526
+ port_type=PortType.NUMBER,
527
+ value=10,
528
+ ),
529
+ "output_type": InputPort(
530
+ name="output_type",
531
+ port_type=PortType.SELECT,
532
+ value="markdown",
533
+ options=[
534
+ {"value": "only_link", "label": "only_link"},
535
+ {"value": "markdown", "label": "markdown"},
536
+ {"value": "html", "label": "html"},
537
+ ],
538
+ ),
539
+ "output": OutputPort(),
540
+ },
541
+ )
542
+
543
+
544
+ class VideoEditing(Node):
545
+ def __init__(self, id: Optional[str] = None):
546
+ super().__init__(
547
+ node_type="VideoEditing",
548
+ category="media_editing",
549
+ task_name="media_editing.video_editing",
550
+ node_id=id,
551
+ ports={
552
+ "input_video": InputPort(
553
+ name="input_video",
554
+ port_type=PortType.FILE,
555
+ value=list(),
556
+ support_file_types=["video/*"],
557
+ ),
558
+ "video_processing_logic": InputPort(
559
+ name="video_processing_logic",
560
+ port_type=PortType.SELECT,
561
+ value="process_each",
562
+ options=[
563
+ {"value": "process_each", "label": "process_each"},
564
+ {"value": "merge", "label": "merge"},
565
+ ],
566
+ ),
567
+ "trim_video": InputPort(
568
+ name="trim_video",
569
+ port_type=PortType.CHECKBOX,
570
+ value=False,
571
+ ),
572
+ "trim_start_time": InputPort(
573
+ name="trim_start_time",
574
+ port_type=PortType.INPUT,
575
+ value="00:00:00",
576
+ condition="return fieldsData.trim_video.value",
577
+ ),
578
+ "trim_end_time": InputPort(
579
+ name="trim_end_time",
580
+ port_type=PortType.INPUT,
581
+ value="00:01:00",
582
+ condition="return fieldsData.trim_video.value",
583
+ ),
584
+ "rotate_video": InputPort(
585
+ name="rotate_video",
586
+ port_type=PortType.SELECT,
587
+ value=0,
588
+ options=[
589
+ {"value": 0, "label": "0"},
590
+ {"value": 90, "label": "90"},
591
+ {"value": 180, "label": "180"},
592
+ {"value": 270, "label": "270"},
593
+ ],
594
+ ),
595
+ "add_watermark": InputPort(
596
+ name="add_watermark",
597
+ port_type=PortType.CHECKBOX,
598
+ value=False,
599
+ ),
600
+ "watermark_text": InputPort(
601
+ name="watermark_text",
602
+ port_type=PortType.INPUT,
603
+ value="",
604
+ condition="return fieldsData.add_watermark.value",
605
+ ),
606
+ "output_video_format": InputPort(
607
+ name="output_video_format",
608
+ port_type=PortType.SELECT,
609
+ value="mp4",
610
+ options=[
611
+ {"value": "mp4", "label": "mp4"},
612
+ {"value": "avi", "label": "avi"},
613
+ {"value": "mov", "label": "mov"},
614
+ ],
615
+ ),
616
+ "output": OutputPort(),
617
+ },
618
+ )
619
+
620
+
621
+ class VideoScreenshot(Node):
622
+ def __init__(self, id: Optional[str] = None):
623
+ super().__init__(
624
+ node_type="VideoScreenshot",
625
+ category="media_editing",
626
+ task_name="media_editing.video_screenshot",
627
+ node_id=id,
628
+ ports={
629
+ "input_video": InputPort(
630
+ name="input_video",
631
+ port_type=PortType.FILE,
632
+ value=list(),
633
+ support_file_types=["video/*"],
634
+ ),
635
+ "screenshot_method": InputPort(
636
+ name="screenshot_method",
637
+ port_type=PortType.SELECT,
638
+ value="interval",
639
+ options=[
640
+ {"value": "interval", "label": "interval"},
641
+ {"value": "timestamps", "label": "timestamps"},
642
+ ],
643
+ ),
644
+ "screenshot_interval": InputPort(
645
+ name="screenshot_interval",
646
+ port_type=PortType.NUMBER,
647
+ value=10,
648
+ condition="return fieldsData.screenshot_method.value === 'interval'",
649
+ ),
650
+ "screenshot_timestamps": InputPort(
651
+ name="screenshot_timestamps",
652
+ port_type=PortType.INPUT,
653
+ value="",
654
+ condition="return fieldsData.screenshot_method.value === 'timestamps'",
655
+ ),
656
+ "output_type": InputPort(
657
+ name="output_type",
658
+ port_type=PortType.SELECT,
659
+ value="markdown",
660
+ options=[
661
+ {"value": "only_link", "label": "only_link"},
662
+ {"value": "markdown", "label": "markdown"},
663
+ {"value": "html", "label": "html"},
664
+ ],
665
+ ),
666
+ "output": OutputPort(),
667
+ },
668
+ )