@swiftbrowser/swift 0.1.0 → 0.2.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 (393) hide show
  1. package/Package.swift +200 -9
  2. package/README.md +7 -9
  3. package/Sources/AVFoundation/AVFoundation.swift +131 -0
  4. package/Sources/AVFoundation/Asset.swift +487 -0
  5. package/Sources/AVFoundation/AudioSession.swift +144 -0
  6. package/Sources/AVFoundation/CMTime.swift +303 -0
  7. package/Sources/AVFoundation/Capture.swift +688 -0
  8. package/Sources/AVFoundation/Player.swift +749 -0
  9. package/Sources/AVFoundation/PlayerView.swift +117 -0
  10. package/Sources/AVKit/AVKit.swift +132 -0
  11. package/Sources/Accelerate/Accelerate.swift +122 -0
  12. package/Sources/AppIntents/AppIntents.swift +144 -0
  13. package/Sources/AppIntents/Parameters.swift +220 -0
  14. package/Sources/AppIntents/Shortcuts.swift +159 -0
  15. package/Sources/AudioToolbox/AudioToolbox.swift +55 -0
  16. package/Sources/AuthenticationServices/AuthenticationServices.swift +257 -0
  17. package/Sources/AuthenticationServices/Authorization.swift +251 -0
  18. package/Sources/Charts/Charts.swift +0 -4
  19. package/Sources/Combine/AnyCancellable.swift +65 -0
  20. package/Sources/Combine/AnyPublisher.swift +148 -0
  21. package/Sources/Combine/AnySubscriber.swift +230 -0
  22. package/Sources/Combine/Cancellable.swift +35 -0
  23. package/Sources/Combine/Codable.swift +29 -0
  24. package/Sources/Combine/CombineIdentifier.swift +45 -0
  25. package/Sources/Combine/Concurrency/ConcurrencyHelpers.swift +24 -0
  26. package/Sources/Combine/Concurrency/Future+Concurrency.swift +136 -0
  27. package/Sources/Combine/Concurrency/GENERATED-Publisher+Concurrency.swift +397 -0
  28. package/Sources/Combine/CurrentValueSubject.swift +252 -0
  29. package/Sources/Combine/CustomCombineIdentifierConvertible.swift +28 -0
  30. package/Sources/Combine/Future.swift +228 -0
  31. package/Sources/Combine/GENERATED-RootProtocols.swift +426 -0
  32. package/Sources/Combine/Helpers/ConduitBase.swift +40 -0
  33. package/Sources/Combine/Helpers/ConduitList.swift +59 -0
  34. package/Sources/Combine/Helpers/DebugHook.swift +177 -0
  35. package/Sources/Combine/Helpers/FilterProducer.swift +174 -0
  36. package/Sources/Combine/Helpers/Locking.swift +30 -0
  37. package/Sources/Combine/Helpers/PartialCompletion.swift +26 -0
  38. package/Sources/Combine/Helpers/ReduceProducer.swift +249 -0
  39. package/Sources/Combine/Helpers/SubjectSubscriber.swift +96 -0
  40. package/Sources/Combine/Helpers/SubscriberTap.swift +69 -0
  41. package/Sources/Combine/Helpers/SubscriptionStatus.swift +33 -0
  42. package/Sources/Combine/Helpers/SubscriptionTap.swift +33 -0
  43. package/Sources/Combine/Helpers/Utils.swift +30 -0
  44. package/Sources/Combine/Helpers/Violations.swift +33 -0
  45. package/Sources/Combine/ImmediateScheduler.swift +178 -0
  46. package/Sources/Combine/LICENSE +21 -0
  47. package/Sources/Combine/NotificationPublisher.swift +48 -0
  48. package/Sources/Combine/ObjectWillChange.swift +46 -0
  49. package/Sources/Combine/PassthroughSubject.swift +222 -0
  50. package/Sources/Combine/Publisher+Subscribe.swift +53 -0
  51. package/Sources/Combine/Publishers/Deferred.swift +48 -0
  52. package/Sources/Combine/Publishers/Empty.swift +54 -0
  53. package/Sources/Combine/Publishers/Fail.swift +42 -0
  54. package/Sources/Combine/Publishers/GENERATED-Publishers.Catch.swift +673 -0
  55. package/Sources/Combine/Publishers/GENERATED-Publishers.Encode.swift +388 -0
  56. package/Sources/Combine/Publishers/GENERATED-Publishers.MapKeyPath.swift +384 -0
  57. package/Sources/Combine/Publishers/Just.swift +313 -0
  58. package/Sources/Combine/Publishers/Optional.Publisher.swift +315 -0
  59. package/Sources/Combine/Publishers/Publishers.AllSatisfy.swift +217 -0
  60. package/Sources/Combine/Publishers/Publishers.AssertNoFailure.swift +158 -0
  61. package/Sources/Combine/Publishers/Publishers.Autoconnect.swift +193 -0
  62. package/Sources/Combine/Publishers/Publishers.Breakpoint.swift +231 -0
  63. package/Sources/Combine/Publishers/Publishers.Buffer.swift +356 -0
  64. package/Sources/Combine/Publishers/Publishers.Collect.swift +102 -0
  65. package/Sources/Combine/Publishers/Publishers.CollectByCount.swift +195 -0
  66. package/Sources/Combine/Publishers/Publishers.CompactMap.swift +241 -0
  67. package/Sources/Combine/Publishers/Publishers.Comparison.swift +371 -0
  68. package/Sources/Combine/Publishers/Publishers.Concatenate.swift +474 -0
  69. package/Sources/Combine/Publishers/Publishers.Contains.swift +293 -0
  70. package/Sources/Combine/Publishers/Publishers.Count.swift +87 -0
  71. package/Sources/Combine/Publishers/Publishers.Debounce.swift +332 -0
  72. package/Sources/Combine/Publishers/Publishers.Delay.swift +269 -0
  73. package/Sources/Combine/Publishers/Publishers.Drop.swift +155 -0
  74. package/Sources/Combine/Publishers/Publishers.DropUntilOutput.swift +283 -0
  75. package/Sources/Combine/Publishers/Publishers.DropWhile.swift +378 -0
  76. package/Sources/Combine/Publishers/Publishers.Filter.swift +248 -0
  77. package/Sources/Combine/Publishers/Publishers.First.swift +261 -0
  78. package/Sources/Combine/Publishers/Publishers.FlatMap.swift +533 -0
  79. package/Sources/Combine/Publishers/Publishers.HandleEvents.swift +260 -0
  80. package/Sources/Combine/Publishers/Publishers.IgnoreOutput.swift +109 -0
  81. package/Sources/Combine/Publishers/Publishers.Last.swift +252 -0
  82. package/Sources/Combine/Publishers/Publishers.MakeConnectable.swift +82 -0
  83. package/Sources/Combine/Publishers/Publishers.Map.swift +351 -0
  84. package/Sources/Combine/Publishers/Publishers.MapError.swift +140 -0
  85. package/Sources/Combine/Publishers/Publishers.MeasureInterval.swift +187 -0
  86. package/Sources/Combine/Publishers/Publishers.Multicast.swift +284 -0
  87. package/Sources/Combine/Publishers/Publishers.Output.swift +241 -0
  88. package/Sources/Combine/Publishers/Publishers.PrefixUntilOutput.swift +197 -0
  89. package/Sources/Combine/Publishers/Publishers.PrefixWhile.swift +176 -0
  90. package/Sources/Combine/Publishers/Publishers.Print.swift +206 -0
  91. package/Sources/Combine/Publishers/Publishers.ReceiveOn.swift +227 -0
  92. package/Sources/Combine/Publishers/Publishers.Reduce.swift +204 -0
  93. package/Sources/Combine/Publishers/Publishers.RemoveDuplicates.swift +264 -0
  94. package/Sources/Combine/Publishers/Publishers.ReplaceEmpty.swift +201 -0
  95. package/Sources/Combine/Publishers/Publishers.ReplaceError.swift +211 -0
  96. package/Sources/Combine/Publishers/Publishers.Retry.swift +274 -0
  97. package/Sources/Combine/Publishers/Publishers.Scan.swift +331 -0
  98. package/Sources/Combine/Publishers/Publishers.Sequence.swift +437 -0
  99. package/Sources/Combine/Publishers/Publishers.SetFailureType.swift +120 -0
  100. package/Sources/Combine/Publishers/Publishers.Share.swift +104 -0
  101. package/Sources/Combine/Publishers/Publishers.SubscribeOn.swift +197 -0
  102. package/Sources/Combine/Publishers/Publishers.SwitchToLatest.swift +444 -0
  103. package/Sources/Combine/Publishers/Publishers.Throttle.swift +359 -0
  104. package/Sources/Combine/Publishers/Publishers.Timeout.swift +301 -0
  105. package/Sources/Combine/Publishers/Publishers.Zip.swift +720 -0
  106. package/Sources/Combine/Publishers/Publishers.swift +13 -0
  107. package/Sources/Combine/Publishers/Record.swift +237 -0
  108. package/Sources/Combine/Publishers/Result.Publisher.swift +337 -0
  109. package/Sources/Combine/Result.swift +46 -0
  110. package/Sources/Combine/Scheduler.swift +89 -0
  111. package/Sources/Combine/Schedulers.swift +211 -0
  112. package/Sources/Combine/Subject+Void.swift +17 -0
  113. package/Sources/Combine/Subscriber+Void.swift +20 -0
  114. package/Sources/Combine/Subscribers/Subscribers.Assign.swift +175 -0
  115. package/Sources/Combine/Subscribers/Subscribers.Completion.swift +90 -0
  116. package/Sources/Combine/Subscribers/Subscribers.Demand.swift +476 -0
  117. package/Sources/Combine/Subscribers/Subscribers.Sink.swift +206 -0
  118. package/Sources/Combine/Subscribers/Subscribers.swift +9 -0
  119. package/Sources/Combine/Subscription.swift +22 -0
  120. package/Sources/Combine/Subscriptions.swift +42 -0
  121. package/Sources/Combine/SwiftUIObservation.swift +10 -0
  122. package/Sources/Combine/_Introspection.swift +107 -0
  123. package/Sources/CommonCrypto/CommonCrypto.swift +80 -0
  124. package/Sources/Compression/Compression.swift +365 -0
  125. package/Sources/Compression/Deflate.swift +407 -0
  126. package/Sources/Compression/Zlib.swift +179 -0
  127. package/Sources/CoreFoundationTypes/CoreFoundationTypes.swift +101 -0
  128. package/Sources/CoreGraphics/CoreGraphics.swift +411 -0
  129. package/Sources/CoreGraphics/ProjectionTransforms.swift +28 -0
  130. package/Sources/CoreHaptics/CoreHaptics.swift +399 -0
  131. package/Sources/CoreImage/CIColor.swift +41 -0
  132. package/Sources/CoreImage/CIContext.swift +31 -0
  133. package/Sources/CoreImage/CIDetector.swift +57 -0
  134. package/Sources/CoreImage/CIFilter.swift +243 -0
  135. package/Sources/CoreImage/CIFilterBuiltins.swift +136 -0
  136. package/Sources/CoreImage/CIImage.swift +162 -0
  137. package/Sources/CoreImage/QRCode.swift +393 -0
  138. package/Sources/CoreLocation/Coordinate.swift +30 -0
  139. package/Sources/CoreLocation/Location.swift +65 -0
  140. package/Sources/CoreML/Evaluation.swift +414 -0
  141. package/Sources/CoreML/FeatureValue.swift +266 -0
  142. package/Sources/CoreML/Model.swift +269 -0
  143. package/Sources/CoreML/MultiArray.swift +92 -0
  144. package/Sources/CoreML/Specification.swift +233 -0
  145. package/Sources/CoreText/CoreText.swift +64 -0
  146. package/Sources/CoreTransferable/CoreTransferable.swift +606 -0
  147. package/Sources/CryptoKit/ChaChaPoly.swift +258 -0
  148. package/Sources/CryptoKit/CryptoKit.swift +375 -0
  149. package/Sources/CryptoKit/Curve25519.swift +317 -0
  150. package/Sources/CryptoKit/P256.swift +321 -0
  151. package/Sources/FoundationBridge/AppStorage.swift +165 -0
  152. package/Sources/FoundationBridge/AssetResources.swift +90 -0
  153. package/Sources/FoundationBridge/AsyncBytes.swift +128 -0
  154. package/Sources/FoundationBridge/AsyncImage.swift +116 -0
  155. package/Sources/FoundationBridge/AttributedStrings.swift +16 -0
  156. package/Sources/{_FoundationCommon → FoundationBridge}/Bundle.swift +41 -4
  157. package/Sources/FoundationBridge/CombineExports.swift +8 -0
  158. package/Sources/FoundationBridge/CoreFoundation.swift +77 -0
  159. package/Sources/FoundationBridge/Dispatch.swift +458 -0
  160. package/Sources/FoundationBridge/EnvironmentFoundation.swift +41 -0
  161. package/Sources/FoundationBridge/FileImporter.swift +128 -0
  162. package/Sources/FoundationBridge/FileSystem.swift +68 -0
  163. package/Sources/FoundationBridge/FoundationBridge.swift +24 -72
  164. package/Sources/FoundationBridge/HostResolution.swift +31 -0
  165. package/Sources/FoundationBridge/ItemProvider.swift +655 -0
  166. package/Sources/FoundationBridge/KeyValueObserving.swift +138 -0
  167. package/Sources/FoundationBridge/Links.swift +127 -0
  168. package/Sources/FoundationBridge/ListFormatter.swift +32 -0
  169. package/Sources/FoundationBridge/Localization.swift +149 -0
  170. package/Sources/FoundationBridge/Locks.swift +50 -0
  171. package/Sources/FoundationBridge/Markdown.swift +527 -0
  172. package/Sources/FoundationBridge/MeasurementFormat.swift +95 -0
  173. package/Sources/FoundationBridge/NotificationCenter.swift +154 -0
  174. package/Sources/FoundationBridge/OpenURLHandlers.swift +60 -0
  175. package/Sources/FoundationBridge/Operation.swift +195 -0
  176. package/Sources/FoundationBridge/ProcessInfo.swift +32 -0
  177. package/Sources/FoundationBridge/RelativeDateTimeFormatter.swift +136 -0
  178. package/Sources/FoundationBridge/SceneStorage.swift +78 -0
  179. package/Sources/FoundationBridge/SecurityExports.swift +8 -0
  180. package/Sources/FoundationBridge/Selector.swift +226 -0
  181. package/Sources/FoundationBridge/StringComparators.swift +17 -0
  182. package/Sources/FoundationBridge/Table.swift +211 -0
  183. package/Sources/FoundationBridge/TextAttributes.swift +42 -0
  184. package/Sources/FoundationBridge/Timer.swift +6 -1
  185. package/Sources/FoundationBridge/URLSession.swift +718 -0
  186. package/Sources/{_FoundationCommon → FoundationBridge}/UserDefaults.swift +17 -4
  187. package/Sources/FoundationBridge/WebAuthRedirects.swift +227 -0
  188. package/Sources/FoundationBridge/WebSocket.swift +187 -0
  189. package/Sources/FoundationModels/FoundationModels.swift +1098 -0
  190. package/Sources/ImageIO/GIF.swift +72 -0
  191. package/Sources/ImageIO/ImageIO.swift +248 -0
  192. package/Sources/ImageIO/ImageTypes.swift +28 -0
  193. package/Sources/LinkPresentation/LinkPresentation.swift +249 -0
  194. package/Sources/LocalAuthentication/LAContext.swift +86 -0
  195. package/Sources/MapKit/Geometry.swift +223 -0
  196. package/Sources/MapKit/Map.swift +638 -0
  197. package/Sources/MapKit/MapView.swift +229 -0
  198. package/Sources/MobileCoreServices/MobileCoreServices.swift +28 -0
  199. package/Sources/NaturalLanguage/LanguageIdentifier.swift +317 -0
  200. package/Sources/NaturalLanguage/NaturalLanguage.swift +135 -0
  201. package/Sources/OSLog/OSLog.swift +6 -0
  202. package/Sources/Photos/Photos.swift +572 -0
  203. package/Sources/PhotosUI/PhotosPicker.swift +248 -0
  204. package/Sources/PhotosUI/PhotosPickerItem.swift +261 -0
  205. package/Sources/QuickLook/QuickLook.swift +168 -0
  206. package/Sources/SafariServices/SafariServices.swift +106 -0
  207. package/Sources/Security/Security.swift +332 -0
  208. package/Sources/StoreKit/AppStore.swift +207 -0
  209. package/Sources/StoreKit/Products.swift +280 -0
  210. package/Sources/StoreKit/RequestReview.swift +28 -0
  211. package/Sources/StoreKit/StoreKit1.swift +486 -0
  212. package/Sources/StoreKit/StoreViews.swift +428 -0
  213. package/Sources/StoreKit/Transactions.swift +197 -0
  214. package/Sources/SwiftData/Macros.swift +58 -0
  215. package/Sources/SwiftData/ModelActor.swift +38 -0
  216. package/Sources/SwiftData/ModelContainer.swift +129 -0
  217. package/Sources/SwiftData/ModelContext.swift +451 -0
  218. package/Sources/SwiftData/PersistentModel.swift +238 -0
  219. package/Sources/SwiftData/Properties.swift +261 -0
  220. package/Sources/SwiftData/Query.swift +256 -0
  221. package/Sources/SwiftData/Schema.swift +192 -0
  222. package/Sources/SwiftData/Store.swift +146 -0
  223. package/Sources/SwiftData/StringPredicates.swift +125 -0
  224. package/Sources/SwiftDataMacros/EntryMacro.swift +82 -0
  225. package/Sources/SwiftDataMacros/GenerableMacro.swift +183 -0
  226. package/Sources/SwiftDataMacros/ModelActorMacro.swift +46 -0
  227. package/Sources/SwiftDataMacros/ModelMacro.swift +260 -0
  228. package/Sources/SwiftDataMacros/Plugin.swift +18 -0
  229. package/Sources/SwiftDataMacros/PredicateMacro.swift +1244 -0
  230. package/Sources/SwiftUI/API/Accessibility.swift +55 -6
  231. package/Sources/SwiftUI/API/AccessibilityExtras.swift +33 -0
  232. package/Sources/SwiftUI/API/AccessibilityFocus.swift +63 -0
  233. package/Sources/SwiftUI/API/Alert.swift +1 -1
  234. package/Sources/SwiftUI/API/AlignmentGuides.swift +65 -0
  235. package/Sources/SwiftUI/API/Animation.swift +37 -5
  236. package/Sources/SwiftUI/API/App.swift +31 -1
  237. package/Sources/SwiftUI/API/BindingCollections.swift +35 -0
  238. package/Sources/SwiftUI/API/BindingForEach.swift +27 -0
  239. package/Sources/SwiftUI/API/Bitmaps.swift +254 -0
  240. package/Sources/SwiftUI/API/ButtonStyles.swift +96 -0
  241. package/Sources/SwiftUI/API/Canvas.swift +337 -0
  242. package/Sources/SwiftUI/API/Color.swift +104 -28
  243. package/Sources/SwiftUI/API/ColorEffects.swift +52 -0
  244. package/Sources/SwiftUI/API/ColorPickerAndLabeledContent.swift +138 -0
  245. package/Sources/SwiftUI/API/ColorSpaces.swift +161 -0
  246. package/Sources/SwiftUI/API/Commands.swift +106 -0
  247. package/Sources/SwiftUI/API/ContainerBackground.swift +28 -0
  248. package/Sources/SwiftUI/API/ContentShape.swift +33 -0
  249. package/Sources/SwiftUI/API/ContentSizeCategory.swift +35 -0
  250. package/Sources/SwiftUI/API/ContentUnavailable.swift +101 -0
  251. package/Sources/SwiftUI/API/Controls.swift +59 -27
  252. package/Sources/SwiftUI/API/CustomLayout.swift +49 -10
  253. package/Sources/SwiftUI/API/CustomToolbarContent.swift +46 -0
  254. package/Sources/SwiftUI/API/Decorations.swift +1 -1
  255. package/Sources/SwiftUI/API/EditMode.swift +25 -82
  256. package/Sources/SwiftUI/API/Effects.swift +105 -7
  257. package/Sources/SwiftUI/API/Entry.swift +8 -0
  258. package/Sources/SwiftUI/API/Environment.swift +93 -9
  259. package/Sources/SwiftUI/API/EnvironmentSendable.swift +6 -0
  260. package/Sources/SwiftUI/API/Focus.swift +11 -3
  261. package/Sources/SwiftUI/API/Gauge.swift +3 -2
  262. package/Sources/SwiftUI/API/GeometryEffects.swift +232 -0
  263. package/Sources/SwiftUI/API/GeometryReader.swift +13 -2
  264. package/Sources/SwiftUI/API/GestureState.swift +65 -0
  265. package/Sources/SwiftUI/API/Gestures.swift +1 -1
  266. package/Sources/SwiftUI/API/Glass.swift +127 -0
  267. package/Sources/SwiftUI/API/Grid.swift +1 -1
  268. package/Sources/SwiftUI/API/GroupBoxAndControlGroup.swift +130 -0
  269. package/Sources/SwiftUI/API/KeyPress.swift +54 -0
  270. package/Sources/SwiftUI/API/LabelStyle.swift +13 -6
  271. package/Sources/SwiftUI/API/Layout.swift +67 -12
  272. package/Sources/SwiftUI/API/LazyStacks.swift +49 -0
  273. package/Sources/SwiftUI/API/LegacyAlert.swift +97 -0
  274. package/Sources/SwiftUI/API/Lists.swift +61 -6
  275. package/Sources/SwiftUI/API/Menu.swift +8 -1
  276. package/Sources/SwiftUI/API/Modifiers.swift +80 -10
  277. package/Sources/SwiftUI/API/MoreModifiers.swift +100 -0
  278. package/Sources/SwiftUI/API/Namespace.swift +44 -0
  279. package/Sources/SwiftUI/API/Navigation.swift +24 -9
  280. package/Sources/SwiftUI/API/NavigationDestinationBindings.swift +55 -0
  281. package/Sources/SwiftUI/API/ObservableObject.swift +16 -2
  282. package/Sources/SwiftUI/API/Path.swift +543 -0
  283. package/Sources/SwiftUI/API/Phase8Controls.swift +48 -31
  284. package/Sources/SwiftUI/API/PhaseAnimator.swift +130 -0
  285. package/Sources/SwiftUI/API/Picker.swift +11 -2
  286. package/Sources/SwiftUI/API/PointerAndKeyboard.swift +77 -0
  287. package/Sources/SwiftUI/API/Popover.swift +41 -0
  288. package/Sources/SwiftUI/API/Preferences.swift +262 -0
  289. package/Sources/SwiftUI/API/Presentation.swift +17 -4
  290. package/Sources/SwiftUI/API/PresentationExtras.swift +60 -0
  291. package/Sources/SwiftUI/API/Primitives.swift +164 -37
  292. package/Sources/SwiftUI/API/Publishers.swift +4 -4
  293. package/Sources/SwiftUI/API/Redaction.swift +75 -0
  294. package/Sources/SwiftUI/API/RowActions.swift +3 -2
  295. package/Sources/SwiftUI/API/Scenes.swift +131 -0
  296. package/Sources/SwiftUI/API/ScrollModifiers.swift +132 -0
  297. package/Sources/SwiftUI/API/ScrollTargets.swift +3 -3
  298. package/Sources/SwiftUI/API/ScrollViewReader.swift +144 -0
  299. package/Sources/SwiftUI/API/SectionSupplements.swift +96 -0
  300. package/Sources/SwiftUI/API/Shape.swift +214 -0
  301. package/Sources/SwiftUI/API/ShapeStyle.swift +105 -7
  302. package/Sources/SwiftUI/API/ShapeTrim.swift +78 -0
  303. package/Sources/SwiftUI/API/Sharing.swift +193 -0
  304. package/Sources/SwiftUI/API/StackLayouts.swift +199 -0
  305. package/Sources/SwiftUI/API/State.swift +18 -1
  306. package/Sources/SwiftUI/API/StatusGaps.swift +121 -0
  307. package/Sources/SwiftUI/API/SymbolEffects.swift +203 -0
  308. package/Sources/SwiftUI/API/TabContent.swift +841 -0
  309. package/Sources/SwiftUI/API/Table.swift +382 -0
  310. package/Sources/SwiftUI/API/Tabs.swift +148 -4
  311. package/Sources/SwiftUI/API/Tasks.swift +2 -2
  312. package/Sources/SwiftUI/API/Text.swift +386 -0
  313. package/Sources/SwiftUI/API/TextDates.swift +61 -0
  314. package/Sources/SwiftUI/API/TextDecorations.swift +52 -0
  315. package/Sources/SwiftUI/API/TextFieldAxis.swift +103 -0
  316. package/Sources/SwiftUI/API/TextFieldCommit.swift +52 -0
  317. package/Sources/SwiftUI/API/Toolbar.swift +52 -16
  318. package/Sources/SwiftUI/API/Transfer.swift +145 -0
  319. package/Sources/SwiftUI/API/UnevenRoundedRectangle.swift +66 -0
  320. package/Sources/SwiftUI/API/Video.swift +64 -0
  321. package/Sources/SwiftUI/API/View.swift +10 -2
  322. package/Sources/SwiftUI/API/ViewModifier.swift +4 -1
  323. package/Sources/SwiftUI/API/VisualEffect.swift +74 -1
  324. package/Sources/SwiftUI/API/Windows.swift +25 -0
  325. package/Sources/SwiftUI/Charts/Axis.swift +7 -1
  326. package/Sources/SwiftUI/Charts/AxisFormatsAndRanges.swift +68 -0
  327. package/Sources/SwiftUI/Charts/Chart.swift +17 -3
  328. package/Sources/SwiftUI/Charts/ChartProxy.swift +57 -0
  329. package/Sources/SwiftUI/Localization/Localization.swift +498 -0
  330. package/Sources/SwiftUI/Localization/PluralRules.swift +127 -0
  331. package/Sources/SwiftUI/Runtime/Executor.swift +2 -0
  332. package/Sources/SwiftUI/Runtime/Exports.swift +37 -1
  333. package/Sources/SwiftUI/Runtime/ImageSource.swift +310 -0
  334. package/Sources/SwiftUI/Runtime/JSON.swift +76 -4
  335. package/Sources/SwiftUI/Runtime/LazyRows.swift +99 -0
  336. package/Sources/SwiftUI/Runtime/Measurements.swift +140 -0
  337. package/Sources/SwiftUI/Runtime/Ops.swift +58 -12
  338. package/Sources/SwiftUI/Runtime/Reconciler.swift +10 -1
  339. package/Sources/SwiftUI/Runtime/Replay.swift +382 -0
  340. package/Sources/SwiftUI/Runtime/Runtime.swift +977 -198
  341. package/Sources/SwiftUI/Runtime/Sameness.swift +152 -0
  342. package/Sources/SwiftUI/Runtime/ViewPath.swift +89 -0
  343. package/Sources/SwiftUI/Runtime/ViewTraits.swift +175 -0
  344. package/Sources/SwiftUI/Runtime/WebAuthHeadless.swift +49 -0
  345. package/Sources/Symbols/Symbols.swift +25 -0
  346. package/Sources/Translation/Translation.swift +423 -0
  347. package/Sources/UIKit/Activity.swift +213 -0
  348. package/Sources/UIKit/Alerts.swift +69 -0
  349. package/Sources/UIKit/AppDelegate.swift +222 -0
  350. package/Sources/UIKit/Appearance.swift +84 -0
  351. package/Sources/UIKit/ColorConversions.swift +70 -0
  352. package/Sources/UIKit/Controls.swift +225 -0
  353. package/Sources/UIKit/Device.swift +200 -0
  354. package/Sources/UIKit/Feedback.swift +65 -0
  355. package/Sources/UIKit/Font.swift +307 -0
  356. package/Sources/UIKit/Graphics.swift +204 -0
  357. package/Sources/UIKit/HostingController.swift +185 -0
  358. package/Sources/UIKit/Identity.swift +24 -0
  359. package/Sources/UIKit/Introspectable.swift +510 -0
  360. package/Sources/UIKit/Pasteboard.swift +363 -0
  361. package/Sources/UIKit/PhotoAlbum.swift +81 -0
  362. package/Sources/UIKit/RemoteNotifications.swift +15 -0
  363. package/Sources/UIKit/Representable.swift +288 -0
  364. package/Sources/UIKit/SafeArea.swift +12 -0
  365. package/Sources/UIKit/SceneDelegates.swift +132 -0
  366. package/Sources/UIKit/Scenes.swift +40 -0
  367. package/Sources/UIKit/ScrollView.swift +157 -0
  368. package/Sources/UIKit/ShortcutItems.swift +67 -0
  369. package/Sources/UIKit/SymbolConfiguration.swift +124 -0
  370. package/Sources/UIKit/TargetAction.swift +123 -0
  371. package/Sources/UIKit/TextPaste.swift +161 -0
  372. package/Sources/UIKit/TextView.swift +538 -0
  373. package/Sources/UIKit/UIKit.swift +292 -0
  374. package/Sources/UIKit/UIView.swift +855 -0
  375. package/Sources/UIKit/ViewTranslation.swift +311 -0
  376. package/Sources/UniformTypeIdentifiers/UTType.swift +196 -0
  377. package/Sources/UserNotifications/Content.swift +370 -0
  378. package/Sources/UserNotifications/NotificationCenter.swift +309 -0
  379. package/Sources/WeatherKit/WeatherKit.swift +228 -0
  380. package/Sources/WebKit/WebKit.swift +245 -0
  381. package/Sources/os/os.swift +376 -0
  382. package/Sources/zlib/zlib.swift +6 -0
  383. package/index.d.ts +1 -1
  384. package/index.mjs +2 -2
  385. package/manifest.d.mts +2 -0
  386. package/manifest.mjs +39 -0
  387. package/package.json +5 -3
  388. package/sync-sources.mjs +21 -7
  389. package/Sources/FoundationLite/Common.swift +0 -3
  390. package/Sources/FoundationLite/FoundationLite.swift +0 -171
  391. package/Sources/FoundationLite/Interaction.swift +0 -146
  392. package/Sources/FoundationLite/Timer.swift +0 -48
  393. package/Sources/_FoundationCommon/_FoundationCommon.swift +0 -10
