context.dev 2.8.0 → 2.10.0

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.
Files changed (116) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +28 -0
  3. data/README.md +1 -1
  4. data/lib/context_dev/client.rb +10 -0
  5. data/lib/context_dev/models/batch_delete_params.rb +22 -0
  6. data/lib/context_dev/models/batch_delete_response.rb +60 -0
  7. data/lib/context_dev/models/batch_get_results_response.rb +46 -4
  8. data/lib/context_dev/models/batch_list_response.rb +13 -4
  9. data/lib/context_dev/models/batch_retrieve_response.rb +13 -4
  10. data/lib/context_dev/models/batch_submit_params.rb +2080 -26
  11. data/lib/context_dev/models/batch_submit_response.rb +125 -531
  12. data/lib/context_dev/models/brand_retrieve_response.rb +50 -1
  13. data/lib/context_dev/models/brand_search_params.rb +41 -3
  14. data/lib/context_dev/models/brand_search_response.rb +3 -2
  15. data/lib/context_dev/models/crawl_controls.rb +21 -15
  16. data/lib/context_dev/models/news_search_params.rb +467 -0
  17. data/lib/context_dev/models/news_search_response.rb +238 -0
  18. data/lib/context_dev/models/parse_handle_params.rb +20 -147
  19. data/lib/context_dev/models/person_enrich_params.rb +176 -0
  20. data/lib/context_dev/models/person_enrich_response.rb +641 -0
  21. data/lib/context_dev/models/utility_prefetch_params.rb +19 -16
  22. data/lib/context_dev/models/utility_prefetch_response.rb +4 -5
  23. data/lib/context_dev/models/web_screenshot_params.rb +3 -30
  24. data/lib/context_dev/models/web_search_response.rb +1 -0
  25. data/lib/context_dev/models/web_web_crawl_md_params.rb +5 -4
  26. data/lib/context_dev/models/web_web_crawl_md_response.rb +30 -1
  27. data/lib/context_dev/models/web_web_scrape_html_params.rb +20 -156
  28. data/lib/context_dev/models/web_web_scrape_html_response.rb +30 -1
  29. data/lib/context_dev/models/web_web_scrape_images_params.rb +12 -124
  30. data/lib/context_dev/models/web_web_scrape_md_params.rb +40 -241
  31. data/lib/context_dev/models/web_web_scrape_md_response.rb +41 -2
  32. data/lib/context_dev/models/web_web_scrape_sitemap_params.rb +11 -1
  33. data/lib/context_dev/models/web_web_scrape_sitemap_response.rb +3 -2
  34. data/lib/context_dev/models.rb +6 -0
  35. data/lib/context_dev/resources/batch.rb +33 -7
  36. data/lib/context_dev/resources/brand.rb +10 -10
  37. data/lib/context_dev/resources/news.rb +51 -0
  38. data/lib/context_dev/resources/parse.rb +5 -5
  39. data/lib/context_dev/resources/people.rb +56 -0
  40. data/lib/context_dev/resources/utility.rb +7 -6
  41. data/lib/context_dev/resources/web.rb +46 -24
  42. data/lib/context_dev/version.rb +1 -1
  43. data/lib/context_dev.rb +8 -0
  44. data/rbi/context_dev/client.rbi +8 -0
  45. data/rbi/context_dev/models/batch_delete_params.rbi +40 -0
  46. data/rbi/context_dev/models/batch_delete_response.rbi +116 -0
  47. data/rbi/context_dev/models/batch_get_results_response.rbi +85 -3
  48. data/rbi/context_dev/models/batch_list_response.rbi +24 -8
  49. data/rbi/context_dev/models/batch_retrieve_response.rbi +24 -8
  50. data/rbi/context_dev/models/batch_submit_params.rbi +6421 -44
  51. data/rbi/context_dev/models/batch_submit_response.rbi +184 -1151
  52. data/rbi/context_dev/models/brand_retrieve_response.rbi +152 -0
  53. data/rbi/context_dev/models/brand_search_params.rbi +71 -2
  54. data/rbi/context_dev/models/brand_search_response.rbi +4 -2
  55. data/rbi/context_dev/models/crawl_controls.rbi +22 -28
  56. data/rbi/context_dev/models/news_search_params.rbi +1294 -0
  57. data/rbi/context_dev/models/news_search_response.rbi +423 -0
  58. data/rbi/context_dev/models/parse_handle_params.rbi +30 -323
  59. data/rbi/context_dev/models/person_enrich_params.rbi +332 -0
  60. data/rbi/context_dev/models/person_enrich_response.rbi +1295 -0
  61. data/rbi/context_dev/models/utility_prefetch_params.rbi +24 -16
  62. data/rbi/context_dev/models/utility_prefetch_response.rbi +8 -6
  63. data/rbi/context_dev/models/web_screenshot_params.rbi +4 -71
  64. data/rbi/context_dev/models/web_search_response.rbi +5 -0
  65. data/rbi/context_dev/models/web_web_crawl_md_params.rbi +8 -6
  66. data/rbi/context_dev/models/web_web_crawl_md_response.rbi +67 -0
  67. data/rbi/context_dev/models/web_web_scrape_html_params.rbi +30 -363
  68. data/rbi/context_dev/models/web_web_scrape_html_response.rbi +65 -0
  69. data/rbi/context_dev/models/web_web_scrape_images_params.rbi +16 -287
  70. data/rbi/context_dev/models/web_web_scrape_md_params.rbi +57 -558
  71. data/rbi/context_dev/models/web_web_scrape_md_response.rbi +80 -0
  72. data/rbi/context_dev/models/web_web_scrape_sitemap_params.rbi +15 -0
  73. data/rbi/context_dev/models/web_web_scrape_sitemap_response.rbi +4 -2
  74. data/rbi/context_dev/models.rbi +6 -0
  75. data/rbi/context_dev/resources/batch.rbi +32 -10
  76. data/rbi/context_dev/resources/brand.rbi +14 -8
  77. data/rbi/context_dev/resources/news.rbi +46 -0
  78. data/rbi/context_dev/resources/parse.rbi +10 -26
  79. data/rbi/context_dev/resources/people.rbi +47 -0
  80. data/rbi/context_dev/resources/utility.rbi +8 -6
  81. data/rbi/context_dev/resources/web.rbi +49 -66
  82. data/sig/context_dev/client.rbs +4 -0
  83. data/sig/context_dev/models/batch_delete_params.rbs +23 -0
  84. data/sig/context_dev/models/batch_delete_response.rbs +57 -0
  85. data/sig/context_dev/models/batch_get_results_response.rbs +30 -2
  86. data/sig/context_dev/models/batch_list_response.rbs +16 -2
  87. data/sig/context_dev/models/batch_retrieve_response.rbs +16 -2
  88. data/sig/context_dev/models/batch_submit_params.rbs +2666 -15
  89. data/sig/context_dev/models/batch_submit_response.rbs +78 -466
  90. data/sig/context_dev/models/brand_retrieve_response.rbs +62 -0
  91. data/sig/context_dev/models/brand_search_params.rbs +38 -1
  92. data/sig/context_dev/models/crawl_controls.rbs +16 -16
  93. data/sig/context_dev/models/news_search_params.rbs +532 -0
  94. data/sig/context_dev/models/news_search_response.rbs +206 -0
  95. data/sig/context_dev/models/parse_handle_params.rbs +25 -90
  96. data/sig/context_dev/models/person_enrich_params.rbs +199 -0
  97. data/sig/context_dev/models/person_enrich_response.rbs +638 -0
  98. data/sig/context_dev/models/utility_prefetch_params.rbs +2 -1
  99. data/sig/context_dev/models/utility_prefetch_response.rbs +2 -1
  100. data/sig/context_dev/models/web_screenshot_params.rbs +5 -18
  101. data/sig/context_dev/models/web_search_response.rbs +2 -0
  102. data/sig/context_dev/models/web_web_crawl_md_response.rbs +21 -0
  103. data/sig/context_dev/models/web_web_scrape_html_params.rbs +24 -94
  104. data/sig/context_dev/models/web_web_scrape_html_response.rbs +21 -0
  105. data/sig/context_dev/models/web_web_scrape_images_params.rbs +20 -72
  106. data/sig/context_dev/models/web_web_scrape_md_params.rbs +46 -148
  107. data/sig/context_dev/models/web_web_scrape_md_response.rbs +28 -0
  108. data/sig/context_dev/models/web_web_scrape_sitemap_params.rbs +7 -0
  109. data/sig/context_dev/models.rbs +6 -0
  110. data/sig/context_dev/resources/batch.rbs +8 -2
  111. data/sig/context_dev/resources/brand.rbs +3 -0
  112. data/sig/context_dev/resources/news.rbs +17 -0
  113. data/sig/context_dev/resources/parse.rbs +5 -5
  114. data/sig/context_dev/resources/people.rbs +19 -0
  115. data/sig/context_dev/resources/web.rbs +13 -11
  116. metadata +26 -2