@@ -0,0 +1,543 @@
1
+ // `Path` and `CGAffineTransform`: the outline a custom `Shape` draws in
2
+ // `path(in:)` (Shape.swift), kept as SwiftUI's elements (moves, lines,
3
+ // quadratic and cubic curves, closes). Arcs, ellipses and rounded rectangles
4
+ // are added as cubic curves, as Core Graphics adds them. The page draws a
5
+ // path as SVG path data (`_svg`).
6
+ //
7
+ // `CGAffineTransform` lives here, not in the CoreGraphics module, so that a
8
+ // path can be transformed (`applying(_:)`, the `transform:` arguments);
9
+ // CoreGraphics re-exports it, as it does the geometry types.
10
+
11
+ #if canImport(WASILibc)
12
+ import WASILibc
13
+ #elseif canImport(Glibc)
14
+ import Glibc
15
+ #elseif canImport(Musl)
16
+ import Musl
17
+ #elseif canImport(Darwin)
18
+ import Darwin
19
+ #endif
20
+
21
+ // MARK: - Transforms
22
+
23
+ public struct CGAffineTransform: Equatable, Hashable, Sendable {
24
+ public var a, b, c, d, tx, ty: CGFloat
25
+
26
+ public init(a: CGFloat, b: CGFloat, c: CGFloat, d: CGFloat, tx: CGFloat, ty: CGFloat) {
27
+ (self.a, self.b, self.c, self.d, self.tx, self.ty) = (a, b, c, d, tx, ty)
28
+ }
29
+
30
+ public init(_ a: CGFloat, _ b: CGFloat, _ c: CGFloat, _ d: CGFloat, _ tx: CGFloat, _ ty: CGFloat) {
31
+ self.init(a: a, b: b, c: c, d: d, tx: tx, ty: ty)
32
+ }
33
+
34
+ public init() { self.init(a: 1, b: 0, c: 0, d: 1, tx: 0, ty: 0) }
35
+ public init(translationX tx: CGFloat, y ty: CGFloat) { self.init(a: 1, b: 0, c: 0, d: 1, tx: tx, ty: ty) }
36
+ public init(scaleX sx: CGFloat, y sy: CGFloat) { self.init(a: sx, b: 0, c: 0, d: sy, tx: 0, ty: 0) }
37
+ public init(rotationAngle angle: CGFloat) {
38
+ let (s, c) = (sin(angle), cos(angle))
39
+ self.init(a: c, b: s, c: -s, d: c, tx: 0, ty: 0)
40
+ }
41
+
42
+ public static let identity = CGAffineTransform()
43
+ public var isIdentity: Bool { self == .identity }
44
+
45
+ public func concatenating(_ t: CGAffineTransform) -> CGAffineTransform {
46
+ CGAffineTransform(a: a * t.a + b * t.c, b: a * t.b + b * t.d,
47
+ c: c * t.a + d * t.c, d: c * t.b + d * t.d,
48
+ tx: tx * t.a + ty * t.c + t.tx, ty: tx * t.b + ty * t.d + t.ty)
49
+ }
50
+
51
+ public func translatedBy(x: CGFloat, y: CGFloat) -> CGAffineTransform { CGAffineTransform(translationX: x, y: y).concatenating(self) }
52
+ public func scaledBy(x: CGFloat, y: CGFloat) -> CGAffineTransform { CGAffineTransform(scaleX: x, y: y).concatenating(self) }
53
+ public func rotated(by angle: CGFloat) -> CGAffineTransform { CGAffineTransform(rotationAngle: angle).concatenating(self) }
54
+
55
+ public func inverted() -> CGAffineTransform {
56
+ let det = a * d - b * c
57
+ guard det != 0 else { return self }
58
+ return CGAffineTransform(a: d / det, b: -b / det, c: -c / det, d: a / det,
59
+ tx: (c * ty - d * tx) / det, ty: (b * tx - a * ty) / det)
60
+ }
61
+ }
62
+
63
+ extension CGPoint {
64
+ public func applying(_ t: CGAffineTransform) -> CGPoint {
65
+ CGPoint(x: t.a * x + t.c * y + t.tx, y: t.b * x + t.d * y + t.ty)
66
+ }
67
+ }
68
+
69
+ extension CGSize {
70
+ public func applying(_ t: CGAffineTransform) -> CGSize {
71
+ CGSize(width: t.a * width + t.c * height, height: t.b * width + t.d * height)
72
+ }
73
+ }
74
+
75
+ extension CGRect {
76
+ /// The bounding box of the transformed corners.
77
+ public func applying(_ t: CGAffineTransform) -> CGRect {
78
+ let corners = [CGPoint(x: minX, y: minY), CGPoint(x: maxX, y: minY), CGPoint(x: minX, y: maxY), CGPoint(x: maxX, y: maxY)].map { $0.applying(t) }
79
+ let xs = corners.map(\.x), ys = corners.map(\.y)
80
+ return CGRect(x: xs.min()!, y: ys.min()!, width: xs.max()! - xs.min()!, height: ys.max()! - ys.min()!)
81
+ }
82
+ }
83
+
84
+ // MARK: - Path
85
+
86
+ /// An outline: subpaths of lines and curves.
87
+ public struct Path: Equatable, Sendable {
88
+ /// One step of a path.
89
+ public enum Element: Equatable, Sendable {
90
+ case move(to: CGPoint)
91
+ case line(to: CGPoint)
92
+ case quadCurve(to: CGPoint, control: CGPoint)
93
+ case curve(to: CGPoint, control1: CGPoint, control2: CGPoint)
94
+ case closeSubpath
95
+ }
96
+
97
+ private(set) var elements: [Element] = []
98
+ /// Where the current subpath started (a close returns there).
99
+ private var subpathStart: CGPoint?
100
+
101
+ public init() {}
102
+
103
+ public init(_ rect: CGRect) {
104
+ addRect(rect)
105
+ }
106
+
107
+ public init(roundedRect rect: CGRect, cornerRadius: CGFloat, style: RoundedCornerStyle = .continuous) {
108
+ addRoundedRect(in: rect, cornerSize: CGSize(width: cornerRadius, height: cornerRadius), style: style)
109
+ }
110
+
111
+ public init(roundedRect rect: CGRect, cornerSize: CGSize, style: RoundedCornerStyle = .continuous) {
112
+ addRoundedRect(in: rect, cornerSize: cornerSize, style: style)
113
+ }
114
+
115
+ public init(roundedRect rect: CGRect, cornerRadii: RectangleCornerRadii, style: RoundedCornerStyle = .continuous) {
116
+ addRoundedRect(in: rect, cornerRadii: cornerRadii, style: style)
117
+ }
118
+
119
+ public init(ellipseIn rect: CGRect) {
120
+ addEllipse(in: rect)
121
+ }
122
+
123
+ public init(_ callback: (inout Path) -> Void) {
124
+ var path = Path()
125
+ callback(&path)
126
+ self = path
127
+ }
128
+
129
+ public var isEmpty: Bool { elements.isEmpty }
130
+
131
+ /// The last point of the path; nil for an empty one.
132
+ public var currentPoint: CGPoint? {
133
+ switch elements.last {
134
+ case .move(let p)?, .line(let p)?, .quadCurve(let p, _)?, .curve(let p, _, _)?: p
135
+ case .closeSubpath?: subpathStart
136
+ case nil: nil
137
+ }
138
+ }
139
+
140
+ // MARK: Building
141
+
142
+ public mutating func move(to point: CGPoint) {
143
+ elements.append(.move(to: point))
144
+ subpathStart = point
145
+ }
146
+
147
+ public mutating func addLine(to point: CGPoint) {
148
+ guard currentPoint != nil else { move(to: point); return }
149
+ elements.append(.line(to: point))
150
+ }
151
+
152
+ public mutating func addLines(_ points: [CGPoint]) {
153
+ guard let first = points.first else { return }
154
+ move(to: first)
155
+ for point in points.dropFirst() { addLine(to: point) }
156
+ }
157
+
158
+ public mutating func addQuadCurve(to point: CGPoint, control: CGPoint) {
159
+ guard currentPoint != nil else { move(to: point); return }
160
+ elements.append(.quadCurve(to: point, control: control))
161
+ }
162
+
163
+ public mutating func addCurve(to point: CGPoint, control1: CGPoint, control2: CGPoint) {
164
+ guard currentPoint != nil else { move(to: point); return }
165
+ elements.append(.curve(to: point, control1: control1, control2: control2))
166
+ }
167
+
168
+ public mutating func closeSubpath() {
169
+ guard let last = elements.last, last != .closeSubpath else { return }
170
+ elements.append(.closeSubpath)
171
+ }
172
+
173
+ public mutating func addRect(_ rect: CGRect, transform: CGAffineTransform = .identity) {
174
+ let r = rect.standardized
175
+ var path = Path()
176
+ path.move(to: CGPoint(x: r.minX, y: r.minY))
177
+ path.addLine(to: CGPoint(x: r.maxX, y: r.minY))
178
+ path.addLine(to: CGPoint(x: r.maxX, y: r.maxY))
179
+ path.addLine(to: CGPoint(x: r.minX, y: r.maxY))
180
+ path.closeSubpath()
181
+ addPath(path, transform: transform)
182
+ }
183
+
184
+ public mutating func addRects(_ rects: [CGRect], transform: CGAffineTransform = .identity) {
185
+ for rect in rects { addRect(rect, transform: transform) }
186
+ }
187
+
188
+ public mutating func addRoundedRect(in rect: CGRect, cornerSize: CGSize, style: RoundedCornerStyle = .continuous,
189
+ transform: CGAffineTransform = .identity) {
190
+ let r = rect.standardized
191
+ let rx = max(0, min(cornerSize.width, r.width / 2))
192
+ let ry = max(0, min(cornerSize.height, r.height / 2))
193
+ addRoundedRect(r, radii: [(rx, ry), (rx, ry), (rx, ry), (rx, ry)], transform: transform)
194
+ }
195
+
196
+ public mutating func addRoundedRect(in rect: CGRect, cornerRadii: RectangleCornerRadii, style: RoundedCornerStyle = .continuous,
197
+ transform: CGAffineTransform = .identity) {
198
+ let r = rect.standardized
199
+ let limit = min(r.width, r.height) / 2
200
+ func clamp(_ v: CGFloat) -> (CGFloat, CGFloat) { let v = max(0, min(v, limit)); return (v, v) }
201
+ // Clockwise from the top leading corner.
202
+ addRoundedRect(r, radii: [clamp(cornerRadii.topLeading), clamp(cornerRadii.topTrailing),
203
+ clamp(cornerRadii.bottomTrailing), clamp(cornerRadii.bottomLeading)], transform: transform)
204
+ }
205
+
206
+ /// A rectangle with elliptical corners (top leading, top trailing, bottom
207
+ /// trailing, bottom leading), clockwise from the end of the top leading one.
208
+ private mutating func addRoundedRect(_ r: CGRect, radii: [(CGFloat, CGFloat)], transform: CGAffineTransform) {
209
+ let k = Path.kappa
210
+ let (tl, tr, br, bl) = (radii[0], radii[1], radii[2], radii[3])
211
+ var path = Path()
212
+ path.move(to: CGPoint(x: r.minX + tl.0, y: r.minY))
213
+ path.addLine(to: CGPoint(x: r.maxX - tr.0, y: r.minY))
214
+ if tr.0 > 0 || tr.1 > 0 {
215
+ path.addCurve(to: CGPoint(x: r.maxX, y: r.minY + tr.1),
216
+ control1: CGPoint(x: r.maxX - tr.0 + tr.0 * k, y: r.minY),
217
+ control2: CGPoint(x: r.maxX, y: r.minY + tr.1 - tr.1 * k))
218
+ }
219
+ path.addLine(to: CGPoint(x: r.maxX, y: r.maxY - br.1))
220
+ if br.0 > 0 || br.1 > 0 {
221
+ path.addCurve(to: CGPoint(x: r.maxX - br.0, y: r.maxY),
222
+ control1: CGPoint(x: r.maxX, y: r.maxY - br.1 + br.1 * k),
223
+ control2: CGPoint(x: r.maxX - br.0 + br.0 * k, y: r.maxY))
224
+ }
225
+ path.addLine(to: CGPoint(x: r.minX + bl.0, y: r.maxY))
226
+ if bl.0 > 0 || bl.1 > 0 {
227
+ path.addCurve(to: CGPoint(x: r.minX, y: r.maxY - bl.1),
228
+ control1: CGPoint(x: r.minX + bl.0 - bl.0 * k, y: r.maxY),
229
+ control2: CGPoint(x: r.minX, y: r.maxY - bl.1 + bl.1 * k))
230
+ }
231
+ path.addLine(to: CGPoint(x: r.minX, y: r.minY + tl.1))
232
+ if tl.0 > 0 || tl.1 > 0 {
233
+ path.addCurve(to: CGPoint(x: r.minX + tl.0, y: r.minY),
234
+ control1: CGPoint(x: r.minX, y: r.minY + tl.1 - tl.1 * k),
235
+ control2: CGPoint(x: r.minX + tl.0 - tl.0 * k, y: r.minY))
236
+ }
237
+ path.closeSubpath()
238
+ addPath(path, transform: transform)
239
+ }
240
+
241
+ /// An ellipse, clockwise on screen from its trailing point (3 o'clock).
242
+ public mutating func addEllipse(in rect: CGRect, transform: CGAffineTransform = .identity) {
243
+ let r = rect.standardized
244
+ let (rx, ry) = (r.width / 2, r.height / 2)
245
+ let (cx, cy) = (r.midX, r.midY)
246
+ let (ox, oy) = (rx * Path.kappa, ry * Path.kappa)
247
+ var path = Path()
248
+ path.move(to: CGPoint(x: r.maxX, y: cy))
249
+ path.addCurve(to: CGPoint(x: cx, y: r.maxY), control1: CGPoint(x: r.maxX, y: cy + oy), control2: CGPoint(x: cx + ox, y: r.maxY))
250
+ path.addCurve(to: CGPoint(x: r.minX, y: cy), control1: CGPoint(x: cx - ox, y: r.maxY), control2: CGPoint(x: r.minX, y: cy + oy))
251
+ path.addCurve(to: CGPoint(x: cx, y: r.minY), control1: CGPoint(x: r.minX, y: cy - oy), control2: CGPoint(x: cx - ox, y: r.minY))
252
+ path.addCurve(to: CGPoint(x: r.maxX, y: cy), control1: CGPoint(x: cx + ox, y: r.minY), control2: CGPoint(x: r.maxX, y: cy - oy))
253
+ path.closeSubpath()
254
+ addPath(path, transform: transform)
255
+ }
256
+
257
+ /// An arc of the circle around `center`, from `startAngle` to
258
+ /// `endAngle`. Angles turn from the x axis towards the y axis, which is
259
+ /// down on screen; `clockwise` is as Core Graphics means it in a y-up
260
+ /// space, so on screen `clockwise: false` turns clockwise (SwiftUI's
261
+ /// well-known inversion). A line joins the current point to the start.
262
+ public mutating func addArc(center: CGPoint, radius: CGFloat, startAngle: Angle, endAngle: Angle, clockwise: Bool,
263
+ transform: CGAffineTransform = .identity) {
264
+ let full = 2 * CGFloat.pi
265
+ var delta = endAngle.radians - startAngle.radians
266
+ if clockwise {
267
+ if delta <= -full { delta = -full } else if delta > 0 {
268
+ delta = delta.truncatingRemainder(dividingBy: full)
269
+ if delta > 0 { delta -= full }
270
+ }
271
+ } else {
272
+ if delta >= full { delta = full } else if delta < 0 {
273
+ delta = delta.truncatingRemainder(dividingBy: full)
274
+ if delta < 0 { delta += full }
275
+ }
276
+ }
277
+ addRelativeArc(center: center, radius: radius, startAngle: startAngle, delta: Angle(radians: delta), transform: transform)
278
+ }
279
+
280
+ /// An arc of `delta` from `startAngle` (positive: clockwise on screen).
281
+ public mutating func addRelativeArc(center: CGPoint, radius: CGFloat, startAngle: Angle, delta: Angle,
282
+ transform: CGAffineTransform = .identity) {
283
+ let start = startAngle.radians
284
+ let sweep = delta.radians
285
+ func point(_ angle: CGFloat) -> CGPoint {
286
+ CGPoint(x: center.x + radius * cos(angle), y: center.y + radius * sin(angle)).applying(transform)
287
+ }
288
+ let first = point(start)
289
+ if currentPoint == nil { move(to: first) } else { addLine(to: first) }
290
+ guard sweep != 0, radius > 0 else { return }
291
+ let segments = max(1, Int((abs(sweep) / (CGFloat.pi / 2)).rounded(.up)))
292
+ let step = sweep / CGFloat(segments)
293
+ let k = 4 / 3 * tan(step / 4)
294
+ var angle = start
295
+ for _ in 0..<segments {
296
+ let next = angle + step
297
+ let (c0, s0, c1, s1) = (cos(angle), sin(angle), cos(next), sin(next))
298
+ let control1 = CGPoint(x: center.x + radius * (c0 - k * s0), y: center.y + radius * (s0 + k * c0))
299
+ let control2 = CGPoint(x: center.x + radius * (c1 + k * s1), y: center.y + radius * (s1 - k * c1))
300
+ elements.append(.curve(to: point(next), control1: control1.applying(transform), control2: control2.applying(transform)))
301
+ angle = next
302
+ }
303
+ }
304
+
305
+ /// The arc of `radius` tangent to the lines from the current point to
306
+ /// `tangent1End` and from there to `tangent2End`.
307
+ public mutating func addArc(tangent1End: CGPoint, tangent2End: CGPoint, radius: CGFloat,
308
+ transform: CGAffineTransform = .identity) {
309
+ guard let current = currentPoint?.applying(transform.inverted()) else {
310
+ move(to: tangent1End.applying(transform))
311
+ return
312
+ }
313
+ let (p0, p1, p2) = (current, tangent1End, tangent2End)
314
+ let v1 = CGPoint(x: p0.x - p1.x, y: p0.y - p1.y), v2 = CGPoint(x: p2.x - p1.x, y: p2.y - p1.y)
315
+ let l1 = (v1.x * v1.x + v1.y * v1.y).squareRoot(), l2 = (v2.x * v2.x + v2.y * v2.y).squareRoot()
316
+ let cross = v1.x * v2.y - v1.y * v2.x
317
+ guard l1 > 0, l2 > 0, abs(cross) > 1e-9, radius > 0 else {
318
+ addLine(to: p1.applying(transform))
319
+ return
320
+ }
321
+ let angle = acos(max(-1, min(1, (v1.x * v2.x + v1.y * v2.y) / (l1 * l2))))
322
+ let distance = radius / tan(angle / 2)
323
+ let t1 = CGPoint(x: p1.x + v1.x / l1 * distance, y: p1.y + v1.y / l1 * distance)
324
+ let t2 = CGPoint(x: p1.x + v2.x / l2 * distance, y: p1.y + v2.y / l2 * distance)
325
+ // The center lies along the bisector, `radius` from both tangent points.
326
+ let bisector = CGPoint(x: v1.x / l1 + v2.x / l2, y: v1.y / l1 + v2.y / l2)
327
+ let bl = (bisector.x * bisector.x + bisector.y * bisector.y).squareRoot()
328
+ let centerDistance = (distance * distance + radius * radius).squareRoot()
329
+ let center = CGPoint(x: p1.x + bisector.x / bl * centerDistance, y: p1.y + bisector.y / bl * centerDistance)
330
+ let a1 = atan2(t1.y - center.y, t1.x - center.x)
331
+ let a2 = atan2(t2.y - center.y, t2.x - center.x)
332
+ var sweep = a2 - a1
333
+ while sweep > CGFloat.pi { sweep -= 2 * CGFloat.pi }
334
+ while sweep < -CGFloat.pi { sweep += 2 * CGFloat.pi }
335
+ addLine(to: t1.applying(transform))
336
+ addRelativeArc(center: center, radius: radius, startAngle: Angle(radians: a1), delta: Angle(radians: sweep), transform: transform)
337
+ }
338
+
339
+ public mutating func addPath(_ path: Path, transform: CGAffineTransform = .identity) {
340
+ for element in path.applying(transform).elements {
341
+ switch element {
342
+ case .move(let p): move(to: p)
343
+ case .line(let p): elements.append(.line(to: p))
344
+ case .quadCurve(let p, let c): elements.append(.quadCurve(to: p, control: c))
345
+ case .curve(let p, let c1, let c2): elements.append(.curve(to: p, control1: c1, control2: c2))
346
+ case .closeSubpath: closeSubpath()
347
+ }
348
+ }
349
+ }
350
+
351
+ // MARK: Reading
352
+
353
+ public func forEach(_ body: (Element) -> Void) {
354
+ elements.forEach(body)
355
+ }
356
+
357
+ public func applying(_ transform: CGAffineTransform) -> Path {
358
+ guard !transform.isIdentity else { return self }
359
+ var path = Path()
360
+ path.elements = elements.map { element in
361
+ switch element {
362
+ case .move(let p): .move(to: p.applying(transform))
363
+ case .line(let p): .line(to: p.applying(transform))
364
+ case .quadCurve(let p, let c): .quadCurve(to: p.applying(transform), control: c.applying(transform))
365
+ case .curve(let p, let c1, let c2): .curve(to: p.applying(transform), control1: c1.applying(transform), control2: c2.applying(transform))
366
+ case .closeSubpath: .closeSubpath
367
+ }
368
+ }
369
+ path.subpathStart = subpathStart?.applying(transform)
370
+ return path
371
+ }
372
+
373
+ public func offsetBy(dx: CGFloat, dy: CGFloat) -> Path {
374
+ applying(CGAffineTransform(translationX: dx, y: dy))
375
+ }
376
+
377
+ /// The smallest rectangle around the path's outline (curves included,
378
+ /// their control points not).
379
+ public var boundingRect: CGRect {
380
+ let points = polylines().flatMap(\.points)
381
+ guard let first = points.first else { return .zero }
382
+ var (minX, minY, maxX, maxY) = (first.x, first.y, first.x, first.y)
383
+ for p in points {
384
+ minX = min(minX, p.x); minY = min(minY, p.y)
385
+ maxX = max(maxX, p.x); maxY = max(maxY, p.y)
386
+ }
387
+ return CGRect(x: minX, y: minY, width: maxX - minX, height: maxY - minY)
388
+ }
389
+
390
+ /// Whether `point` is inside the path filled with the non-zero winding
391
+ /// rule, or the even-odd rule with `eoFill`.
392
+ public func contains(_ point: CGPoint, eoFill: Bool = false) -> Bool {
393
+ var winding = 0
394
+ for line in polylines() {
395
+ var points = line.points
396
+ if let first = points.first, points.last != first { points.append(first) }
397
+ for (a, b) in zip(points, points.dropFirst()) where (a.y <= point.y) != (b.y <= point.y) {
398
+ let x = a.x + (point.y - a.y) / (b.y - a.y) * (b.x - a.x)
399
+ if x > point.x { winding += b.y > a.y ? 1 : -1 }
400
+ }
401
+ }
402
+ return eoFill ? winding % 2 != 0 : winding != 0
403
+ }
404
+
405
+ /// The part of the outline between two fractions of its length (curves
406
+ /// are kept as the short lines they flatten to).
407
+ public func trimmedPath(from: CGFloat, to: CGFloat) -> Path {
408
+ let from = max(0, min(1, from)), to = max(0, min(1, to))
409
+ guard to > from else { return Path() }
410
+ if from == 0 && to == 1 { return self }
411
+ let lines = polylines().map { line -> [CGPoint] in
412
+ line.closed && line.points.first != line.points.last ? line.points + [line.points[0]] : line.points
413
+ }
414
+ var total: CGFloat = 0
415
+ for points in lines { for (a, b) in zip(points, points.dropFirst()) { total += a.distance(to: b) } }
416
+ guard total > 0 else { return Path() }
417
+ let (start, end) = (from * total, to * total)
418
+ var result = Path()
419
+ var travelled: CGFloat = 0
420
+ for points in lines {
421
+ var drawing = false
422
+ for (a, b) in zip(points, points.dropFirst()) {
423
+ let length = a.distance(to: b)
424
+ let (s, e) = (travelled, travelled + length)
425
+ travelled = e
426
+ guard e > start, s < end, length > 0 else { continue }
427
+ let p = a.interpolated(to: b, amount: max(0, (start - s) / length))
428
+ let q = b == a ? b : a.interpolated(to: b, amount: min(1, (end - s) / length))
429
+ if !drawing { result.move(to: p); drawing = true }
430
+ result.addLine(to: q)
431
+ }
432
+ }
433
+ return result
434
+ }
435
+
436
+ /// The subpaths flattened to points (curves in short lines).
437
+ private func polylines() -> [(points: [CGPoint], closed: Bool)] {
438
+ var lines: [(points: [CGPoint], closed: Bool)] = []
439
+ var points: [CGPoint] = []
440
+ func finish(closed: Bool) {
441
+ if !points.isEmpty { lines.append((points, closed)) }
442
+ points = []
443
+ }
444
+ for element in elements {
445
+ switch element {
446
+ case .move(let p):
447
+ finish(closed: false)
448
+ points = [p]
449
+ case .line(let p):
450
+ points.append(p)
451
+ case .quadCurve(let p, let c):
452
+ let p0 = points.last ?? p
453
+ for i in 1...16 {
454
+ let t = CGFloat(i) / 16, u = 1 - t
455
+ points.append(CGPoint(x: u * u * p0.x + 2 * u * t * c.x + t * t * p.x,
456
+ y: u * u * p0.y + 2 * u * t * c.y + t * t * p.y))
457
+ }
458
+ case .curve(let p, let c1, let c2):
459
+ let p0 = points.last ?? p
460
+ for i in 1...16 {
461
+ let t = CGFloat(i) / 16, u = 1 - t
462
+ let (a, b, c, d) = (u * u * u, 3 * u * u * t, 3 * u * t * t, t * t * t)
463
+ points.append(CGPoint(x: a * p0.x + b * c1.x + c * c2.x + d * p.x,
464
+ y: a * p0.y + b * c1.y + c * c2.y + d * p.y))
465
+ }
466
+ case .closeSubpath:
467
+ let start = points.first
468
+ finish(closed: true)
469
+ if let start { points = [start] }
470
+ }
471
+ }
472
+ finish(closed: false)
473
+ return lines.filter { $0.points.count > 1 || $0.closed }
474
+ }
475
+
476
+ /// The control point distance of a quarter circle drawn as a cubic curve.
477
+ static let kappa: CGFloat = 0.5522847498307936
478
+
479
+ /// The path as SVG path data, in points rounded to hundredths.
480
+ var _svg: String {
481
+ var out = ""
482
+ func add(_ command: Character, _ points: CGPoint...) {
483
+ out.append(command)
484
+ var first = true
485
+ for p in points {
486
+ if !first { out.append(" ") }
487
+ out += Path.number(p.x) + " " + Path.number(p.y)
488
+ first = false
489
+ }
490
+ }
491
+ for element in elements {
492
+ switch element {
493
+ case .move(let p): add("M", p)
494
+ case .line(let p): add("L", p)
495
+ case .quadCurve(let p, let c): add("Q", c, p)
496
+ case .curve(let p, let c1, let c2): add("C", c1, c2, p)
497
+ case .closeSubpath: out.append("Z")
498
+ }
499
+ }
500
+ return out
501
+ }
502
+
503
+ static func number(_ value: CGFloat) -> String {
504
+ guard value.isFinite else { return "0" }
505
+ let rounded = (value * 100).rounded() / 100
506
+ if rounded == 0 { return "0" }
507
+ if rounded == rounded.rounded() { return String(Int(rounded)) }
508
+ return String(rounded)
509
+ }
510
+ }
511
+
512
+ extension Path: CustomStringConvertible {
513
+ /// Core Graphics' textual form (`x y m`, `x y l`, `cx cy x y q`, `c1 c2 p c`, `h`).
514
+ public var description: String {
515
+ elements.map { element in
516
+ func n(_ p: CGPoint) -> String { Path.number(p.x) + " " + Path.number(p.y) }
517
+ switch element {
518
+ case .move(let p): return n(p) + " m"
519
+ case .line(let p): return n(p) + " l"
520
+ case .quadCurve(let p, let c): return n(c) + " " + n(p) + " q"
521
+ case .curve(let p, let c1, let c2): return n(c1) + " " + n(c2) + " " + n(p) + " c"
522
+ case .closeSubpath: return "h"
523
+ }
524
+ }.joined(separator: " ")
525
+ }
526
+ }
527
+
528
+ extension CGRect {
529
+ /// The rectangle with a positive width and height.
530
+ public var standardized: CGRect {
531
+ CGRect(x: min(minX, maxX), y: min(minY, maxY), width: abs(width), height: abs(height))
532
+ }
533
+ }
534
+
535
+ extension CGPoint {
536
+ fileprivate func distance(to other: CGPoint) -> CGFloat {
537
+ ((other.x - x) * (other.x - x) + (other.y - y) * (other.y - y)).squareRoot()
538
+ }
539
+
540
+ fileprivate func interpolated(to other: CGPoint, amount: CGFloat) -> CGPoint {
541
+ CGPoint(x: x + (other.x - x) * amount, y: y + (other.y - y) * amount)
542
+ }
543
+ }