@@ -14,7 +14,7 @@ module ContextDev
14
14
  )
15
15
  end
16
16
 
17
- # Identifier of the brand to prefetch. Provide exactly one of domain or email.
17
+ # Identifier of the target to prefetch. Provide exactly one of domain or email.
18
18
  sig do
19
19
  returns(
20
20
  T.any(
@@ -25,7 +25,8 @@ module ContextDev
25
25
  end
26
26
  attr_accessor :identifier
27
27
 
28
- # What to prefetch. Currently only 'brand' is supported.
28
+ # What to prefetch: 'brand' warms the brand data cache, 'styleguide' warms the
29
+ # styleguide cache.
29
30
  sig { returns(ContextDev::UtilityPrefetchParams::Type::OrSymbol) }
30
31
  attr_accessor :type
31
32
 
@@ -59,9 +60,10 @@ module ContextDev
59
60
  ).returns(T.attached_class)
60
61
  end
61
62
  def self.new(
62
- # Identifier of the brand to prefetch. Provide exactly one of domain or email.
63
+ # Identifier of the target to prefetch. Provide exactly one of domain or email.
63
64
  identifier:,
64
- # What to prefetch. Currently only 'brand' is supported.
65
+ # What to prefetch: 'brand' warms the brand data cache, 'styleguide' warms the
66
+ # styleguide cache.
65
67
  type:,
66
68
  # Optional tags for tracking usage. Up to 20 tags, each 1 to 50 characters.
67
69
  tags: nil,
@@ -91,7 +93,7 @@ module ContextDev
91
93
  def to_hash
92
94
  end
93
95
 
94
- # Identifier of the brand to prefetch. Provide exactly one of domain or email.
96
+ # Identifier of the target to prefetch. Provide exactly one of domain or email.
95
97
  module Identifier
96
98
  extend ContextDev::Internal::Type::Union
97
99
 
@@ -112,14 +114,14 @@ module ContextDev
112
114
  )
113
115
  end
114
116
 
115
- # Domain name to prefetch brand data for
117
+ # Domain name to prefetch data for
116
118
  sig { returns(String) }
117
119
  attr_accessor :domain
118
120
 
119
- # Prefetch brand data by domain.
121
+ # Prefetch by domain.
120
122
  sig { params(domain: String).returns(T.attached_class) }
121
123
  def self.new(
122
- # Domain name to prefetch brand data for
124
+ # Domain name to prefetch data for
123
125
  domain:
124
126
  )
125
127
  end
@@ -138,18 +140,18 @@ module ContextDev
138
140
  )
139
141
  end
140
142
 
141
- # Email address to prefetch brand data for. The domain will be extracted from the
142
- # email. Free email providers (gmail.com, yahoo.com, etc.) and disposable email
143
- # addresses are not allowed.
143
+ # Email address to prefetch data for. The domain will be extracted from the email.
144
+ # Free email providers (gmail.com, yahoo.com, etc.) and disposable email addresses
145
+ # are not allowed.
144
146
  sig { returns(String) }
145
147
  attr_accessor :email
146
148
 
147
- # Prefetch brand data by email. The domain will be extracted and validated.
149
+ # Prefetch by email. The domain will be extracted and validated.
148
150
  sig { params(email: String).returns(T.attached_class) }
149
151
  def self.new(
150
- # Email address to prefetch brand data for. The domain will be extracted from the
151
- # email. Free email providers (gmail.com, yahoo.com, etc.) and disposable email
152
- # addresses are not allowed.
152
+ # Email address to prefetch data for. The domain will be extracted from the email.
153
+ # Free email providers (gmail.com, yahoo.com, etc.) and disposable email addresses
154
+ # are not allowed.
153
155
  email:
154
156
  )
155
157
  end
@@ -168,7 +170,8 @@ module ContextDev
168
170
  end
169
171
  end
170
172
 
171
- # What to prefetch. Currently only 'brand' is supported.
173
+ # What to prefetch: 'brand' warms the brand data cache, 'styleguide' warms the
174
+ # styleguide cache.
172
175
  module Type
173
176
  extend ContextDev::Internal::Type::Enum
174
177
 
@@ -180,6 +183,11 @@ module ContextDev
180
183
 
181
184
  BRAND =
182
185
  T.let(:brand, ContextDev::UtilityPrefetchParams::Type::TaggedSymbol)
186
+ STYLEGUIDE =
187
+ T.let(
188
+ :styleguide,
189
+ ContextDev::UtilityPrefetchParams::Type::TaggedSymbol
190
+ )
183
191
 
184
192
  sig do
185
193
  override.returns(
@@ -49,8 +49,7 @@ module ContextDev
49
49
  sig { params(status: String).void }
50
50
  attr_writer :status
51
51
 
52
- # The type of prefetch that was queued, echoed from the request (currently always
53
- # 'brand')
52
+ # The type of prefetch that was queued, echoed from the request
54
53
  sig do
55
54
  returns(
56
55
  T.nilable(
@@ -87,8 +86,7 @@ module ContextDev
87
86
  message: nil,
88
87
  # Status of the response, e.g., 'ok'
89
88
  status: nil,
90
- # The type of prefetch that was queued, echoed from the request (currently always
91
- # 'brand')
89
+ # The type of prefetch that was queued, echoed from the request
92
90
  type: nil
93
91
  )
94
92
  end
@@ -150,8 +148,7 @@ module ContextDev
150
148
  end
151
149
  end
152
150
 
153
- # The type of prefetch that was queued, echoed from the request (currently always
154
- # 'brand')
151
+ # The type of prefetch that was queued, echoed from the request
155
152
  module Type
156
153
  extend ContextDev::Internal::Type::Enum
157
154
 
@@ -166,6 +163,11 @@ module ContextDev
166
163
  :brand,
167
164
  ContextDev::Models::UtilityPrefetchResponse::Type::TaggedSymbol
168
165
  )
166
+ STYLEGUIDE =
167
+ T.let(
168
+ :styleguide,
169
+ ContextDev::Models::UtilityPrefetchResponse::Type::TaggedSymbol
170
+ )
169
171
 
170
172
  sig do
171
173
  override.returns(
@@ -78,27 +78,10 @@ module ContextDev
78
78
  # Optional parameter to control cookie/consent popup handling. If 'true', we
79
79
  # dismiss cookie banner before capture. If 'false' or not provided, captures the
80
80
  # page without that step.
81
- sig do
82
- returns(
83
- T.nilable(
84
- T.any(
85
- T::Boolean,
86
- ContextDev::WebScreenshotParams::HandleCookiePopup::OrSymbol
87
- )
88
- )
89
- )
90
- end
81
+ sig { returns(T.nilable(T::Boolean)) }
91
82
  attr_reader :handle_cookie_popup
92
83
 
93
- sig do
94
- params(
95
- handle_cookie_popup:
96
- T.any(
97
- T::Boolean,
98
- ContextDev::WebScreenshotParams::HandleCookiePopup::OrSymbol
99
- )
100
- ).void
101
- end
84
+ sig { params(handle_cookie_popup: T::Boolean).void }
102
85
  attr_writer :handle_cookie_popup
103
86
 
104
87
  # Return a cached screenshot if a prior screenshot for the same parameters exists
@@ -180,11 +163,7 @@ module ContextDev
180
163
  domain: String,
181
164
  full_screenshot:
182
165
  ContextDev::WebScreenshotParams::FullScreenshot::OrSymbol,
183
- handle_cookie_popup:
184
- T.any(
185
- T::Boolean,
186
- ContextDev::WebScreenshotParams::HandleCookiePopup::OrSymbol
187
- ),
166
+ handle_cookie_popup: T::Boolean,
188
167
  max_age_ms: T.nilable(Integer),
189
168
  page: ContextDev::WebScreenshotParams::Page::OrSymbol,
190
169
  scroll_offset: T.nilable(Integer),
@@ -269,11 +248,7 @@ module ContextDev
269
248
  domain: String,
270
249
  full_screenshot:
271
250
  ContextDev::WebScreenshotParams::FullScreenshot::OrSymbol,
272
- handle_cookie_popup:
273
- T.any(
274
- T::Boolean,
275
- ContextDev::WebScreenshotParams::HandleCookiePopup::OrSymbol
276
- ),
251
+ handle_cookie_popup: T::Boolean,
277
252
  max_age_ms: T.nilable(Integer),
278
253
  page: ContextDev::WebScreenshotParams::Page::OrSymbol,
279
254
  scroll_offset: T.nilable(Integer),
@@ -579,48 +554,6 @@ module ContextDev
579
554
  end
580
555
  end
581
556
 
582
- # Optional parameter to control cookie/consent popup handling. If 'true', we
583
- # dismiss cookie banner before capture. If 'false' or not provided, captures the
584
- # page without that step.
585
- module HandleCookiePopup
586
- extend ContextDev::Internal::Type::Union
587
-
588
- Variants =
589
- T.type_alias do
590
- T.any(
591
- T::Boolean,
592
- ContextDev::WebScreenshotParams::HandleCookiePopup::TaggedSymbol
593
- )
594
- end
595
-
596
- sig do
597
- override.returns(
598
- T::Array[
599
- ContextDev::WebScreenshotParams::HandleCookiePopup::Variants
600
- ]
601
- )
602
- end
603
- def self.variants
604
- end
605
-
606
- TaggedSymbol =
607
- T.type_alias do
608
- T.all(Symbol, ContextDev::WebScreenshotParams::HandleCookiePopup)
609
- end
610
- OrSymbol = T.type_alias { T.any(Symbol, String) }
611
-
612
- TRUE =
613
- T.let(
614
- :true,
615
- ContextDev::WebScreenshotParams::HandleCookiePopup::TaggedSymbol
616
- )
617
- FALSE =
618
- T.let(
619
- :false,
620
- ContextDev::WebScreenshotParams::HandleCookiePopup::TaggedSymbol
621
- )
622
- end
623
-
624
557
  # Optional parameter to specify which page type to screenshot. If provided, the
625
558
  # system will scrape the domain's links and use heuristics to find the most
626
559
  # appropriate URL for the specified page type (30 supported languages). If not
@@ -224,6 +224,11 @@ module ContextDev
224
224
  :TIMEOUT,
225
225
  ContextDev::Models::WebSearchResponse::Result::Markdown::Code::TaggedSymbol
226
226
  )
227
+ CONTENT_TOO_LARGE =
228
+ T.let(
229
+ :CONTENT_TOO_LARGE,
230
+ ContextDev::Models::WebSearchResponse::Result::Markdown::Code::TaggedSymbol
231
+ )
227
232
  WEBSITE_ACCESS_ERROR =
228
233
  T.let(
229
234
  :WEBSITE_ACCESS_ERROR,
@@ -553,9 +553,10 @@ module ContextDev
553
553
  sig { params(end_: Integer).void }
554
554
  attr_writer :end_
555
555
 
556
- # When true, detect and OCR images embedded in the selected PDF pages, inserting
557
- # recognized text at each image's position in page reading order while preserving
558
- # the PDF text layer. This is separate from automatic scanned-PDF OCR fallback.
556
+ # When true, OCR the selected PDF pages that have no usable text layer (scans),
557
+ # replacing each recovered page's text with the OCR result while pages with a real
558
+ # text layer keep it. Billed at 1 credit per page OCR actually recovered, on top
559
+ # of the base request cost.
559
560
  sig { returns(T.nilable(T::Boolean)) }
560
561
  attr_reader :ocr
561
562
 
@@ -591,9 +592,10 @@ module ContextDev
591
592
  # Last 1-based PDF page to parse. When omitted, parsing ends at the last page.
592
593
  # Must be greater than or equal to start when both are provided.
593
594
  end_: nil,
594
- # When true, detect and OCR images embedded in the selected PDF pages, inserting
595
- # recognized text at each image's position in page reading order while preserving
596
- # the PDF text layer. This is separate from automatic scanned-PDF OCR fallback.
595
+ # When true, OCR the selected PDF pages that have no usable text layer (scans),
596
+ # replacing each recovered page's text with the OCR result while pages with a real
597
+ # text layer keep it. Billed at 1 credit per page OCR actually recovered, on top
598
+ # of the base request cost.
597
599
  ocr: nil,
598
600
  # When true, PDF pages are fetched and parsed. When false, PDF pages are skipped
599
601
  # entirely (not included in results and not counted as failures).
@@ -307,6 +307,29 @@ module ContextDev
307
307
  sig { params(favicon: String).void }
308
308
  attr_writer :favicon
309
309
 
310
+ # Page headings (h1–h6) in document order, extracted from the unfiltered document.
311
+ # Capped at the first 500 headings. Omitted when the page has none.
312
+ sig do
313
+ returns(
314
+ T.nilable(
315
+ T::Array[
316
+ ContextDev::Models::WebWebCrawlMdResponse::Result::Metadata::Heading
317
+ ]
318
+ )
319
+ )
320
+ end
321
+ attr_reader :headings
322
+
323
+ sig do
324
+ params(
325
+ headings:
326
+ T::Array[
327
+ ContextDev::Models::WebWebCrawlMdResponse::Result::Metadata::Heading::OrHash
328
+ ]
329
+ ).void
330
+ end
331
+ attr_writer :headings
332
+
310
333
  # Primary resolved preview image from Open Graph, Twitter, or image metadata.
311
334
  sig { returns(T.nilable(String)) }
312
335
  attr_reader :image
@@ -433,6 +456,10 @@ module ContextDev
433
456
  canonical_url: String,
434
457
  description: String,
435
458
  favicon: String,
459
+ headings:
460
+ T::Array[
461
+ ContextDev::Models::WebWebCrawlMdResponse::Result::Metadata::Heading::OrHash
462
+ ],
436
463
  image: String,
437
464
  json_ld: T::Array[T::Hash[Symbol, T.anything]],
438
465
  keywords: T::Array[String],
@@ -481,6 +508,9 @@ module ContextDev
481
508
  description: nil,
482
509
  # Resolved favicon URL, when present.
483
510
  favicon: nil,
511
+ # Page headings (h1–h6) in document order, extracted from the unfiltered document.
512
+ # Capped at the first 500 headings. Omitted when the page has none.
513
+ headings: nil,
484
514
  # Primary resolved preview image from Open Graph, Twitter, or image metadata.
485
515
  image: nil,
486
516
  # JSON-LD structured data blocks parsed from the page.
@@ -527,6 +557,10 @@ module ContextDev
527
557
  canonical_url: String,
528
558
  description: String,
529
559
  favicon: String,
560
+ headings:
561
+ T::Array[
562
+ ContextDev::Models::WebWebCrawlMdResponse::Result::Metadata::Heading
563
+ ],
530
564
  image: String,
531
565
  json_ld: T::Array[T::Hash[Symbol, T.anything]],
532
566
  keywords: T::Array[String],
@@ -636,6 +670,39 @@ module ContextDev
636
670
  end
637
671
  end
638
672
 
673
+ class Heading < ContextDev::Internal::Type::BaseModel
674
+ OrHash =
675
+ T.type_alias do
676
+ T.any(
677
+ ContextDev::Models::WebWebCrawlMdResponse::Result::Metadata::Heading,
678
+ ContextDev::Internal::AnyHash
679
+ )
680
+ end
681
+
682
+ # Heading level, 1–6 (from h1–h6).
683
+ sig { returns(Integer) }
684
+ attr_accessor :level
685
+
686
+ # Heading text with whitespace collapsed, truncated to 1000 characters.
687
+ sig { returns(String) }
688
+ attr_accessor :text
689
+
690
+ sig do
691
+ params(level: Integer, text: String).returns(T.attached_class)
692
+ end
693
+ def self.new(
694
+ # Heading level, 1–6 (from h1–h6).
695
+ level:,
696
+ # Heading text with whitespace collapsed, truncated to 1000 characters.
697
+ text:
698
+ )
699
+ end
700
+
701
+ sig { override.returns({ level: Integer, text: String }) }
702
+ def to_hash
703
+ end
704
+ end
705
+
639
706
  module OpenGraph
640
707
  extend ContextDev::Internal::Type::Union
641
708