├── .github └── workflows │ └── swift.yml ├── .gitignore ├── Beacon.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ ├── IDEWorkspaceChecks.plist │ │ └── swiftpm │ │ └── Package.resolved └── xcshareddata │ └── xcschemes │ ├── Beacon.xcscheme │ ├── BeaconRelease.xcscheme │ ├── BeaconSim 1.xcscheme │ ├── BeaconSim.xcscheme │ ├── Keyboard.xcscheme │ └── KeyboardKit.xcscheme ├── Beacon ├── ArraygroundApp.swift ├── Assets.xcassets │ ├── AccentColor.colorset │ │ └── Contents.json │ ├── AppIcon.appiconset │ │ ├── Contents.json │ │ └── icon.png │ └── Contents.json ├── Components │ └── ReplInput.swift ├── Info.plist ├── Libs │ ├── curl.xcframework │ │ ├── Info.plist │ │ ├── ios-arm64 │ │ │ └── curl.framework │ │ │ │ ├── Headers │ │ │ │ ├── curl.h │ │ │ │ ├── curlver.h │ │ │ │ ├── easy.h │ │ │ │ ├── header.h │ │ │ │ ├── mprintf.h │ │ │ │ ├── multi.h │ │ │ │ ├── options.h │ │ │ │ ├── stdcheaders.h │ │ │ │ ├── system.h │ │ │ │ ├── typecheck-gcc.h │ │ │ │ ├── urlapi.h │ │ │ │ └── websockets.h │ │ │ │ └── curl │ │ └── ios-arm64_x86_64-simulator │ │ │ └── curl.framework │ │ │ ├── Headers │ │ │ ├── curl.h │ │ │ ├── curlver.h │ │ │ ├── easy.h │ │ │ ├── header.h │ │ │ ├── mprintf.h │ │ │ ├── multi.h │ │ │ ├── options.h │ │ │ ├── stdcheaders.h │ │ │ ├── system.h │ │ │ ├── typecheck-gcc.h │ │ │ ├── urlapi.h │ │ │ └── websockets.h │ │ │ └── curl │ ├── get_libs.sh │ ├── iosbqn.a │ ├── libcbqn.a │ ├── libk.a │ ├── libksim.a │ └── simbqn.a ├── Models │ └── History.swift ├── Preview Content │ └── Preview Assets.xcassets │ │ └── Contents.json ├── Utilities │ ├── Beacon-Bridging-Header.h │ ├── Lexer.swift │ ├── Tokenizer.swift │ ├── Utils.swift │ ├── bqnffi.h │ ├── k.h │ └── stdlib │ │ ├── bigint.bqn │ │ ├── bignat.bqn │ │ ├── csv.bqn │ │ ├── datetime.bqn │ │ ├── hashmap.bqn │ │ ├── matrix.bqn │ │ ├── min.bqn │ │ ├── perlin.bqn │ │ ├── polynomial.bqn │ │ ├── primes.bqn │ │ ├── roots.bqn │ │ └── strings.bqn └── Views │ ├── BuffersView.swift │ ├── ConfigView.swift │ ├── ContentView.swift │ ├── DashboardView.swift │ ├── HelpView.swift │ └── HistoryView.swift ├── Fonts └── BQN386.ttf ├── Keyboard ├── AutocompleteProvider.swift ├── BQNInputSetProvider.swift ├── Info.plist ├── KbViewController.swift ├── KeyboardActionHandler.swift ├── KeyboardAppearance.swift ├── KeyboardLayoutProvider.swift ├── KeyboardView.swift └── KeyboardViewController.swift ├── LICENSE └── README.md /.github/workflows/swift.yml: -------------------------------------------------------------------------------- 1 | # This workflow will build a Swift project 2 | # For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-swift 3 | 4 | name: Swift 5 | 6 | on: 7 | push: 8 | branches: [ "main" ] 9 | pull_request: 10 | branches: [ "main" ] 11 | 12 | jobs: 13 | build: 14 | 15 | runs-on: macos-latest 16 | 17 | steps: 18 | - uses: actions/checkout@v3 19 | - name: Build 20 | run: swift build -v 21 | - name: Run tests 22 | run: swift test -v 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 4 | 5 | ## User settings 6 | xcuserdata/ 7 | 8 | ## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9) 9 | *.xcscmblueprint 10 | *.xccheckout 11 | 12 | ## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4) 13 | build/ 14 | DerivedData/ 15 | *.moved-aside 16 | *.pbxuser 17 | !default.pbxuser 18 | *.mode1v3 19 | !default.mode1v3 20 | *.mode2v3 21 | !default.mode2v3 22 | *.perspectivev3 23 | !default.perspectivev3 24 | 25 | ## Obj-C/Swift specific 26 | *.hmap 27 | 28 | ## App packaging 29 | *.ipa 30 | *.dSYM.zip 31 | *.dSYM 32 | 33 | ## Playgrounds 34 | timeline.xctimeline 35 | playground.xcworkspace 36 | 37 | # Swift Package Manager 38 | # 39 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. 40 | # Packages/ 41 | # Package.pins 42 | # Package.resolved 43 | # *.xcodeproj 44 | # 45 | # Xcode automatically generates this directory with a .xcworkspacedata file and xcuserdata 46 | # hence it is not needed unless you have added a package configuration file to your project 47 | # .swiftpm 48 | 49 | .build/ 50 | 51 | # CocoaPods 52 | # 53 | # We recommend against adding the Pods directory to your .gitignore. However 54 | # you should judge for yourself, the pros and cons are mentioned at: 55 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 56 | # 57 | # Pods/ 58 | # 59 | # Add this line if you want to avoid checking in source code from the Xcode workspace 60 | # *.xcworkspace 61 | 62 | # Carthage 63 | # 64 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 65 | # Carthage/Checkouts 66 | 67 | Carthage/Build/ 68 | 69 | # Accio dependency management 70 | Dependencies/ 71 | .accio/ 72 | 73 | # fastlane 74 | # 75 | # It is recommended to not store the screenshots in the git repo. 76 | # Instead, use fastlane to re-generate the screenshots whenever they are needed. 77 | # For more information about the recommended setup visit: 78 | # https://docs.fastlane.tools/best-practices/source-control/#source-control 79 | 80 | fastlane/report.xml 81 | fastlane/Preview.html 82 | fastlane/screenshots/**/*.png 83 | fastlane/test_output 84 | 85 | # Code Injection 86 | # 87 | # After new code Injection tools there's a generated folder /iOSInjectionProject 88 | # https://github.com/johnno1962/injectionforxcode 89 | 90 | iOSInjectionProject/ 91 | .DS_Store 92 | -------------------------------------------------------------------------------- /Beacon.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Beacon.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Beacon.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved: -------------------------------------------------------------------------------- 1 | { 2 | "pins" : [ 3 | { 4 | "identity" : "keyboardkit", 5 | "kind" : "remoteSourceControl", 6 | "location" : "https://github.com/KeyboardKit/KeyboardKit", 7 | "state" : { 8 | "revision" : "f6bd1def639641b2cff9ca4cddbb4615aa717e5c", 9 | "version" : "7.9.0" 10 | } 11 | }, 12 | { 13 | "identity" : "swiftui-introspect", 14 | "kind" : "remoteSourceControl", 15 | "location" : "https://github.com/siteline/SwiftUI-Introspect", 16 | "state" : { 17 | "branch" : "master", 18 | "revision" : "a5a1d7c305e9d9082958de04d521be57a88d431a" 19 | } 20 | } 21 | ], 22 | "version" : 2 23 | } 24 | -------------------------------------------------------------------------------- /Beacon.xcodeproj/xcshareddata/xcschemes/Beacon.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 43 | 45 | 51 | 52 | 53 | 54 | 60 | 61 | 67 | 68 | 69 | 70 | 72 | 73 | 76 | 77 | 78 | -------------------------------------------------------------------------------- /Beacon.xcodeproj/xcshareddata/xcschemes/BeaconRelease.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 31 | 32 | 42 | 44 | 50 | 51 | 52 | 53 | 59 | 61 | 67 | 68 | 69 | 70 | 72 | 73 | 76 | 77 | 78 | -------------------------------------------------------------------------------- /Beacon.xcodeproj/xcshareddata/xcschemes/BeaconSim 1.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 31 | 32 | 42 | 44 | 50 | 51 | 52 | 53 | 59 | 61 | 67 | 68 | 69 | 70 | 72 | 73 | 76 | 77 | 78 | -------------------------------------------------------------------------------- /Beacon.xcodeproj/xcshareddata/xcschemes/BeaconSim.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 43 | 45 | 51 | 52 | 53 | 54 | 60 | 62 | 68 | 69 | 70 | 71 | 73 | 74 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /Beacon.xcodeproj/xcshareddata/xcschemes/Keyboard.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 6 | 9 | 10 | 16 | 22 | 23 | 24 | 30 | 36 | 37 | 38 | 39 | 40 | 45 | 46 | 47 | 48 | 60 | 64 | 65 | 66 | 72 | 73 | 74 | 75 | 83 | 85 | 91 | 92 | 93 | 94 | 96 | 97 | 100 | 101 | 102 | -------------------------------------------------------------------------------- /Beacon.xcodeproj/xcshareddata/xcschemes/KeyboardKit.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 29 | 35 | 36 | 37 | 38 | 39 | 44 | 45 | 47 | 53 | 54 | 55 | 56 | 57 | 67 | 68 | 74 | 75 | 81 | 82 | 83 | 84 | 86 | 87 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /Beacon/ArraygroundApp.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ArraygroundApp.swift 3 | // Arrayground 4 | // 5 | 6 | import SwiftUI 7 | 8 | @main 9 | struct ArraygroundApp: App { 10 | @AppStorage("scheme") private var scheme: Appearance = .system 11 | @State private var selectedView = 0 12 | var appearanceSwitch: ColorScheme? { 13 | if scheme == .light { 14 | return .light 15 | } else if scheme == .dark { 16 | return .dark 17 | } else { 18 | return .none 19 | } 20 | } 21 | 22 | @StateObject private var viewModel = HistoryModel() 23 | 24 | var body: some Scene { 25 | WindowGroup { 26 | TabView(selection: $selectedView) { 27 | ContentView(viewModel: viewModel).tag(0) 28 | .preferredColorScheme(appearanceSwitch) 29 | // Dashboard().tag(1) 30 | }.tabViewStyle(PageTabViewStyle(indexDisplayMode: .never)) 31 | .onChange(of: selectedView) { 32 | dismissKeyboard() 33 | } 34 | } 35 | } 36 | 37 | func dismissKeyboard() { 38 | UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil) 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /Beacon/Assets.xcassets/AccentColor.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "platform" : "universal", 6 | "reference" : "labelColor" 7 | }, 8 | "idiom" : "universal" 9 | } 10 | ], 11 | "info" : { 12 | "author" : "xcode", 13 | "version" : 1 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Beacon/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "icon.png", 5 | "idiom" : "universal", 6 | "platform" : "ios", 7 | "size" : "1024x1024" 8 | } 9 | ], 10 | "info" : { 11 | "author" : "xcode", 12 | "version" : 1 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Beacon/Assets.xcassets/AppIcon.appiconset/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/x86y/arrayground/996108fc1d4024570b9cf75fdabec0ea3ba85184/Beacon/Assets.xcassets/AppIcon.appiconset/icon.png -------------------------------------------------------------------------------- /Beacon/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /Beacon/Components/ReplInput.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | struct ReplInput: View { 4 | @Binding var text: String 5 | @Binding var helpOpen: Bool 6 | @Binding var settingsOpen: Bool 7 | @Binding var buffersOpen: Bool 8 | var lang: Language 9 | var onSubmit: (() -> Void)? 10 | var font: Font 11 | var letters: [String] { 12 | lang == .bqn ? glyphs : ["`", "'", "/", "\\", "%", "*", "+", "-", "=", "!", "\"", ":", "@"] 13 | } 14 | 15 | var body: some View { 16 | let toolbar = ToolbarItemGroup(placement: .keyboard) { 17 | HStack { 18 | ScrollView(.horizontal) { 19 | HStack { 20 | ForEach(letters, id: \.self) { letter in 21 | Button(letter) { 22 | text.append(letter) 23 | } 24 | .font(.custom("BQN386 Unicode", size: 16)) 25 | .padding(8) 26 | .background(.gray.opacity(0.1)) 27 | .foregroundStyle(.primary) 28 | .clipShape(RoundedRectangle(cornerRadius: 8)) 29 | } 30 | } 31 | } 32 | 33 | Button(action: { text = "" }) { 34 | Image(systemName: "arrow.left.square.fill") 35 | .resizable() 36 | .frame(width: 16.0, height: 16.0) 37 | } 38 | Button(action: { helpOpen.toggle() }) { 39 | Image(systemName: "questionmark.app.fill") 40 | .resizable() 41 | .frame(width: 16.0, height: 16.0) 42 | } 43 | Button(action: { buffersOpen.toggle() }) { 44 | Image(systemName: "list.bullet.rectangle.portrait.fill") 45 | .resizable() 46 | .frame(width: 16.0, height: 16.0) 47 | } 48 | Button(action: { settingsOpen.toggle() }) { 49 | Image(systemName: "command.square.fill") 50 | .resizable() 51 | .frame(width: 16.0, height: 16.0) 52 | } 53 | } 54 | } 55 | 56 | HStack { 57 | TextField("Type \(languageToString(l: lang))...", text: $text, axis: .vertical) 58 | .onSubmit { 59 | onSubmit?() 60 | } 61 | .toolbar { 62 | toolbar 63 | } 64 | .lineLimit(1 ... 8) 65 | .keyboardType(.asciiCapable) 66 | .submitLabel(.done) 67 | .disableAutocorrection(true) 68 | .font(font) 69 | .frame(minHeight: 36) 70 | .padding(EdgeInsets(top: 0, leading: 16, bottom: 0, trailing: 16)) 71 | .overlay( 72 | RoundedRectangle(cornerRadius: 48) 73 | .stroke(.gray.opacity(0.2), lineWidth: 1) 74 | ) 75 | Button(action: { 76 | onSubmit?() 77 | }) { 78 | Image(systemName: "play.circle.fill") 79 | .resizable() 80 | .frame(width: 32.0, height: 32.0) 81 | .foregroundStyle(.blue.opacity(0.9)) 82 | } 83 | .padding(4) 84 | } 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /Beacon/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | UIAppFonts 6 | 7 | Fonts/BQN386.ttf 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Beacon/Libs/curl.xcframework/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | AvailableLibraries 6 | 7 | 8 | LibraryIdentifier 9 | ios-arm64_x86_64-simulator 10 | LibraryPath 11 | curl.framework 12 | SupportedArchitectures 13 | 14 | arm64 15 | x86_64 16 | 17 | SupportedPlatform 18 | ios 19 | SupportedPlatformVariant 20 | simulator 21 | 22 | 23 | LibraryIdentifier 24 | ios-arm64 25 | LibraryPath 26 | curl.framework 27 | SupportedArchitectures 28 | 29 | arm64 30 | 31 | SupportedPlatform 32 | ios 33 | 34 | 35 | CFBundlePackageType 36 | XFWK 37 | CFBundleVersion 38 | 8.0.1 39 | XCFrameworkFormatVersion 40 | 1.0 41 | 42 | 43 | -------------------------------------------------------------------------------- /Beacon/Libs/curl.xcframework/ios-arm64/curl.framework/Headers/curlver.h: -------------------------------------------------------------------------------- 1 | #ifndef CURLINC_CURLVER_H 2 | #define CURLINC_CURLVER_H 3 | /*************************************************************************** 4 | * _ _ ____ _ 5 | * Project ___| | | | _ \| | 6 | * / __| | | | |_) | | 7 | * | (__| |_| | _ <| |___ 8 | * \___|\___/|_| \_\_____| 9 | * 10 | * Copyright (C) Daniel Stenberg, , et al. 11 | * 12 | * This software is licensed as described in the file COPYING, which 13 | * you should have received as part of this distribution. The terms 14 | * are also available at https://curl.se/docs/copyright.html. 15 | * 16 | * You may opt to use, copy, modify, merge, publish, distribute and/or sell 17 | * copies of the Software, and permit persons to whom the Software is 18 | * furnished to do so, under the terms of the COPYING file. 19 | * 20 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 21 | * KIND, either express or implied. 22 | * 23 | * SPDX-License-Identifier: curl 24 | * 25 | ***************************************************************************/ 26 | 27 | /* This header file contains nothing but libcurl version info, generated by 28 | a script at release-time. This was made its own header file in 7.11.2 */ 29 | 30 | /* This is the global package copyright */ 31 | #define LIBCURL_COPYRIGHT "Daniel Stenberg, ." 32 | 33 | /* This is the version number of the libcurl package from which this header 34 | file origins: */ 35 | #define LIBCURL_VERSION "8.0.1" 36 | 37 | /* The numeric version number is also available "in parts" by using these 38 | defines: */ 39 | #define LIBCURL_VERSION_MAJOR 8 40 | #define LIBCURL_VERSION_MINOR 0 41 | #define LIBCURL_VERSION_PATCH 1 42 | 43 | /* This is the numeric version of the libcurl version number, meant for easier 44 | parsing and comparisons by programs. The LIBCURL_VERSION_NUM define will 45 | always follow this syntax: 46 | 47 | 0xXXYYZZ 48 | 49 | Where XX, YY and ZZ are the main version, release and patch numbers in 50 | hexadecimal (using 8 bits each). All three numbers are always represented 51 | using two digits. 1.2 would appear as "0x010200" while version 9.11.7 52 | appears as "0x090b07". 53 | 54 | This 6-digit (24 bits) hexadecimal number does not show pre-release number, 55 | and it is always a greater number in a more recent release. It makes 56 | comparisons with greater than and less than work. 57 | 58 | Note: This define is the full hex number and _does not_ use the 59 | CURL_VERSION_BITS() macro since curl's own configure script greps for it 60 | and needs it to contain the full number. 61 | */ 62 | #define LIBCURL_VERSION_NUM 0x080001 63 | 64 | /* 65 | * This is the date and time when the full source package was created. The 66 | * timestamp is not stored in git, as the timestamp is properly set in the 67 | * tarballs by the maketgz script. 68 | * 69 | * The format of the date follows this template: 70 | * 71 | * "2007-11-23" 72 | */ 73 | #define LIBCURL_TIMESTAMP "2023-03-20" 74 | 75 | #define CURL_VERSION_BITS(x,y,z) ((x)<<16|(y)<<8|(z)) 76 | #define CURL_AT_LEAST_VERSION(x,y,z) \ 77 | (LIBCURL_VERSION_NUM >= CURL_VERSION_BITS(x, y, z)) 78 | 79 | #endif /* CURLINC_CURLVER_H */ 80 | -------------------------------------------------------------------------------- /Beacon/Libs/curl.xcframework/ios-arm64/curl.framework/Headers/easy.h: -------------------------------------------------------------------------------- 1 | #ifndef CURLINC_EASY_H 2 | #define CURLINC_EASY_H 3 | /*************************************************************************** 4 | * _ _ ____ _ 5 | * Project ___| | | | _ \| | 6 | * / __| | | | |_) | | 7 | * | (__| |_| | _ <| |___ 8 | * \___|\___/|_| \_\_____| 9 | * 10 | * Copyright (C) Daniel Stenberg, , et al. 11 | * 12 | * This software is licensed as described in the file COPYING, which 13 | * you should have received as part of this distribution. The terms 14 | * are also available at https://curl.se/docs/copyright.html. 15 | * 16 | * You may opt to use, copy, modify, merge, publish, distribute and/or sell 17 | * copies of the Software, and permit persons to whom the Software is 18 | * furnished to do so, under the terms of the COPYING file. 19 | * 20 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 21 | * KIND, either express or implied. 22 | * 23 | * SPDX-License-Identifier: curl 24 | * 25 | ***************************************************************************/ 26 | #ifdef __cplusplus 27 | extern "C" { 28 | #endif 29 | 30 | /* Flag bits in the curl_blob struct: */ 31 | #define CURL_BLOB_COPY 1 /* tell libcurl to copy the data */ 32 | #define CURL_BLOB_NOCOPY 0 /* tell libcurl to NOT copy the data */ 33 | 34 | struct curl_blob { 35 | void *data; 36 | size_t len; 37 | unsigned int flags; /* bit 0 is defined, the rest are reserved and should be 38 | left zeroes */ 39 | }; 40 | 41 | CURL_EXTERN CURL *curl_easy_init(void); 42 | CURL_EXTERN CURLcode curl_easy_setopt(CURL *curl, CURLoption option, ...); 43 | CURL_EXTERN CURLcode curl_easy_perform(CURL *curl); 44 | CURL_EXTERN void curl_easy_cleanup(CURL *curl); 45 | 46 | /* 47 | * NAME curl_easy_getinfo() 48 | * 49 | * DESCRIPTION 50 | * 51 | * Request internal information from the curl session with this function. The 52 | * third argument MUST be a pointer to a long, a pointer to a char * or a 53 | * pointer to a double (as the documentation describes elsewhere). The data 54 | * pointed to will be filled in accordingly and can be relied upon only if the 55 | * function returns CURLE_OK. This function is intended to get used *AFTER* a 56 | * performed transfer, all results from this function are undefined until the 57 | * transfer is completed. 58 | */ 59 | CURL_EXTERN CURLcode curl_easy_getinfo(CURL *curl, CURLINFO info, ...); 60 | 61 | 62 | /* 63 | * NAME curl_easy_duphandle() 64 | * 65 | * DESCRIPTION 66 | * 67 | * Creates a new curl session handle with the same options set for the handle 68 | * passed in. Duplicating a handle could only be a matter of cloning data and 69 | * options, internal state info and things like persistent connections cannot 70 | * be transferred. It is useful in multithreaded applications when you can run 71 | * curl_easy_duphandle() for each new thread to avoid a series of identical 72 | * curl_easy_setopt() invokes in every thread. 73 | */ 74 | CURL_EXTERN CURL *curl_easy_duphandle(CURL *curl); 75 | 76 | /* 77 | * NAME curl_easy_reset() 78 | * 79 | * DESCRIPTION 80 | * 81 | * Re-initializes a CURL handle to the default values. This puts back the 82 | * handle to the same state as it was in when it was just created. 83 | * 84 | * It does keep: live connections, the Session ID cache, the DNS cache and the 85 | * cookies. 86 | */ 87 | CURL_EXTERN void curl_easy_reset(CURL *curl); 88 | 89 | /* 90 | * NAME curl_easy_recv() 91 | * 92 | * DESCRIPTION 93 | * 94 | * Receives data from the connected socket. Use after successful 95 | * curl_easy_perform() with CURLOPT_CONNECT_ONLY option. 96 | */ 97 | CURL_EXTERN CURLcode curl_easy_recv(CURL *curl, void *buffer, size_t buflen, 98 | size_t *n); 99 | 100 | /* 101 | * NAME curl_easy_send() 102 | * 103 | * DESCRIPTION 104 | * 105 | * Sends data over the connected socket. Use after successful 106 | * curl_easy_perform() with CURLOPT_CONNECT_ONLY option. 107 | */ 108 | CURL_EXTERN CURLcode curl_easy_send(CURL *curl, const void *buffer, 109 | size_t buflen, size_t *n); 110 | 111 | 112 | /* 113 | * NAME curl_easy_upkeep() 114 | * 115 | * DESCRIPTION 116 | * 117 | * Performs connection upkeep for the given session handle. 118 | */ 119 | CURL_EXTERN CURLcode curl_easy_upkeep(CURL *curl); 120 | 121 | #ifdef __cplusplus 122 | } /* end of extern "C" */ 123 | #endif 124 | 125 | #endif 126 | -------------------------------------------------------------------------------- /Beacon/Libs/curl.xcframework/ios-arm64/curl.framework/Headers/header.h: -------------------------------------------------------------------------------- 1 | #ifndef CURLINC_HEADER_H 2 | #define CURLINC_HEADER_H 3 | /*************************************************************************** 4 | * _ _ ____ _ 5 | * Project ___| | | | _ \| | 6 | * / __| | | | |_) | | 7 | * | (__| |_| | _ <| |___ 8 | * \___|\___/|_| \_\_____| 9 | * 10 | * Copyright (C) Daniel Stenberg, , et al. 11 | * 12 | * This software is licensed as described in the file COPYING, which 13 | * you should have received as part of this distribution. The terms 14 | * are also available at https://curl.se/docs/copyright.html. 15 | * 16 | * You may opt to use, copy, modify, merge, publish, distribute and/or sell 17 | * copies of the Software, and permit persons to whom the Software is 18 | * furnished to do so, under the terms of the COPYING file. 19 | * 20 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 21 | * KIND, either express or implied. 22 | * 23 | * SPDX-License-Identifier: curl 24 | * 25 | ***************************************************************************/ 26 | 27 | #ifdef __cplusplus 28 | extern "C" { 29 | #endif 30 | 31 | struct curl_header { 32 | char *name; /* this might not use the same case */ 33 | char *value; 34 | size_t amount; /* number of headers using this name */ 35 | size_t index; /* ... of this instance, 0 or higher */ 36 | unsigned int origin; /* see bits below */ 37 | void *anchor; /* handle privately used by libcurl */ 38 | }; 39 | 40 | /* 'origin' bits */ 41 | #define CURLH_HEADER (1<<0) /* plain server header */ 42 | #define CURLH_TRAILER (1<<1) /* trailers */ 43 | #define CURLH_CONNECT (1<<2) /* CONNECT headers */ 44 | #define CURLH_1XX (1<<3) /* 1xx headers */ 45 | #define CURLH_PSEUDO (1<<4) /* pseudo headers */ 46 | 47 | typedef enum { 48 | CURLHE_OK, 49 | CURLHE_BADINDEX, /* header exists but not with this index */ 50 | CURLHE_MISSING, /* no such header exists */ 51 | CURLHE_NOHEADERS, /* no headers at all exist (yet) */ 52 | CURLHE_NOREQUEST, /* no request with this number was used */ 53 | CURLHE_OUT_OF_MEMORY, /* out of memory while processing */ 54 | CURLHE_BAD_ARGUMENT, /* a function argument was not okay */ 55 | CURLHE_NOT_BUILT_IN /* if API was disabled in the build */ 56 | } CURLHcode; 57 | 58 | CURL_EXTERN CURLHcode curl_easy_header(CURL *easy, 59 | const char *name, 60 | size_t index, 61 | unsigned int origin, 62 | int request, 63 | struct curl_header **hout); 64 | 65 | CURL_EXTERN struct curl_header *curl_easy_nextheader(CURL *easy, 66 | unsigned int origin, 67 | int request, 68 | struct curl_header *prev); 69 | 70 | #ifdef __cplusplus 71 | } /* end of extern "C" */ 72 | #endif 73 | 74 | #endif /* CURLINC_HEADER_H */ 75 | -------------------------------------------------------------------------------- /Beacon/Libs/curl.xcframework/ios-arm64/curl.framework/Headers/mprintf.h: -------------------------------------------------------------------------------- 1 | #ifndef CURLINC_MPRINTF_H 2 | #define CURLINC_MPRINTF_H 3 | /*************************************************************************** 4 | * _ _ ____ _ 5 | * Project ___| | | | _ \| | 6 | * / __| | | | |_) | | 7 | * | (__| |_| | _ <| |___ 8 | * \___|\___/|_| \_\_____| 9 | * 10 | * Copyright (C) Daniel Stenberg, , et al. 11 | * 12 | * This software is licensed as described in the file COPYING, which 13 | * you should have received as part of this distribution. The terms 14 | * are also available at https://curl.se/docs/copyright.html. 15 | * 16 | * You may opt to use, copy, modify, merge, publish, distribute and/or sell 17 | * copies of the Software, and permit persons to whom the Software is 18 | * furnished to do so, under the terms of the COPYING file. 19 | * 20 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 21 | * KIND, either express or implied. 22 | * 23 | * SPDX-License-Identifier: curl 24 | * 25 | ***************************************************************************/ 26 | 27 | #include 28 | #include /* needed for FILE */ 29 | #include "curl.h" /* for CURL_EXTERN */ 30 | 31 | #ifdef __cplusplus 32 | extern "C" { 33 | #endif 34 | 35 | CURL_EXTERN int curl_mprintf(const char *format, ...); 36 | CURL_EXTERN int curl_mfprintf(FILE *fd, const char *format, ...); 37 | CURL_EXTERN int curl_msprintf(char *buffer, const char *format, ...); 38 | CURL_EXTERN int curl_msnprintf(char *buffer, size_t maxlength, 39 | const char *format, ...); 40 | CURL_EXTERN int curl_mvprintf(const char *format, va_list args); 41 | CURL_EXTERN int curl_mvfprintf(FILE *fd, const char *format, va_list args); 42 | CURL_EXTERN int curl_mvsprintf(char *buffer, const char *format, va_list args); 43 | CURL_EXTERN int curl_mvsnprintf(char *buffer, size_t maxlength, 44 | const char *format, va_list args); 45 | CURL_EXTERN char *curl_maprintf(const char *format, ...); 46 | CURL_EXTERN char *curl_mvaprintf(const char *format, va_list args); 47 | 48 | #ifdef __cplusplus 49 | } /* end of extern "C" */ 50 | #endif 51 | 52 | #endif /* CURLINC_MPRINTF_H */ 53 | -------------------------------------------------------------------------------- /Beacon/Libs/curl.xcframework/ios-arm64/curl.framework/Headers/multi.h: -------------------------------------------------------------------------------- 1 | #ifndef CURLINC_MULTI_H 2 | #define CURLINC_MULTI_H 3 | /*************************************************************************** 4 | * _ _ ____ _ 5 | * Project ___| | | | _ \| | 6 | * / __| | | | |_) | | 7 | * | (__| |_| | _ <| |___ 8 | * \___|\___/|_| \_\_____| 9 | * 10 | * Copyright (C) Daniel Stenberg, , et al. 11 | * 12 | * This software is licensed as described in the file COPYING, which 13 | * you should have received as part of this distribution. The terms 14 | * are also available at https://curl.se/docs/copyright.html. 15 | * 16 | * You may opt to use, copy, modify, merge, publish, distribute and/or sell 17 | * copies of the Software, and permit persons to whom the Software is 18 | * furnished to do so, under the terms of the COPYING file. 19 | * 20 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 21 | * KIND, either express or implied. 22 | * 23 | * SPDX-License-Identifier: curl 24 | * 25 | ***************************************************************************/ 26 | /* 27 | This is an "external" header file. Don't give away any internals here! 28 | 29 | GOALS 30 | 31 | o Enable a "pull" interface. The application that uses libcurl decides where 32 | and when to ask libcurl to get/send data. 33 | 34 | o Enable multiple simultaneous transfers in the same thread without making it 35 | complicated for the application. 36 | 37 | o Enable the application to select() on its own file descriptors and curl's 38 | file descriptors simultaneous easily. 39 | 40 | */ 41 | 42 | /* 43 | * This header file should not really need to include "curl.h" since curl.h 44 | * itself includes this file and we expect user applications to do #include 45 | * without the need for especially including multi.h. 46 | * 47 | * For some reason we added this include here at one point, and rather than to 48 | * break existing (wrongly written) libcurl applications, we leave it as-is 49 | * but with this warning attached. 50 | */ 51 | #include "curl.h" 52 | 53 | #ifdef __cplusplus 54 | extern "C" { 55 | #endif 56 | 57 | #if defined(BUILDING_LIBCURL) || defined(CURL_STRICTER) 58 | typedef struct Curl_multi CURLM; 59 | #else 60 | typedef void CURLM; 61 | #endif 62 | 63 | typedef enum { 64 | CURLM_CALL_MULTI_PERFORM = -1, /* please call curl_multi_perform() or 65 | curl_multi_socket*() soon */ 66 | CURLM_OK, 67 | CURLM_BAD_HANDLE, /* the passed-in handle is not a valid CURLM handle */ 68 | CURLM_BAD_EASY_HANDLE, /* an easy handle was not good/valid */ 69 | CURLM_OUT_OF_MEMORY, /* if you ever get this, you're in deep sh*t */ 70 | CURLM_INTERNAL_ERROR, /* this is a libcurl bug */ 71 | CURLM_BAD_SOCKET, /* the passed in socket argument did not match */ 72 | CURLM_UNKNOWN_OPTION, /* curl_multi_setopt() with unsupported option */ 73 | CURLM_ADDED_ALREADY, /* an easy handle already added to a multi handle was 74 | attempted to get added - again */ 75 | CURLM_RECURSIVE_API_CALL, /* an api function was called from inside a 76 | callback */ 77 | CURLM_WAKEUP_FAILURE, /* wakeup is unavailable or failed */ 78 | CURLM_BAD_FUNCTION_ARGUMENT, /* function called with a bad parameter */ 79 | CURLM_ABORTED_BY_CALLBACK, 80 | CURLM_UNRECOVERABLE_POLL, 81 | CURLM_LAST 82 | } CURLMcode; 83 | 84 | /* just to make code nicer when using curl_multi_socket() you can now check 85 | for CURLM_CALL_MULTI_SOCKET too in the same style it works for 86 | curl_multi_perform() and CURLM_CALL_MULTI_PERFORM */ 87 | #define CURLM_CALL_MULTI_SOCKET CURLM_CALL_MULTI_PERFORM 88 | 89 | /* bitmask bits for CURLMOPT_PIPELINING */ 90 | #define CURLPIPE_NOTHING 0L 91 | #define CURLPIPE_HTTP1 1L 92 | #define CURLPIPE_MULTIPLEX 2L 93 | 94 | typedef enum { 95 | CURLMSG_NONE, /* first, not used */ 96 | CURLMSG_DONE, /* This easy handle has completed. 'result' contains 97 | the CURLcode of the transfer */ 98 | CURLMSG_LAST /* last, not used */ 99 | } CURLMSG; 100 | 101 | struct CURLMsg { 102 | CURLMSG msg; /* what this message means */ 103 | CURL *easy_handle; /* the handle it concerns */ 104 | union { 105 | void *whatever; /* message-specific data */ 106 | CURLcode result; /* return code for transfer */ 107 | } data; 108 | }; 109 | typedef struct CURLMsg CURLMsg; 110 | 111 | /* Based on poll(2) structure and values. 112 | * We don't use pollfd and POLL* constants explicitly 113 | * to cover platforms without poll(). */ 114 | #define CURL_WAIT_POLLIN 0x0001 115 | #define CURL_WAIT_POLLPRI 0x0002 116 | #define CURL_WAIT_POLLOUT 0x0004 117 | 118 | struct curl_waitfd { 119 | curl_socket_t fd; 120 | short events; 121 | short revents; /* not supported yet */ 122 | }; 123 | 124 | /* 125 | * Name: curl_multi_init() 126 | * 127 | * Desc: initialize multi-style curl usage 128 | * 129 | * Returns: a new CURLM handle to use in all 'curl_multi' functions. 130 | */ 131 | CURL_EXTERN CURLM *curl_multi_init(void); 132 | 133 | /* 134 | * Name: curl_multi_add_handle() 135 | * 136 | * Desc: add a standard curl handle to the multi stack 137 | * 138 | * Returns: CURLMcode type, general multi error code. 139 | */ 140 | CURL_EXTERN CURLMcode curl_multi_add_handle(CURLM *multi_handle, 141 | CURL *curl_handle); 142 | 143 | /* 144 | * Name: curl_multi_remove_handle() 145 | * 146 | * Desc: removes a curl handle from the multi stack again 147 | * 148 | * Returns: CURLMcode type, general multi error code. 149 | */ 150 | CURL_EXTERN CURLMcode curl_multi_remove_handle(CURLM *multi_handle, 151 | CURL *curl_handle); 152 | 153 | /* 154 | * Name: curl_multi_fdset() 155 | * 156 | * Desc: Ask curl for its fd_set sets. The app can use these to select() or 157 | * poll() on. We want curl_multi_perform() called as soon as one of 158 | * them are ready. 159 | * 160 | * Returns: CURLMcode type, general multi error code. 161 | */ 162 | CURL_EXTERN CURLMcode curl_multi_fdset(CURLM *multi_handle, 163 | fd_set *read_fd_set, 164 | fd_set *write_fd_set, 165 | fd_set *exc_fd_set, 166 | int *max_fd); 167 | 168 | /* 169 | * Name: curl_multi_wait() 170 | * 171 | * Desc: Poll on all fds within a CURLM set as well as any 172 | * additional fds passed to the function. 173 | * 174 | * Returns: CURLMcode type, general multi error code. 175 | */ 176 | CURL_EXTERN CURLMcode curl_multi_wait(CURLM *multi_handle, 177 | struct curl_waitfd extra_fds[], 178 | unsigned int extra_nfds, 179 | int timeout_ms, 180 | int *ret); 181 | 182 | /* 183 | * Name: curl_multi_poll() 184 | * 185 | * Desc: Poll on all fds within a CURLM set as well as any 186 | * additional fds passed to the function. 187 | * 188 | * Returns: CURLMcode type, general multi error code. 189 | */ 190 | CURL_EXTERN CURLMcode curl_multi_poll(CURLM *multi_handle, 191 | struct curl_waitfd extra_fds[], 192 | unsigned int extra_nfds, 193 | int timeout_ms, 194 | int *ret); 195 | 196 | /* 197 | * Name: curl_multi_wakeup() 198 | * 199 | * Desc: wakes up a sleeping curl_multi_poll call. 200 | * 201 | * Returns: CURLMcode type, general multi error code. 202 | */ 203 | CURL_EXTERN CURLMcode curl_multi_wakeup(CURLM *multi_handle); 204 | 205 | /* 206 | * Name: curl_multi_perform() 207 | * 208 | * Desc: When the app thinks there's data available for curl it calls this 209 | * function to read/write whatever there is right now. This returns 210 | * as soon as the reads and writes are done. This function does not 211 | * require that there actually is data available for reading or that 212 | * data can be written, it can be called just in case. It returns 213 | * the number of handles that still transfer data in the second 214 | * argument's integer-pointer. 215 | * 216 | * Returns: CURLMcode type, general multi error code. *NOTE* that this only 217 | * returns errors etc regarding the whole multi stack. There might 218 | * still have occurred problems on individual transfers even when 219 | * this returns OK. 220 | */ 221 | CURL_EXTERN CURLMcode curl_multi_perform(CURLM *multi_handle, 222 | int *running_handles); 223 | 224 | /* 225 | * Name: curl_multi_cleanup() 226 | * 227 | * Desc: Cleans up and removes a whole multi stack. It does not free or 228 | * touch any individual easy handles in any way. We need to define 229 | * in what state those handles will be if this function is called 230 | * in the middle of a transfer. 231 | * 232 | * Returns: CURLMcode type, general multi error code. 233 | */ 234 | CURL_EXTERN CURLMcode curl_multi_cleanup(CURLM *multi_handle); 235 | 236 | /* 237 | * Name: curl_multi_info_read() 238 | * 239 | * Desc: Ask the multi handle if there's any messages/informationals from 240 | * the individual transfers. Messages include informationals such as 241 | * error code from the transfer or just the fact that a transfer is 242 | * completed. More details on these should be written down as well. 243 | * 244 | * Repeated calls to this function will return a new struct each 245 | * time, until a special "end of msgs" struct is returned as a signal 246 | * that there is no more to get at this point. 247 | * 248 | * The data the returned pointer points to will not survive calling 249 | * curl_multi_cleanup(). 250 | * 251 | * The 'CURLMsg' struct is meant to be very simple and only contain 252 | * very basic information. If more involved information is wanted, 253 | * we will provide the particular "transfer handle" in that struct 254 | * and that should/could/would be used in subsequent 255 | * curl_easy_getinfo() calls (or similar). The point being that we 256 | * must never expose complex structs to applications, as then we'll 257 | * undoubtably get backwards compatibility problems in the future. 258 | * 259 | * Returns: A pointer to a filled-in struct, or NULL if it failed or ran out 260 | * of structs. It also writes the number of messages left in the 261 | * queue (after this read) in the integer the second argument points 262 | * to. 263 | */ 264 | CURL_EXTERN CURLMsg *curl_multi_info_read(CURLM *multi_handle, 265 | int *msgs_in_queue); 266 | 267 | /* 268 | * Name: curl_multi_strerror() 269 | * 270 | * Desc: The curl_multi_strerror function may be used to turn a CURLMcode 271 | * value into the equivalent human readable error string. This is 272 | * useful for printing meaningful error messages. 273 | * 274 | * Returns: A pointer to a null-terminated error message. 275 | */ 276 | CURL_EXTERN const char *curl_multi_strerror(CURLMcode); 277 | 278 | /* 279 | * Name: curl_multi_socket() and 280 | * curl_multi_socket_all() 281 | * 282 | * Desc: An alternative version of curl_multi_perform() that allows the 283 | * application to pass in one of the file descriptors that have been 284 | * detected to have "action" on them and let libcurl perform. 285 | * See man page for details. 286 | */ 287 | #define CURL_POLL_NONE 0 288 | #define CURL_POLL_IN 1 289 | #define CURL_POLL_OUT 2 290 | #define CURL_POLL_INOUT 3 291 | #define CURL_POLL_REMOVE 4 292 | 293 | #define CURL_SOCKET_TIMEOUT CURL_SOCKET_BAD 294 | 295 | #define CURL_CSELECT_IN 0x01 296 | #define CURL_CSELECT_OUT 0x02 297 | #define CURL_CSELECT_ERR 0x04 298 | 299 | typedef int (*curl_socket_callback)(CURL *easy, /* easy handle */ 300 | curl_socket_t s, /* socket */ 301 | int what, /* see above */ 302 | void *userp, /* private callback 303 | pointer */ 304 | void *socketp); /* private socket 305 | pointer */ 306 | /* 307 | * Name: curl_multi_timer_callback 308 | * 309 | * Desc: Called by libcurl whenever the library detects a change in the 310 | * maximum number of milliseconds the app is allowed to wait before 311 | * curl_multi_socket() or curl_multi_perform() must be called 312 | * (to allow libcurl's timed events to take place). 313 | * 314 | * Returns: The callback should return zero. 315 | */ 316 | typedef int (*curl_multi_timer_callback)(CURLM *multi, /* multi handle */ 317 | long timeout_ms, /* see above */ 318 | void *userp); /* private callback 319 | pointer */ 320 | 321 | CURL_EXTERN CURLMcode CURL_DEPRECATED(7.19.5, "Use curl_multi_socket_action()") 322 | curl_multi_socket(CURLM *multi_handle, curl_socket_t s, int *running_handles); 323 | 324 | CURL_EXTERN CURLMcode curl_multi_socket_action(CURLM *multi_handle, 325 | curl_socket_t s, 326 | int ev_bitmask, 327 | int *running_handles); 328 | 329 | CURL_EXTERN CURLMcode CURL_DEPRECATED(7.19.5, "Use curl_multi_socket_action()") 330 | curl_multi_socket_all(CURLM *multi_handle, int *running_handles); 331 | 332 | #ifndef CURL_ALLOW_OLD_MULTI_SOCKET 333 | /* This macro below was added in 7.16.3 to push users who recompile to use 334 | the new curl_multi_socket_action() instead of the old curl_multi_socket() 335 | */ 336 | #define curl_multi_socket(x,y,z) curl_multi_socket_action(x,y,0,z) 337 | #endif 338 | 339 | /* 340 | * Name: curl_multi_timeout() 341 | * 342 | * Desc: Returns the maximum number of milliseconds the app is allowed to 343 | * wait before curl_multi_socket() or curl_multi_perform() must be 344 | * called (to allow libcurl's timed events to take place). 345 | * 346 | * Returns: CURLM error code. 347 | */ 348 | CURL_EXTERN CURLMcode curl_multi_timeout(CURLM *multi_handle, 349 | long *milliseconds); 350 | 351 | typedef enum { 352 | /* This is the socket callback function pointer */ 353 | CURLOPT(CURLMOPT_SOCKETFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 1), 354 | 355 | /* This is the argument passed to the socket callback */ 356 | CURLOPT(CURLMOPT_SOCKETDATA, CURLOPTTYPE_OBJECTPOINT, 2), 357 | 358 | /* set to 1 to enable pipelining for this multi handle */ 359 | CURLOPT(CURLMOPT_PIPELINING, CURLOPTTYPE_LONG, 3), 360 | 361 | /* This is the timer callback function pointer */ 362 | CURLOPT(CURLMOPT_TIMERFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 4), 363 | 364 | /* This is the argument passed to the timer callback */ 365 | CURLOPT(CURLMOPT_TIMERDATA, CURLOPTTYPE_OBJECTPOINT, 5), 366 | 367 | /* maximum number of entries in the connection cache */ 368 | CURLOPT(CURLMOPT_MAXCONNECTS, CURLOPTTYPE_LONG, 6), 369 | 370 | /* maximum number of (pipelining) connections to one host */ 371 | CURLOPT(CURLMOPT_MAX_HOST_CONNECTIONS, CURLOPTTYPE_LONG, 7), 372 | 373 | /* maximum number of requests in a pipeline */ 374 | CURLOPT(CURLMOPT_MAX_PIPELINE_LENGTH, CURLOPTTYPE_LONG, 8), 375 | 376 | /* a connection with a content-length longer than this 377 | will not be considered for pipelining */ 378 | CURLOPT(CURLMOPT_CONTENT_LENGTH_PENALTY_SIZE, CURLOPTTYPE_OFF_T, 9), 379 | 380 | /* a connection with a chunk length longer than this 381 | will not be considered for pipelining */ 382 | CURLOPT(CURLMOPT_CHUNK_LENGTH_PENALTY_SIZE, CURLOPTTYPE_OFF_T, 10), 383 | 384 | /* a list of site names(+port) that are blocked from pipelining */ 385 | CURLOPT(CURLMOPT_PIPELINING_SITE_BL, CURLOPTTYPE_OBJECTPOINT, 11), 386 | 387 | /* a list of server types that are blocked from pipelining */ 388 | CURLOPT(CURLMOPT_PIPELINING_SERVER_BL, CURLOPTTYPE_OBJECTPOINT, 12), 389 | 390 | /* maximum number of open connections in total */ 391 | CURLOPT(CURLMOPT_MAX_TOTAL_CONNECTIONS, CURLOPTTYPE_LONG, 13), 392 | 393 | /* This is the server push callback function pointer */ 394 | CURLOPT(CURLMOPT_PUSHFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 14), 395 | 396 | /* This is the argument passed to the server push callback */ 397 | CURLOPT(CURLMOPT_PUSHDATA, CURLOPTTYPE_OBJECTPOINT, 15), 398 | 399 | /* maximum number of concurrent streams to support on a connection */ 400 | CURLOPT(CURLMOPT_MAX_CONCURRENT_STREAMS, CURLOPTTYPE_LONG, 16), 401 | 402 | CURLMOPT_LASTENTRY /* the last unused */ 403 | } CURLMoption; 404 | 405 | 406 | /* 407 | * Name: curl_multi_setopt() 408 | * 409 | * Desc: Sets options for the multi handle. 410 | * 411 | * Returns: CURLM error code. 412 | */ 413 | CURL_EXTERN CURLMcode curl_multi_setopt(CURLM *multi_handle, 414 | CURLMoption option, ...); 415 | 416 | 417 | /* 418 | * Name: curl_multi_assign() 419 | * 420 | * Desc: This function sets an association in the multi handle between the 421 | * given socket and a private pointer of the application. This is 422 | * (only) useful for curl_multi_socket uses. 423 | * 424 | * Returns: CURLM error code. 425 | */ 426 | CURL_EXTERN CURLMcode curl_multi_assign(CURLM *multi_handle, 427 | curl_socket_t sockfd, void *sockp); 428 | 429 | 430 | /* 431 | * Name: curl_push_callback 432 | * 433 | * Desc: This callback gets called when a new stream is being pushed by the 434 | * server. It approves or denies the new stream. It can also decide 435 | * to completely fail the connection. 436 | * 437 | * Returns: CURL_PUSH_OK, CURL_PUSH_DENY or CURL_PUSH_ERROROUT 438 | */ 439 | #define CURL_PUSH_OK 0 440 | #define CURL_PUSH_DENY 1 441 | #define CURL_PUSH_ERROROUT 2 /* added in 7.72.0 */ 442 | 443 | struct curl_pushheaders; /* forward declaration only */ 444 | 445 | CURL_EXTERN char *curl_pushheader_bynum(struct curl_pushheaders *h, 446 | size_t num); 447 | CURL_EXTERN char *curl_pushheader_byname(struct curl_pushheaders *h, 448 | const char *name); 449 | 450 | typedef int (*curl_push_callback)(CURL *parent, 451 | CURL *easy, 452 | size_t num_headers, 453 | struct curl_pushheaders *headers, 454 | void *userp); 455 | 456 | #ifdef __cplusplus 457 | } /* end of extern "C" */ 458 | #endif 459 | 460 | #endif 461 | -------------------------------------------------------------------------------- /Beacon/Libs/curl.xcframework/ios-arm64/curl.framework/Headers/options.h: -------------------------------------------------------------------------------- 1 | #ifndef CURLINC_OPTIONS_H 2 | #define CURLINC_OPTIONS_H 3 | /*************************************************************************** 4 | * _ _ ____ _ 5 | * Project ___| | | | _ \| | 6 | * / __| | | | |_) | | 7 | * | (__| |_| | _ <| |___ 8 | * \___|\___/|_| \_\_____| 9 | * 10 | * Copyright (C) Daniel Stenberg, , et al. 11 | * 12 | * This software is licensed as described in the file COPYING, which 13 | * you should have received as part of this distribution. The terms 14 | * are also available at https://curl.se/docs/copyright.html. 15 | * 16 | * You may opt to use, copy, modify, merge, publish, distribute and/or sell 17 | * copies of the Software, and permit persons to whom the Software is 18 | * furnished to do so, under the terms of the COPYING file. 19 | * 20 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 21 | * KIND, either express or implied. 22 | * 23 | * SPDX-License-Identifier: curl 24 | * 25 | ***************************************************************************/ 26 | 27 | #ifdef __cplusplus 28 | extern "C" { 29 | #endif 30 | 31 | typedef enum { 32 | CURLOT_LONG, /* long (a range of values) */ 33 | CURLOT_VALUES, /* (a defined set or bitmask) */ 34 | CURLOT_OFF_T, /* curl_off_t (a range of values) */ 35 | CURLOT_OBJECT, /* pointer (void *) */ 36 | CURLOT_STRING, /* (char * to null-terminated buffer) */ 37 | CURLOT_SLIST, /* (struct curl_slist *) */ 38 | CURLOT_CBPTR, /* (void * passed as-is to a callback) */ 39 | CURLOT_BLOB, /* blob (struct curl_blob *) */ 40 | CURLOT_FUNCTION /* function pointer */ 41 | } curl_easytype; 42 | 43 | /* Flag bits */ 44 | 45 | /* "alias" means it is provided for old programs to remain functional, 46 | we prefer another name */ 47 | #define CURLOT_FLAG_ALIAS (1<<0) 48 | 49 | /* The CURLOPTTYPE_* id ranges can still be used to figure out what type/size 50 | to use for curl_easy_setopt() for the given id */ 51 | struct curl_easyoption { 52 | const char *name; 53 | CURLoption id; 54 | curl_easytype type; 55 | unsigned int flags; 56 | }; 57 | 58 | CURL_EXTERN const struct curl_easyoption * 59 | curl_easy_option_by_name(const char *name); 60 | 61 | CURL_EXTERN const struct curl_easyoption * 62 | curl_easy_option_by_id(CURLoption id); 63 | 64 | CURL_EXTERN const struct curl_easyoption * 65 | curl_easy_option_next(const struct curl_easyoption *prev); 66 | 67 | #ifdef __cplusplus 68 | } /* end of extern "C" */ 69 | #endif 70 | #endif /* CURLINC_OPTIONS_H */ 71 | -------------------------------------------------------------------------------- /Beacon/Libs/curl.xcframework/ios-arm64/curl.framework/Headers/stdcheaders.h: -------------------------------------------------------------------------------- 1 | #ifndef CURLINC_STDCHEADERS_H 2 | #define CURLINC_STDCHEADERS_H 3 | /*************************************************************************** 4 | * _ _ ____ _ 5 | * Project ___| | | | _ \| | 6 | * / __| | | | |_) | | 7 | * | (__| |_| | _ <| |___ 8 | * \___|\___/|_| \_\_____| 9 | * 10 | * Copyright (C) Daniel Stenberg, , et al. 11 | * 12 | * This software is licensed as described in the file COPYING, which 13 | * you should have received as part of this distribution. The terms 14 | * are also available at https://curl.se/docs/copyright.html. 15 | * 16 | * You may opt to use, copy, modify, merge, publish, distribute and/or sell 17 | * copies of the Software, and permit persons to whom the Software is 18 | * furnished to do so, under the terms of the COPYING file. 19 | * 20 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 21 | * KIND, either express or implied. 22 | * 23 | * SPDX-License-Identifier: curl 24 | * 25 | ***************************************************************************/ 26 | 27 | #include 28 | 29 | size_t fread(void *, size_t, size_t, FILE *); 30 | size_t fwrite(const void *, size_t, size_t, FILE *); 31 | 32 | int strcasecmp(const char *, const char *); 33 | int strncasecmp(const char *, const char *, size_t); 34 | 35 | #endif /* CURLINC_STDCHEADERS_H */ 36 | -------------------------------------------------------------------------------- /Beacon/Libs/curl.xcframework/ios-arm64/curl.framework/Headers/urlapi.h: -------------------------------------------------------------------------------- 1 | #ifndef CURLINC_URLAPI_H 2 | #define CURLINC_URLAPI_H 3 | /*************************************************************************** 4 | * _ _ ____ _ 5 | * Project ___| | | | _ \| | 6 | * / __| | | | |_) | | 7 | * | (__| |_| | _ <| |___ 8 | * \___|\___/|_| \_\_____| 9 | * 10 | * Copyright (C) Daniel Stenberg, , et al. 11 | * 12 | * This software is licensed as described in the file COPYING, which 13 | * you should have received as part of this distribution. The terms 14 | * are also available at https://curl.se/docs/copyright.html. 15 | * 16 | * You may opt to use, copy, modify, merge, publish, distribute and/or sell 17 | * copies of the Software, and permit persons to whom the Software is 18 | * furnished to do so, under the terms of the COPYING file. 19 | * 20 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 21 | * KIND, either express or implied. 22 | * 23 | * SPDX-License-Identifier: curl 24 | * 25 | ***************************************************************************/ 26 | 27 | #include "curl.h" 28 | 29 | #ifdef __cplusplus 30 | extern "C" { 31 | #endif 32 | 33 | /* the error codes for the URL API */ 34 | typedef enum { 35 | CURLUE_OK, 36 | CURLUE_BAD_HANDLE, /* 1 */ 37 | CURLUE_BAD_PARTPOINTER, /* 2 */ 38 | CURLUE_MALFORMED_INPUT, /* 3 */ 39 | CURLUE_BAD_PORT_NUMBER, /* 4 */ 40 | CURLUE_UNSUPPORTED_SCHEME, /* 5 */ 41 | CURLUE_URLDECODE, /* 6 */ 42 | CURLUE_OUT_OF_MEMORY, /* 7 */ 43 | CURLUE_USER_NOT_ALLOWED, /* 8 */ 44 | CURLUE_UNKNOWN_PART, /* 9 */ 45 | CURLUE_NO_SCHEME, /* 10 */ 46 | CURLUE_NO_USER, /* 11 */ 47 | CURLUE_NO_PASSWORD, /* 12 */ 48 | CURLUE_NO_OPTIONS, /* 13 */ 49 | CURLUE_NO_HOST, /* 14 */ 50 | CURLUE_NO_PORT, /* 15 */ 51 | CURLUE_NO_QUERY, /* 16 */ 52 | CURLUE_NO_FRAGMENT, /* 17 */ 53 | CURLUE_NO_ZONEID, /* 18 */ 54 | CURLUE_BAD_FILE_URL, /* 19 */ 55 | CURLUE_BAD_FRAGMENT, /* 20 */ 56 | CURLUE_BAD_HOSTNAME, /* 21 */ 57 | CURLUE_BAD_IPV6, /* 22 */ 58 | CURLUE_BAD_LOGIN, /* 23 */ 59 | CURLUE_BAD_PASSWORD, /* 24 */ 60 | CURLUE_BAD_PATH, /* 25 */ 61 | CURLUE_BAD_QUERY, /* 26 */ 62 | CURLUE_BAD_SCHEME, /* 27 */ 63 | CURLUE_BAD_SLASHES, /* 28 */ 64 | CURLUE_BAD_USER, /* 29 */ 65 | CURLUE_LACKS_IDN, /* 30 */ 66 | CURLUE_LAST 67 | } CURLUcode; 68 | 69 | typedef enum { 70 | CURLUPART_URL, 71 | CURLUPART_SCHEME, 72 | CURLUPART_USER, 73 | CURLUPART_PASSWORD, 74 | CURLUPART_OPTIONS, 75 | CURLUPART_HOST, 76 | CURLUPART_PORT, 77 | CURLUPART_PATH, 78 | CURLUPART_QUERY, 79 | CURLUPART_FRAGMENT, 80 | CURLUPART_ZONEID /* added in 7.65.0 */ 81 | } CURLUPart; 82 | 83 | #define CURLU_DEFAULT_PORT (1<<0) /* return default port number */ 84 | #define CURLU_NO_DEFAULT_PORT (1<<1) /* act as if no port number was set, 85 | if the port number matches the 86 | default for the scheme */ 87 | #define CURLU_DEFAULT_SCHEME (1<<2) /* return default scheme if 88 | missing */ 89 | #define CURLU_NON_SUPPORT_SCHEME (1<<3) /* allow non-supported scheme */ 90 | #define CURLU_PATH_AS_IS (1<<4) /* leave dot sequences */ 91 | #define CURLU_DISALLOW_USER (1<<5) /* no user+password allowed */ 92 | #define CURLU_URLDECODE (1<<6) /* URL decode on get */ 93 | #define CURLU_URLENCODE (1<<7) /* URL encode on set */ 94 | #define CURLU_APPENDQUERY (1<<8) /* append a form style part */ 95 | #define CURLU_GUESS_SCHEME (1<<9) /* legacy curl-style guessing */ 96 | #define CURLU_NO_AUTHORITY (1<<10) /* Allow empty authority when the 97 | scheme is unknown. */ 98 | #define CURLU_ALLOW_SPACE (1<<11) /* Allow spaces in the URL */ 99 | #define CURLU_PUNYCODE (1<<12) /* get the host name in pynycode */ 100 | 101 | typedef struct Curl_URL CURLU; 102 | 103 | /* 104 | * curl_url() creates a new CURLU handle and returns a pointer to it. 105 | * Must be freed with curl_url_cleanup(). 106 | */ 107 | CURL_EXTERN CURLU *curl_url(void); 108 | 109 | /* 110 | * curl_url_cleanup() frees the CURLU handle and related resources used for 111 | * the URL parsing. It will not free strings previously returned with the URL 112 | * API. 113 | */ 114 | CURL_EXTERN void curl_url_cleanup(CURLU *handle); 115 | 116 | /* 117 | * curl_url_dup() duplicates a CURLU handle and returns a new copy. The new 118 | * handle must also be freed with curl_url_cleanup(). 119 | */ 120 | CURL_EXTERN CURLU *curl_url_dup(const CURLU *in); 121 | 122 | /* 123 | * curl_url_get() extracts a specific part of the URL from a CURLU 124 | * handle. Returns error code. The returned pointer MUST be freed with 125 | * curl_free() afterwards. 126 | */ 127 | CURL_EXTERN CURLUcode curl_url_get(const CURLU *handle, CURLUPart what, 128 | char **part, unsigned int flags); 129 | 130 | /* 131 | * curl_url_set() sets a specific part of the URL in a CURLU handle. Returns 132 | * error code. The passed in string will be copied. Passing a NULL instead of 133 | * a part string, clears that part. 134 | */ 135 | CURL_EXTERN CURLUcode curl_url_set(CURLU *handle, CURLUPart what, 136 | const char *part, unsigned int flags); 137 | 138 | /* 139 | * curl_url_strerror() turns a CURLUcode value into the equivalent human 140 | * readable error string. This is useful for printing meaningful error 141 | * messages. 142 | */ 143 | CURL_EXTERN const char *curl_url_strerror(CURLUcode); 144 | 145 | #ifdef __cplusplus 146 | } /* end of extern "C" */ 147 | #endif 148 | 149 | #endif /* CURLINC_URLAPI_H */ 150 | -------------------------------------------------------------------------------- /Beacon/Libs/curl.xcframework/ios-arm64/curl.framework/Headers/websockets.h: -------------------------------------------------------------------------------- 1 | #ifndef CURLINC_WEBSOCKETS_H 2 | #define CURLINC_WEBSOCKETS_H 3 | /*************************************************************************** 4 | * _ _ ____ _ 5 | * Project ___| | | | _ \| | 6 | * / __| | | | |_) | | 7 | * | (__| |_| | _ <| |___ 8 | * \___|\___/|_| \_\_____| 9 | * 10 | * Copyright (C) Daniel Stenberg, , et al. 11 | * 12 | * This software is licensed as described in the file COPYING, which 13 | * you should have received as part of this distribution. The terms 14 | * are also available at https://curl.se/docs/copyright.html. 15 | * 16 | * You may opt to use, copy, modify, merge, publish, distribute and/or sell 17 | * copies of the Software, and permit persons to whom the Software is 18 | * furnished to do so, under the terms of the COPYING file. 19 | * 20 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 21 | * KIND, either express or implied. 22 | * 23 | * SPDX-License-Identifier: curl 24 | * 25 | ***************************************************************************/ 26 | 27 | #ifdef __cplusplus 28 | extern "C" { 29 | #endif 30 | 31 | struct curl_ws_frame { 32 | int age; /* zero */ 33 | int flags; /* See the CURLWS_* defines */ 34 | curl_off_t offset; /* the offset of this data into the frame */ 35 | curl_off_t bytesleft; /* number of pending bytes left of the payload */ 36 | size_t len; /* size of the current data chunk */ 37 | }; 38 | 39 | /* flag bits */ 40 | #define CURLWS_TEXT (1<<0) 41 | #define CURLWS_BINARY (1<<1) 42 | #define CURLWS_CONT (1<<2) 43 | #define CURLWS_CLOSE (1<<3) 44 | #define CURLWS_PING (1<<4) 45 | #define CURLWS_OFFSET (1<<5) 46 | 47 | /* 48 | * NAME curl_ws_recv() 49 | * 50 | * DESCRIPTION 51 | * 52 | * Receives data from the websocket connection. Use after successful 53 | * curl_easy_perform() with CURLOPT_CONNECT_ONLY option. 54 | */ 55 | CURL_EXTERN CURLcode curl_ws_recv(CURL *curl, void *buffer, size_t buflen, 56 | size_t *recv, 57 | struct curl_ws_frame **metap); 58 | 59 | /* sendflags for curl_ws_send() */ 60 | #define CURLWS_PONG (1<<6) 61 | 62 | /* 63 | * NAME curl_easy_send() 64 | * 65 | * DESCRIPTION 66 | * 67 | * Sends data over the websocket connection. Use after successful 68 | * curl_easy_perform() with CURLOPT_CONNECT_ONLY option. 69 | */ 70 | CURL_EXTERN CURLcode curl_ws_send(CURL *curl, const void *buffer, 71 | size_t buflen, size_t *sent, 72 | curl_off_t framesize, 73 | unsigned int sendflags); 74 | 75 | /* bits for the CURLOPT_WS_OPTIONS bitmask: */ 76 | #define CURLWS_RAW_MODE (1<<0) 77 | 78 | CURL_EXTERN struct curl_ws_frame *curl_ws_meta(CURL *curl); 79 | 80 | #ifdef __cplusplus 81 | } 82 | #endif 83 | 84 | #endif /* CURLINC_WEBSOCKETS_H */ 85 | -------------------------------------------------------------------------------- /Beacon/Libs/curl.xcframework/ios-arm64/curl.framework/curl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/x86y/arrayground/996108fc1d4024570b9cf75fdabec0ea3ba85184/Beacon/Libs/curl.xcframework/ios-arm64/curl.framework/curl -------------------------------------------------------------------------------- /Beacon/Libs/curl.xcframework/ios-arm64_x86_64-simulator/curl.framework/Headers/curlver.h: -------------------------------------------------------------------------------- 1 | #ifndef CURLINC_CURLVER_H 2 | #define CURLINC_CURLVER_H 3 | /*************************************************************************** 4 | * _ _ ____ _ 5 | * Project ___| | | | _ \| | 6 | * / __| | | | |_) | | 7 | * | (__| |_| | _ <| |___ 8 | * \___|\___/|_| \_\_____| 9 | * 10 | * Copyright (C) Daniel Stenberg, , et al. 11 | * 12 | * This software is licensed as described in the file COPYING, which 13 | * you should have received as part of this distribution. The terms 14 | * are also available at https://curl.se/docs/copyright.html. 15 | * 16 | * You may opt to use, copy, modify, merge, publish, distribute and/or sell 17 | * copies of the Software, and permit persons to whom the Software is 18 | * furnished to do so, under the terms of the COPYING file. 19 | * 20 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 21 | * KIND, either express or implied. 22 | * 23 | * SPDX-License-Identifier: curl 24 | * 25 | ***************************************************************************/ 26 | 27 | /* This header file contains nothing but libcurl version info, generated by 28 | a script at release-time. This was made its own header file in 7.11.2 */ 29 | 30 | /* This is the global package copyright */ 31 | #define LIBCURL_COPYRIGHT "Daniel Stenberg, ." 32 | 33 | /* This is the version number of the libcurl package from which this header 34 | file origins: */ 35 | #define LIBCURL_VERSION "8.0.1" 36 | 37 | /* The numeric version number is also available "in parts" by using these 38 | defines: */ 39 | #define LIBCURL_VERSION_MAJOR 8 40 | #define LIBCURL_VERSION_MINOR 0 41 | #define LIBCURL_VERSION_PATCH 1 42 | 43 | /* This is the numeric version of the libcurl version number, meant for easier 44 | parsing and comparisons by programs. The LIBCURL_VERSION_NUM define will 45 | always follow this syntax: 46 | 47 | 0xXXYYZZ 48 | 49 | Where XX, YY and ZZ are the main version, release and patch numbers in 50 | hexadecimal (using 8 bits each). All three numbers are always represented 51 | using two digits. 1.2 would appear as "0x010200" while version 9.11.7 52 | appears as "0x090b07". 53 | 54 | This 6-digit (24 bits) hexadecimal number does not show pre-release number, 55 | and it is always a greater number in a more recent release. It makes 56 | comparisons with greater than and less than work. 57 | 58 | Note: This define is the full hex number and _does not_ use the 59 | CURL_VERSION_BITS() macro since curl's own configure script greps for it 60 | and needs it to contain the full number. 61 | */ 62 | #define LIBCURL_VERSION_NUM 0x080001 63 | 64 | /* 65 | * This is the date and time when the full source package was created. The 66 | * timestamp is not stored in git, as the timestamp is properly set in the 67 | * tarballs by the maketgz script. 68 | * 69 | * The format of the date follows this template: 70 | * 71 | * "2007-11-23" 72 | */ 73 | #define LIBCURL_TIMESTAMP "2023-03-20" 74 | 75 | #define CURL_VERSION_BITS(x,y,z) ((x)<<16|(y)<<8|(z)) 76 | #define CURL_AT_LEAST_VERSION(x,y,z) \ 77 | (LIBCURL_VERSION_NUM >= CURL_VERSION_BITS(x, y, z)) 78 | 79 | #endif /* CURLINC_CURLVER_H */ 80 | -------------------------------------------------------------------------------- /Beacon/Libs/curl.xcframework/ios-arm64_x86_64-simulator/curl.framework/Headers/easy.h: -------------------------------------------------------------------------------- 1 | #ifndef CURLINC_EASY_H 2 | #define CURLINC_EASY_H 3 | /*************************************************************************** 4 | * _ _ ____ _ 5 | * Project ___| | | | _ \| | 6 | * / __| | | | |_) | | 7 | * | (__| |_| | _ <| |___ 8 | * \___|\___/|_| \_\_____| 9 | * 10 | * Copyright (C) Daniel Stenberg, , et al. 11 | * 12 | * This software is licensed as described in the file COPYING, which 13 | * you should have received as part of this distribution. The terms 14 | * are also available at https://curl.se/docs/copyright.html. 15 | * 16 | * You may opt to use, copy, modify, merge, publish, distribute and/or sell 17 | * copies of the Software, and permit persons to whom the Software is 18 | * furnished to do so, under the terms of the COPYING file. 19 | * 20 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 21 | * KIND, either express or implied. 22 | * 23 | * SPDX-License-Identifier: curl 24 | * 25 | ***************************************************************************/ 26 | #ifdef __cplusplus 27 | extern "C" { 28 | #endif 29 | 30 | /* Flag bits in the curl_blob struct: */ 31 | #define CURL_BLOB_COPY 1 /* tell libcurl to copy the data */ 32 | #define CURL_BLOB_NOCOPY 0 /* tell libcurl to NOT copy the data */ 33 | 34 | struct curl_blob { 35 | void *data; 36 | size_t len; 37 | unsigned int flags; /* bit 0 is defined, the rest are reserved and should be 38 | left zeroes */ 39 | }; 40 | 41 | CURL_EXTERN CURL *curl_easy_init(void); 42 | CURL_EXTERN CURLcode curl_easy_setopt(CURL *curl, CURLoption option, ...); 43 | CURL_EXTERN CURLcode curl_easy_perform(CURL *curl); 44 | CURL_EXTERN void curl_easy_cleanup(CURL *curl); 45 | 46 | /* 47 | * NAME curl_easy_getinfo() 48 | * 49 | * DESCRIPTION 50 | * 51 | * Request internal information from the curl session with this function. The 52 | * third argument MUST be a pointer to a long, a pointer to a char * or a 53 | * pointer to a double (as the documentation describes elsewhere). The data 54 | * pointed to will be filled in accordingly and can be relied upon only if the 55 | * function returns CURLE_OK. This function is intended to get used *AFTER* a 56 | * performed transfer, all results from this function are undefined until the 57 | * transfer is completed. 58 | */ 59 | CURL_EXTERN CURLcode curl_easy_getinfo(CURL *curl, CURLINFO info, ...); 60 | 61 | 62 | /* 63 | * NAME curl_easy_duphandle() 64 | * 65 | * DESCRIPTION 66 | * 67 | * Creates a new curl session handle with the same options set for the handle 68 | * passed in. Duplicating a handle could only be a matter of cloning data and 69 | * options, internal state info and things like persistent connections cannot 70 | * be transferred. It is useful in multithreaded applications when you can run 71 | * curl_easy_duphandle() for each new thread to avoid a series of identical 72 | * curl_easy_setopt() invokes in every thread. 73 | */ 74 | CURL_EXTERN CURL *curl_easy_duphandle(CURL *curl); 75 | 76 | /* 77 | * NAME curl_easy_reset() 78 | * 79 | * DESCRIPTION 80 | * 81 | * Re-initializes a CURL handle to the default values. This puts back the 82 | * handle to the same state as it was in when it was just created. 83 | * 84 | * It does keep: live connections, the Session ID cache, the DNS cache and the 85 | * cookies. 86 | */ 87 | CURL_EXTERN void curl_easy_reset(CURL *curl); 88 | 89 | /* 90 | * NAME curl_easy_recv() 91 | * 92 | * DESCRIPTION 93 | * 94 | * Receives data from the connected socket. Use after successful 95 | * curl_easy_perform() with CURLOPT_CONNECT_ONLY option. 96 | */ 97 | CURL_EXTERN CURLcode curl_easy_recv(CURL *curl, void *buffer, size_t buflen, 98 | size_t *n); 99 | 100 | /* 101 | * NAME curl_easy_send() 102 | * 103 | * DESCRIPTION 104 | * 105 | * Sends data over the connected socket. Use after successful 106 | * curl_easy_perform() with CURLOPT_CONNECT_ONLY option. 107 | */ 108 | CURL_EXTERN CURLcode curl_easy_send(CURL *curl, const void *buffer, 109 | size_t buflen, size_t *n); 110 | 111 | 112 | /* 113 | * NAME curl_easy_upkeep() 114 | * 115 | * DESCRIPTION 116 | * 117 | * Performs connection upkeep for the given session handle. 118 | */ 119 | CURL_EXTERN CURLcode curl_easy_upkeep(CURL *curl); 120 | 121 | #ifdef __cplusplus 122 | } /* end of extern "C" */ 123 | #endif 124 | 125 | #endif 126 | -------------------------------------------------------------------------------- /Beacon/Libs/curl.xcframework/ios-arm64_x86_64-simulator/curl.framework/Headers/header.h: -------------------------------------------------------------------------------- 1 | #ifndef CURLINC_HEADER_H 2 | #define CURLINC_HEADER_H 3 | /*************************************************************************** 4 | * _ _ ____ _ 5 | * Project ___| | | | _ \| | 6 | * / __| | | | |_) | | 7 | * | (__| |_| | _ <| |___ 8 | * \___|\___/|_| \_\_____| 9 | * 10 | * Copyright (C) Daniel Stenberg, , et al. 11 | * 12 | * This software is licensed as described in the file COPYING, which 13 | * you should have received as part of this distribution. The terms 14 | * are also available at https://curl.se/docs/copyright.html. 15 | * 16 | * You may opt to use, copy, modify, merge, publish, distribute and/or sell 17 | * copies of the Software, and permit persons to whom the Software is 18 | * furnished to do so, under the terms of the COPYING file. 19 | * 20 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 21 | * KIND, either express or implied. 22 | * 23 | * SPDX-License-Identifier: curl 24 | * 25 | ***************************************************************************/ 26 | 27 | #ifdef __cplusplus 28 | extern "C" { 29 | #endif 30 | 31 | struct curl_header { 32 | char *name; /* this might not use the same case */ 33 | char *value; 34 | size_t amount; /* number of headers using this name */ 35 | size_t index; /* ... of this instance, 0 or higher */ 36 | unsigned int origin; /* see bits below */ 37 | void *anchor; /* handle privately used by libcurl */ 38 | }; 39 | 40 | /* 'origin' bits */ 41 | #define CURLH_HEADER (1<<0) /* plain server header */ 42 | #define CURLH_TRAILER (1<<1) /* trailers */ 43 | #define CURLH_CONNECT (1<<2) /* CONNECT headers */ 44 | #define CURLH_1XX (1<<3) /* 1xx headers */ 45 | #define CURLH_PSEUDO (1<<4) /* pseudo headers */ 46 | 47 | typedef enum { 48 | CURLHE_OK, 49 | CURLHE_BADINDEX, /* header exists but not with this index */ 50 | CURLHE_MISSING, /* no such header exists */ 51 | CURLHE_NOHEADERS, /* no headers at all exist (yet) */ 52 | CURLHE_NOREQUEST, /* no request with this number was used */ 53 | CURLHE_OUT_OF_MEMORY, /* out of memory while processing */ 54 | CURLHE_BAD_ARGUMENT, /* a function argument was not okay */ 55 | CURLHE_NOT_BUILT_IN /* if API was disabled in the build */ 56 | } CURLHcode; 57 | 58 | CURL_EXTERN CURLHcode curl_easy_header(CURL *easy, 59 | const char *name, 60 | size_t index, 61 | unsigned int origin, 62 | int request, 63 | struct curl_header **hout); 64 | 65 | CURL_EXTERN struct curl_header *curl_easy_nextheader(CURL *easy, 66 | unsigned int origin, 67 | int request, 68 | struct curl_header *prev); 69 | 70 | #ifdef __cplusplus 71 | } /* end of extern "C" */ 72 | #endif 73 | 74 | #endif /* CURLINC_HEADER_H */ 75 | -------------------------------------------------------------------------------- /Beacon/Libs/curl.xcframework/ios-arm64_x86_64-simulator/curl.framework/Headers/mprintf.h: -------------------------------------------------------------------------------- 1 | #ifndef CURLINC_MPRINTF_H 2 | #define CURLINC_MPRINTF_H 3 | /*************************************************************************** 4 | * _ _ ____ _ 5 | * Project ___| | | | _ \| | 6 | * / __| | | | |_) | | 7 | * | (__| |_| | _ <| |___ 8 | * \___|\___/|_| \_\_____| 9 | * 10 | * Copyright (C) Daniel Stenberg, , et al. 11 | * 12 | * This software is licensed as described in the file COPYING, which 13 | * you should have received as part of this distribution. The terms 14 | * are also available at https://curl.se/docs/copyright.html. 15 | * 16 | * You may opt to use, copy, modify, merge, publish, distribute and/or sell 17 | * copies of the Software, and permit persons to whom the Software is 18 | * furnished to do so, under the terms of the COPYING file. 19 | * 20 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 21 | * KIND, either express or implied. 22 | * 23 | * SPDX-License-Identifier: curl 24 | * 25 | ***************************************************************************/ 26 | 27 | #include 28 | #include /* needed for FILE */ 29 | #include "curl.h" /* for CURL_EXTERN */ 30 | 31 | #ifdef __cplusplus 32 | extern "C" { 33 | #endif 34 | 35 | CURL_EXTERN int curl_mprintf(const char *format, ...); 36 | CURL_EXTERN int curl_mfprintf(FILE *fd, const char *format, ...); 37 | CURL_EXTERN int curl_msprintf(char *buffer, const char *format, ...); 38 | CURL_EXTERN int curl_msnprintf(char *buffer, size_t maxlength, 39 | const char *format, ...); 40 | CURL_EXTERN int curl_mvprintf(const char *format, va_list args); 41 | CURL_EXTERN int curl_mvfprintf(FILE *fd, const char *format, va_list args); 42 | CURL_EXTERN int curl_mvsprintf(char *buffer, const char *format, va_list args); 43 | CURL_EXTERN int curl_mvsnprintf(char *buffer, size_t maxlength, 44 | const char *format, va_list args); 45 | CURL_EXTERN char *curl_maprintf(const char *format, ...); 46 | CURL_EXTERN char *curl_mvaprintf(const char *format, va_list args); 47 | 48 | #ifdef __cplusplus 49 | } /* end of extern "C" */ 50 | #endif 51 | 52 | #endif /* CURLINC_MPRINTF_H */ 53 | -------------------------------------------------------------------------------- /Beacon/Libs/curl.xcframework/ios-arm64_x86_64-simulator/curl.framework/Headers/options.h: -------------------------------------------------------------------------------- 1 | #ifndef CURLINC_OPTIONS_H 2 | #define CURLINC_OPTIONS_H 3 | /*************************************************************************** 4 | * _ _ ____ _ 5 | * Project ___| | | | _ \| | 6 | * / __| | | | |_) | | 7 | * | (__| |_| | _ <| |___ 8 | * \___|\___/|_| \_\_____| 9 | * 10 | * Copyright (C) Daniel Stenberg, , et al. 11 | * 12 | * This software is licensed as described in the file COPYING, which 13 | * you should have received as part of this distribution. The terms 14 | * are also available at https://curl.se/docs/copyright.html. 15 | * 16 | * You may opt to use, copy, modify, merge, publish, distribute and/or sell 17 | * copies of the Software, and permit persons to whom the Software is 18 | * furnished to do so, under the terms of the COPYING file. 19 | * 20 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 21 | * KIND, either express or implied. 22 | * 23 | * SPDX-License-Identifier: curl 24 | * 25 | ***************************************************************************/ 26 | 27 | #ifdef __cplusplus 28 | extern "C" { 29 | #endif 30 | 31 | typedef enum { 32 | CURLOT_LONG, /* long (a range of values) */ 33 | CURLOT_VALUES, /* (a defined set or bitmask) */ 34 | CURLOT_OFF_T, /* curl_off_t (a range of values) */ 35 | CURLOT_OBJECT, /* pointer (void *) */ 36 | CURLOT_STRING, /* (char * to null-terminated buffer) */ 37 | CURLOT_SLIST, /* (struct curl_slist *) */ 38 | CURLOT_CBPTR, /* (void * passed as-is to a callback) */ 39 | CURLOT_BLOB, /* blob (struct curl_blob *) */ 40 | CURLOT_FUNCTION /* function pointer */ 41 | } curl_easytype; 42 | 43 | /* Flag bits */ 44 | 45 | /* "alias" means it is provided for old programs to remain functional, 46 | we prefer another name */ 47 | #define CURLOT_FLAG_ALIAS (1<<0) 48 | 49 | /* The CURLOPTTYPE_* id ranges can still be used to figure out what type/size 50 | to use for curl_easy_setopt() for the given id */ 51 | struct curl_easyoption { 52 | const char *name; 53 | CURLoption id; 54 | curl_easytype type; 55 | unsigned int flags; 56 | }; 57 | 58 | CURL_EXTERN const struct curl_easyoption * 59 | curl_easy_option_by_name(const char *name); 60 | 61 | CURL_EXTERN const struct curl_easyoption * 62 | curl_easy_option_by_id(CURLoption id); 63 | 64 | CURL_EXTERN const struct curl_easyoption * 65 | curl_easy_option_next(const struct curl_easyoption *prev); 66 | 67 | #ifdef __cplusplus 68 | } /* end of extern "C" */ 69 | #endif 70 | #endif /* CURLINC_OPTIONS_H */ 71 | -------------------------------------------------------------------------------- /Beacon/Libs/curl.xcframework/ios-arm64_x86_64-simulator/curl.framework/Headers/stdcheaders.h: -------------------------------------------------------------------------------- 1 | #ifndef CURLINC_STDCHEADERS_H 2 | #define CURLINC_STDCHEADERS_H 3 | /*************************************************************************** 4 | * _ _ ____ _ 5 | * Project ___| | | | _ \| | 6 | * / __| | | | |_) | | 7 | * | (__| |_| | _ <| |___ 8 | * \___|\___/|_| \_\_____| 9 | * 10 | * Copyright (C) Daniel Stenberg, , et al. 11 | * 12 | * This software is licensed as described in the file COPYING, which 13 | * you should have received as part of this distribution. The terms 14 | * are also available at https://curl.se/docs/copyright.html. 15 | * 16 | * You may opt to use, copy, modify, merge, publish, distribute and/or sell 17 | * copies of the Software, and permit persons to whom the Software is 18 | * furnished to do so, under the terms of the COPYING file. 19 | * 20 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 21 | * KIND, either express or implied. 22 | * 23 | * SPDX-License-Identifier: curl 24 | * 25 | ***************************************************************************/ 26 | 27 | #include 28 | 29 | size_t fread(void *, size_t, size_t, FILE *); 30 | size_t fwrite(const void *, size_t, size_t, FILE *); 31 | 32 | int strcasecmp(const char *, const char *); 33 | int strncasecmp(const char *, const char *, size_t); 34 | 35 | #endif /* CURLINC_STDCHEADERS_H */ 36 | -------------------------------------------------------------------------------- /Beacon/Libs/curl.xcframework/ios-arm64_x86_64-simulator/curl.framework/Headers/urlapi.h: -------------------------------------------------------------------------------- 1 | #ifndef CURLINC_URLAPI_H 2 | #define CURLINC_URLAPI_H 3 | /*************************************************************************** 4 | * _ _ ____ _ 5 | * Project ___| | | | _ \| | 6 | * / __| | | | |_) | | 7 | * | (__| |_| | _ <| |___ 8 | * \___|\___/|_| \_\_____| 9 | * 10 | * Copyright (C) Daniel Stenberg, , et al. 11 | * 12 | * This software is licensed as described in the file COPYING, which 13 | * you should have received as part of this distribution. The terms 14 | * are also available at https://curl.se/docs/copyright.html. 15 | * 16 | * You may opt to use, copy, modify, merge, publish, distribute and/or sell 17 | * copies of the Software, and permit persons to whom the Software is 18 | * furnished to do so, under the terms of the COPYING file. 19 | * 20 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 21 | * KIND, either express or implied. 22 | * 23 | * SPDX-License-Identifier: curl 24 | * 25 | ***************************************************************************/ 26 | 27 | #include "curl.h" 28 | 29 | #ifdef __cplusplus 30 | extern "C" { 31 | #endif 32 | 33 | /* the error codes for the URL API */ 34 | typedef enum { 35 | CURLUE_OK, 36 | CURLUE_BAD_HANDLE, /* 1 */ 37 | CURLUE_BAD_PARTPOINTER, /* 2 */ 38 | CURLUE_MALFORMED_INPUT, /* 3 */ 39 | CURLUE_BAD_PORT_NUMBER, /* 4 */ 40 | CURLUE_UNSUPPORTED_SCHEME, /* 5 */ 41 | CURLUE_URLDECODE, /* 6 */ 42 | CURLUE_OUT_OF_MEMORY, /* 7 */ 43 | CURLUE_USER_NOT_ALLOWED, /* 8 */ 44 | CURLUE_UNKNOWN_PART, /* 9 */ 45 | CURLUE_NO_SCHEME, /* 10 */ 46 | CURLUE_NO_USER, /* 11 */ 47 | CURLUE_NO_PASSWORD, /* 12 */ 48 | CURLUE_NO_OPTIONS, /* 13 */ 49 | CURLUE_NO_HOST, /* 14 */ 50 | CURLUE_NO_PORT, /* 15 */ 51 | CURLUE_NO_QUERY, /* 16 */ 52 | CURLUE_NO_FRAGMENT, /* 17 */ 53 | CURLUE_NO_ZONEID, /* 18 */ 54 | CURLUE_BAD_FILE_URL, /* 19 */ 55 | CURLUE_BAD_FRAGMENT, /* 20 */ 56 | CURLUE_BAD_HOSTNAME, /* 21 */ 57 | CURLUE_BAD_IPV6, /* 22 */ 58 | CURLUE_BAD_LOGIN, /* 23 */ 59 | CURLUE_BAD_PASSWORD, /* 24 */ 60 | CURLUE_BAD_PATH, /* 25 */ 61 | CURLUE_BAD_QUERY, /* 26 */ 62 | CURLUE_BAD_SCHEME, /* 27 */ 63 | CURLUE_BAD_SLASHES, /* 28 */ 64 | CURLUE_BAD_USER, /* 29 */ 65 | CURLUE_LACKS_IDN, /* 30 */ 66 | CURLUE_LAST 67 | } CURLUcode; 68 | 69 | typedef enum { 70 | CURLUPART_URL, 71 | CURLUPART_SCHEME, 72 | CURLUPART_USER, 73 | CURLUPART_PASSWORD, 74 | CURLUPART_OPTIONS, 75 | CURLUPART_HOST, 76 | CURLUPART_PORT, 77 | CURLUPART_PATH, 78 | CURLUPART_QUERY, 79 | CURLUPART_FRAGMENT, 80 | CURLUPART_ZONEID /* added in 7.65.0 */ 81 | } CURLUPart; 82 | 83 | #define CURLU_DEFAULT_PORT (1<<0) /* return default port number */ 84 | #define CURLU_NO_DEFAULT_PORT (1<<1) /* act as if no port number was set, 85 | if the port number matches the 86 | default for the scheme */ 87 | #define CURLU_DEFAULT_SCHEME (1<<2) /* return default scheme if 88 | missing */ 89 | #define CURLU_NON_SUPPORT_SCHEME (1<<3) /* allow non-supported scheme */ 90 | #define CURLU_PATH_AS_IS (1<<4) /* leave dot sequences */ 91 | #define CURLU_DISALLOW_USER (1<<5) /* no user+password allowed */ 92 | #define CURLU_URLDECODE (1<<6) /* URL decode on get */ 93 | #define CURLU_URLENCODE (1<<7) /* URL encode on set */ 94 | #define CURLU_APPENDQUERY (1<<8) /* append a form style part */ 95 | #define CURLU_GUESS_SCHEME (1<<9) /* legacy curl-style guessing */ 96 | #define CURLU_NO_AUTHORITY (1<<10) /* Allow empty authority when the 97 | scheme is unknown. */ 98 | #define CURLU_ALLOW_SPACE (1<<11) /* Allow spaces in the URL */ 99 | #define CURLU_PUNYCODE (1<<12) /* get the host name in pynycode */ 100 | 101 | typedef struct Curl_URL CURLU; 102 | 103 | /* 104 | * curl_url() creates a new CURLU handle and returns a pointer to it. 105 | * Must be freed with curl_url_cleanup(). 106 | */ 107 | CURL_EXTERN CURLU *curl_url(void); 108 | 109 | /* 110 | * curl_url_cleanup() frees the CURLU handle and related resources used for 111 | * the URL parsing. It will not free strings previously returned with the URL 112 | * API. 113 | */ 114 | CURL_EXTERN void curl_url_cleanup(CURLU *handle); 115 | 116 | /* 117 | * curl_url_dup() duplicates a CURLU handle and returns a new copy. The new 118 | * handle must also be freed with curl_url_cleanup(). 119 | */ 120 | CURL_EXTERN CURLU *curl_url_dup(const CURLU *in); 121 | 122 | /* 123 | * curl_url_get() extracts a specific part of the URL from a CURLU 124 | * handle. Returns error code. The returned pointer MUST be freed with 125 | * curl_free() afterwards. 126 | */ 127 | CURL_EXTERN CURLUcode curl_url_get(const CURLU *handle, CURLUPart what, 128 | char **part, unsigned int flags); 129 | 130 | /* 131 | * curl_url_set() sets a specific part of the URL in a CURLU handle. Returns 132 | * error code. The passed in string will be copied. Passing a NULL instead of 133 | * a part string, clears that part. 134 | */ 135 | CURL_EXTERN CURLUcode curl_url_set(CURLU *handle, CURLUPart what, 136 | const char *part, unsigned int flags); 137 | 138 | /* 139 | * curl_url_strerror() turns a CURLUcode value into the equivalent human 140 | * readable error string. This is useful for printing meaningful error 141 | * messages. 142 | */ 143 | CURL_EXTERN const char *curl_url_strerror(CURLUcode); 144 | 145 | #ifdef __cplusplus 146 | } /* end of extern "C" */ 147 | #endif 148 | 149 | #endif /* CURLINC_URLAPI_H */ 150 | -------------------------------------------------------------------------------- /Beacon/Libs/curl.xcframework/ios-arm64_x86_64-simulator/curl.framework/Headers/websockets.h: -------------------------------------------------------------------------------- 1 | #ifndef CURLINC_WEBSOCKETS_H 2 | #define CURLINC_WEBSOCKETS_H 3 | /*************************************************************************** 4 | * _ _ ____ _ 5 | * Project ___| | | | _ \| | 6 | * / __| | | | |_) | | 7 | * | (__| |_| | _ <| |___ 8 | * \___|\___/|_| \_\_____| 9 | * 10 | * Copyright (C) Daniel Stenberg, , et al. 11 | * 12 | * This software is licensed as described in the file COPYING, which 13 | * you should have received as part of this distribution. The terms 14 | * are also available at https://curl.se/docs/copyright.html. 15 | * 16 | * You may opt to use, copy, modify, merge, publish, distribute and/or sell 17 | * copies of the Software, and permit persons to whom the Software is 18 | * furnished to do so, under the terms of the COPYING file. 19 | * 20 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 21 | * KIND, either express or implied. 22 | * 23 | * SPDX-License-Identifier: curl 24 | * 25 | ***************************************************************************/ 26 | 27 | #ifdef __cplusplus 28 | extern "C" { 29 | #endif 30 | 31 | struct curl_ws_frame { 32 | int age; /* zero */ 33 | int flags; /* See the CURLWS_* defines */ 34 | curl_off_t offset; /* the offset of this data into the frame */ 35 | curl_off_t bytesleft; /* number of pending bytes left of the payload */ 36 | size_t len; /* size of the current data chunk */ 37 | }; 38 | 39 | /* flag bits */ 40 | #define CURLWS_TEXT (1<<0) 41 | #define CURLWS_BINARY (1<<1) 42 | #define CURLWS_CONT (1<<2) 43 | #define CURLWS_CLOSE (1<<3) 44 | #define CURLWS_PING (1<<4) 45 | #define CURLWS_OFFSET (1<<5) 46 | 47 | /* 48 | * NAME curl_ws_recv() 49 | * 50 | * DESCRIPTION 51 | * 52 | * Receives data from the websocket connection. Use after successful 53 | * curl_easy_perform() with CURLOPT_CONNECT_ONLY option. 54 | */ 55 | CURL_EXTERN CURLcode curl_ws_recv(CURL *curl, void *buffer, size_t buflen, 56 | size_t *recv, 57 | struct curl_ws_frame **metap); 58 | 59 | /* sendflags for curl_ws_send() */ 60 | #define CURLWS_PONG (1<<6) 61 | 62 | /* 63 | * NAME curl_easy_send() 64 | * 65 | * DESCRIPTION 66 | * 67 | * Sends data over the websocket connection. Use after successful 68 | * curl_easy_perform() with CURLOPT_CONNECT_ONLY option. 69 | */ 70 | CURL_EXTERN CURLcode curl_ws_send(CURL *curl, const void *buffer, 71 | size_t buflen, size_t *sent, 72 | curl_off_t framesize, 73 | unsigned int sendflags); 74 | 75 | /* bits for the CURLOPT_WS_OPTIONS bitmask: */ 76 | #define CURLWS_RAW_MODE (1<<0) 77 | 78 | CURL_EXTERN struct curl_ws_frame *curl_ws_meta(CURL *curl); 79 | 80 | #ifdef __cplusplus 81 | } 82 | #endif 83 | 84 | #endif /* CURLINC_WEBSOCKETS_H */ 85 | -------------------------------------------------------------------------------- /Beacon/Libs/curl.xcframework/ios-arm64_x86_64-simulator/curl.framework/curl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/x86y/arrayground/996108fc1d4024570b9cf75fdabec0ea3ba85184/Beacon/Libs/curl.xcframework/ios-arm64_x86_64-simulator/curl.framework/curl -------------------------------------------------------------------------------- /Beacon/Libs/get_libs.sh: -------------------------------------------------------------------------------- 1 | cd cbqn 2 | 3 | rm -rf build/obj2 4 | SDKROOT=`xcrun --sdk iphonesimulator --show-sdk-path` BQN ./build/src/build.bqn shared o3 FFI=0 5 | ar rcs simbqn.a build/obj2/cbqn-*/*.o 6 | 7 | rm -rf build/obj2 8 | SDKROOT=`xcrun --sdk iphoneos --show-sdk-path` BQN ./build/src/build.bqn shared o3 FFI=0 9 | ar rcs iosbqn.a build/obj2/cbqn-*/*.o 10 | 11 | lipo -create *bqn.a -output libcbqn.a 12 | cd - 13 | -------------------------------------------------------------------------------- /Beacon/Libs/iosbqn.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/x86y/arrayground/996108fc1d4024570b9cf75fdabec0ea3ba85184/Beacon/Libs/iosbqn.a -------------------------------------------------------------------------------- /Beacon/Libs/libcbqn.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/x86y/arrayground/996108fc1d4024570b9cf75fdabec0ea3ba85184/Beacon/Libs/libcbqn.a -------------------------------------------------------------------------------- /Beacon/Libs/libk.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/x86y/arrayground/996108fc1d4024570b9cf75fdabec0ea3ba85184/Beacon/Libs/libk.a -------------------------------------------------------------------------------- /Beacon/Libs/libksim.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/x86y/arrayground/996108fc1d4024570b9cf75fdabec0ea3ba85184/Beacon/Libs/libksim.a -------------------------------------------------------------------------------- /Beacon/Libs/simbqn.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/x86y/arrayground/996108fc1d4024570b9cf75fdabec0ea3ba85184/Beacon/Libs/simbqn.a -------------------------------------------------------------------------------- /Beacon/Models/History.swift: -------------------------------------------------------------------------------- 1 | // 2 | // History.swift 3 | // Arrayground 4 | // 5 | 6 | import Foundation 7 | 8 | let d = UserDefaults.standard 9 | 10 | struct Entry: Hashable, Codable, Identifiable { 11 | var id: String = UUID().uuidString 12 | var src: String 13 | var out: String 14 | var lang: Language 15 | var tokens: [[Token]] 16 | } 17 | 18 | enum Buffers { 19 | static let k = "history" 20 | static func save(_ value: [String: [Entry]]) { 21 | d.set(try? PropertyListEncoder().encode(value), forKey: k) 22 | } 23 | 24 | static func get() -> [String: [Entry]] { 25 | guard let data = d.object(forKey: k) as? Data else { return ["default": []] } 26 | do { 27 | let userData = try PropertyListDecoder().decode([String: [Entry]].self, from: data) 28 | return userData 29 | } catch { 30 | print("Error decoding the history: \(error)") 31 | return ["default": []] 32 | } 33 | } 34 | 35 | static func clear() { 36 | d.removeObject(forKey: k) 37 | } 38 | } 39 | 40 | class HistoryModel: ObservableObject { 41 | @Published var history: [String: [Entry]] = ["default": []] 42 | 43 | func addMessage(with src: String, out: String, lang: Language, for key: String) { 44 | let tokenize = lang == .k 45 | ? tokenize(src, lexK(src)) 46 | : tokenize(src, lexBQN(src)) 47 | let entry = Entry(src: src, out: out, lang: lang, tokens: tokenize) 48 | if var entries = history[key] { 49 | entries.append(entry) 50 | history[key] = entries 51 | } else { 52 | history[key] = [entry] 53 | } 54 | Buffers.save(history) 55 | } 56 | 57 | func load(_ h: [String: [Entry]]) { 58 | history = h 59 | } 60 | 61 | func clear(b: String) { 62 | history[b] = [] 63 | Buffers.clear() 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /Beacon/Preview Content/Preview Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /Beacon/Utilities/Beacon-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | // 2 | // Beacon-Bridging-Header.h 3 | // Arrayground 4 | // 5 | 6 | #ifndef Beacon_Bridging_Header_h 7 | #define Beacon_Bridging_Header_h 8 | 9 | #include "./bqnffi.h" 10 | #include "./k.h" 11 | #endif /* Beacon_Bridging_Header_h */ 12 | -------------------------------------------------------------------------------- /Beacon/Utilities/Lexer.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Lexer.swift 3 | // Arrayground 4 | // 5 | // Lexing adapted from https://github.com/dzaima/paste 6 | 7 | import Foundation 8 | import SwiftUI 9 | 10 | func lexK(_ str: String) -> [String] { 11 | let regC = "0" 12 | let fnsC = "1" 13 | let fns = "+-*%!&|<>=~,^#_?@." 14 | let mopC = "2" 15 | let mop = "/'\\" 16 | let namC = "4" 17 | let nam = "⎕⍞∆⍙ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" 18 | let digC = "5" 19 | let dig = "0123456789¯∞" 20 | let parC = "6" 21 | let dfnC = "7" 22 | let strC = "8" 23 | let dmdC = "D" 24 | let dmd = ":$" 25 | let comC = "C" 26 | let endL = "E" 27 | 28 | var res = Array(repeating: "", count: str.count) 29 | res[0] = regC 30 | 31 | var i = 0 32 | while i < str.count { 33 | let p = charAt(str, i - 1) 34 | let c = charAt(str, i) 35 | let n = charAt(str, i + 1) 36 | 37 | if dig.contains(c) || (c == "." && dig.contains(n)) { 38 | res[i] = digC 39 | while i < str.count, dig.contains(charAt(str, i)) || ".eEnNbiwW".contains(charAt(str, i)) { 40 | i += 1 41 | } 42 | continue 43 | } else if (c == " " && n == "/") || ((p == "\n" || p == "\0") && c == "/") { 44 | res[i] = comC 45 | while i < str.count, charAt(str, i) != "\n" { 46 | i += 1 47 | } 48 | if charAt(str, i) == "\n" { res[i] = endL } 49 | } else if fns.contains(c) || c.unicodeScalars.first!.value >= 0x80 { 50 | res[i] = fnsC 51 | } else if mop.contains(c) { 52 | res[i] = mopC 53 | if n == ":" { 54 | i += 1 55 | res[i] = mopC 56 | } 57 | } else if "{xyz}".contains(c) { 58 | res[i] = dfnC 59 | } else if "([])".contains(c) { 60 | res[i] = parC 61 | } else if dmd.contains(c) { 62 | res[i] = dmdC 63 | } else if nam.contains(c) { 64 | res[i] = namC 65 | while i < str.count, nam.contains(charAt(str, i)) || dig.contains(charAt(str, i)) { 66 | i += 1 67 | } 68 | continue 69 | } else if c == "\"" { 70 | res[i] = strC 71 | i += 1 72 | while charAt(str, i) != "\"", charAt(str, i) != "\n" { 73 | i += charAt(str, i) == "\\" ? 2 : 1 74 | } 75 | } else if !" \t".contains(c) { 76 | res[i] = regC 77 | } 78 | i += 1 79 | } 80 | 81 | return res 82 | } 83 | 84 | func charAt(_ str: String, _ i: Int) -> String { 85 | if i < 0 || i >= str.count { 86 | return "\0" 87 | } 88 | let index = str.index(str.startIndex, offsetBy: i) 89 | return String(str[index]) 90 | } 91 | 92 | func lexBQN(_ code: String) -> [String] { 93 | let regC = "0" 94 | let fnsC = "1" 95 | let fns = "!+-×÷⋆*√⌊⌈∧∨¬|=≠≤<>≥≡≢⊣⊢⥊∾≍⋈↑↓↕⌽⍉/⍋⍒⊏⊑⊐⊒∊⍷⊔«»⍎⍕" 96 | let mopC = "2" 97 | let mop = "`˜˘¨⁼⌜´˝˙" 98 | let dopC = "3" 99 | let dop = "∘⊸⟜○⌾⎉⚇⍟⊘◶⎊" 100 | let namC = "4" 101 | let nam = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_" 102 | let digC = "5" 103 | let dig = "0123456789π∞" 104 | let digS = dig + "¯." 105 | let digM = "eEiI" 106 | let arrC = "6" 107 | let arr = "·⍬‿⦃⦄⟨⟩[]@" 108 | let dfnC = "7" 109 | let dfn = "𝕨𝕩𝔽𝔾𝕎𝕏𝕗𝕘𝕣ℝ𝕤𝕊{}:" 110 | let strC = "8" 111 | let dmdC = "D" 112 | let dmd = "←↩,⋄→⇐" 113 | let comC = "C" 114 | let newL = "E" 115 | 116 | var res = Array(repeating: "", count: code.count) 117 | var i = code.startIndex 118 | 119 | while i < code.endIndex { 120 | let c = code[i] 121 | if digS.contains(c) { 122 | res[i.utf16Offset(in: code)] = digC 123 | i = code.index(after: i) 124 | while dig.contains(code[safe: i] ?? "\0") || code[safe: i] == "." || digM.contains(code[safe: i] ?? "\0") && digS.contains(code[safe: code.index(after: i)] ?? "\0") { 125 | i = code.index(after: i) 126 | } 127 | continue 128 | } else if fns.contains(c) { 129 | res[i.utf16Offset(in: code)] = fnsC 130 | } else if mop.contains(c) { 131 | res[i.utf16Offset(in: code)] = mopC 132 | } else if dop.contains(c) { 133 | res[i.utf16Offset(in: code)] = dopC 134 | } else if dfn.contains(c) { 135 | res[i.utf16Offset(in: code)] = dfnC 136 | } else if arr.contains(c) { 137 | res[i.utf16Offset(in: code)] = arrC 138 | } else if dmd.contains(c) { 139 | res[i.utf16Offset(in: code)] = dmdC 140 | } else if nam.contains(c) || c == "•" { 141 | let fst = i 142 | if code[safe: i] == "•" { 143 | i = code.index(after: i) 144 | } 145 | let cs = code[safe: i] ?? "\0" 146 | while nam.contains(code[safe: i] ?? "\0") || dig.contains(code[safe: i] ?? "\0") { 147 | i = code.index(after: i) 148 | } 149 | let ce = code[safe: code.index(before: i)] ?? "\0" 150 | let offset = fst.utf16Offset(in: code) 151 | if offset < res.count { 152 | res[offset] = cs == "_" ? (ce == "_" ? dopC : mopC) : (cs >= "A" && cs <= "Z" ? fnsC : namC) 153 | } else { 154 | // Handle this case 155 | } 156 | continue 157 | } else if c == "'" || c == "\"" { 158 | res[i.utf16Offset(in: code)] = strC 159 | i = code.index(after: i) 160 | let q = c 161 | while code[safe: i] != nil, code[safe: i] != q, code[safe: i] != "\n" { 162 | i = code.index(after: i) 163 | } 164 | } else if c == "#" { 165 | res[i.utf16Offset(in: code)] = comC 166 | while code[safe: i] != nil, code[safe: i] != "\n" { 167 | i = code.index(after: i) 168 | } 169 | } else if !" \n\t".contains(c) { 170 | res[i.utf16Offset(in: code)] = regC 171 | } 172 | i = code.index(after: i) 173 | } 174 | return res 175 | } 176 | 177 | extension String { 178 | subscript(safe index: Index) -> Character? { 179 | return indices.contains(index) ? self[index] : nil 180 | } 181 | } 182 | -------------------------------------------------------------------------------- /Beacon/Utilities/Tokenizer.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Tokenizer.swift 3 | // Arrayground 4 | // 5 | 6 | import Foundation 7 | import SwiftUI 8 | 9 | func colorBQN(_ type: TokenType) -> Color { 10 | switch type { 11 | case .regC: 12 | return Color.gray // '#D2D2D2' 13 | case .fnsC: 14 | return Color.green // '#32E732' 15 | case .mopC: 16 | return Color.yellow // '#FFF455' 17 | case .namC: 18 | return Color.primary.opacity(0.8) // '#D2D2D2' 19 | case .digC: 20 | return Color.purple // '#FF80F4' 21 | case .parC: 22 | return Color.blue // '#89A7DC' 23 | case .dfnC: 24 | return Color.red // '#E3736D' 25 | case .strC: 26 | return Color.orange // '#DDAAEE' 27 | case .dmdC: 28 | return Color.yellow // '#FFFF00' 29 | case .comC: 30 | return Color.gray // '#898989' 31 | case .endL: 32 | return Color.gray // '#898989' 33 | } 34 | } 35 | 36 | func colorK(_ type: TokenType, _ isDarkTheme: Bool) -> Color { 37 | let colorHex: String 38 | switch type { 39 | case .regC, .namC: 40 | colorHex = isDarkTheme ? "39BAE6" : "000000" 41 | case .comC, .endL: 42 | colorHex = isDarkTheme ? "ACB6BF" : "6A737D" 43 | case .digC: 44 | colorHex = isDarkTheme ? "D2A6FF" : "005CC5" 45 | case .parC: 46 | colorHex = isDarkTheme ? "E6B673" : "000000" 47 | case .dmdC: 48 | colorHex = isDarkTheme ? "FFFF00" : "0000FF" 49 | case .strC: 50 | colorHex = isDarkTheme ? "AAD94C" : "032F62" 51 | case .fnsC: 52 | colorHex = isDarkTheme ? "F29668" : "D73A49" 53 | case .mopC: 54 | colorHex = isDarkTheme ? "39BAE6" : "ED5F00" 55 | case .dfnC: 56 | colorHex = isDarkTheme ? "FFB454" : "A906D4" 57 | } 58 | return Color(hex: colorHex) 59 | } 60 | 61 | extension Color { 62 | init(hex: String) { 63 | let scanner = Scanner(string: hex) 64 | var rgb: UInt64 = 0 65 | scanner.scanHexInt64(&rgb) 66 | let red = Double((rgb & 0xFF0000) >> 16) / 255.0 67 | let green = Double((rgb & 0x00FF00) >> 8) / 255.0 68 | let blue = Double(rgb & 0x0000FF) / 255.0 69 | self.init(red: red, green: green, blue: blue) 70 | } 71 | } 72 | 73 | enum TokenType: String, Codable { 74 | case regC = "0" 75 | case fnsC = "1" 76 | case mopC = "2" 77 | case namC = "4" 78 | case digC = "5" 79 | case parC = "6" 80 | case dfnC = "7" 81 | case strC = "8" 82 | case dmdC = "D" 83 | case comC = "C" 84 | case endL = "E" 85 | } 86 | 87 | struct Token: Hashable, Codable, Identifiable { 88 | var id = UUID() 89 | let value: String 90 | let type: TokenType 91 | } 92 | 93 | func tokenize(_ str: String, _ lexed: [String]) -> [[Token]] { 94 | var tokens: [Token] = [] 95 | var i = 0 96 | 97 | while i < lexed.count { 98 | if let type = TokenType(rawValue: lexed[i]) { 99 | var j = i + 1 100 | while j < lexed.count && lexed[j] == "" { 101 | j += 1 102 | } 103 | let value = str[str.index(str.startIndex, offsetBy: i) ..< str.index(str.startIndex, offsetBy: j)] 104 | tokens.append(Token(value: String(value), type: type)) 105 | i = j 106 | } else { 107 | i += 1 108 | } 109 | } 110 | 111 | var res: [[Token]] = [[]] 112 | var temp: [Token] = [] 113 | for token in tokens { 114 | if token.value == "\n" { 115 | if !temp.isEmpty { 116 | res.append(temp) 117 | } 118 | temp = [] 119 | } else { 120 | temp.append(token) 121 | } 122 | } 123 | 124 | if !temp.isEmpty { 125 | res.append(temp) 126 | } 127 | 128 | return res 129 | } 130 | -------------------------------------------------------------------------------- /Beacon/Utilities/Utils.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Utils.swift 3 | // Arrayground 4 | // 5 | 6 | import Foundation 7 | 8 | func runCmd(_ command: (UnsafePointer) -> Void, _ input: String) -> String { 9 | let output = input.withCString { inp in 10 | let pipe = Pipe() 11 | var output = "" 12 | let sema = DispatchSemaphore(value: 0) 13 | 14 | pipe.fileHandleForReading.readabilityHandler = { fileHandle in 15 | let data = fileHandle.availableData 16 | if data.isEmpty { 17 | fileHandle.readabilityHandler = nil 18 | sema.signal() 19 | } else { 20 | output += String(data: data, encoding: .utf8)! 21 | } 22 | } 23 | setvbuf(stdout, nil, _IONBF, 0) 24 | let savedStdout = dup(STDOUT_FILENO) 25 | dup2(pipe.fileHandleForWriting.fileDescriptor, STDOUT_FILENO) // start redirecting 26 | 27 | command(inp) 28 | 29 | dup2(savedStdout, STDOUT_FILENO) 30 | try! pipe.fileHandleForWriting.close() 31 | close(savedStdout) 32 | sema.wait() 33 | return output 34 | } 35 | return String(output.dropLast()) 36 | } 37 | 38 | func cbqnCmd(_ inp: UnsafePointer) { 39 | let ln = Int32(String(cString: inp).count) 40 | let inp = UnsafeMutablePointer(mutating: inp) 41 | cbqn_runLine(inp, ln) 42 | } 43 | 44 | func kCmd(_ inp: UnsafePointer) { 45 | let a = UnsafeMutablePointer.allocate(capacity: 1) 46 | let b = UnsafeMutablePointer.allocate(capacity: 1) 47 | K0(a, String(cString: inp), b, 0) 48 | a.deallocate() 49 | b.deallocate() 50 | } 51 | 52 | func e(input: String) -> String { 53 | var input = input 54 | if input.contains("•Import ") { 55 | let i = input.split(separator: "•Import ") 56 | let vars = i[0] 57 | let filename = i[1].replacingOccurrences(of: "\"", with: "") 58 | input = "\(vars) •Import \"\(Bundle.main.resourcePath!)/bqn-libs/\(filename)\"" 59 | } 60 | input = input.replacingOccurrences(of: "\"", with: #""""#) 61 | input = "((•ReBQN{repl⇐\"loose\"})⎊{𝕊: •Out \"Error: \"∾•CurrentError@}) \"\(input)\"" 62 | return runCmd(cbqnCmd, input) 63 | } 64 | 65 | func ke(input: String) -> String { 66 | var input = input.replacingOccurrences(of: "\\", with: #"\\"#) 67 | input = input.replacingOccurrences(of: "\"", with: #"\""#) 68 | input = ".[{line `k@.\"\(input)\"};[];{`0:(,\"Error: \"),(-2_\"\n\"\\x)}]" 69 | return runCmd(kCmd, input) 70 | } 71 | 72 | extension String { 73 | func matchingStrings(regex: String) -> [[NSRange]] { 74 | guard let regex = try? NSRegularExpression(pattern: regex, options: []) else { return [] } 75 | let nsString = self as NSString 76 | let results = regex.matches(in: self, options: [], range: NSMakeRange(0, nsString.length)) 77 | return results.map { result in 78 | (0 ..< result.numberOfRanges).map { 79 | result.range(at: $0).location != NSNotFound 80 | ? result.range(at: $0) 81 | : result.range(at: $0) 82 | } 83 | } 84 | } 85 | 86 | func trimmingLastOccurrence(of target: String) -> String { 87 | if let range = range(of: target, options: .backwards) { 88 | return replacingCharacters(in: range, with: "") 89 | } 90 | return self 91 | } 92 | } 93 | 94 | func trimLongText(_ input: String) -> String { 95 | let lines = input.split(separator: "\n", omittingEmptySubsequences: false) 96 | guard lines.count > 7 else { return input } 97 | 98 | let firstThreeLines = lines.prefix(3).joined(separator: "\n") 99 | let lastThreeLines = lines.suffix(3).joined(separator: "\n") 100 | return "\(firstThreeLines)\n...\n\(lastThreeLines)" 101 | } 102 | 103 | func removeLastLine(from string: String) -> String { 104 | guard let range = string.range(of: "\n", options: .backwards) else { 105 | return "" 106 | } 107 | return String(string[.. String { 111 | let allowedChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" 112 | let allowedCharsCount = UInt32(allowedChars.count) 113 | var randomString = "" 114 | 115 | for _ in 0 ..< length { 116 | let randomNum = Int(arc4random_uniform(allowedCharsCount)) 117 | let randomIndex = allowedChars.index(allowedChars.startIndex, offsetBy: randomNum) 118 | let newCharacter = allowedChars[randomIndex] 119 | randomString += String(newCharacter) 120 | } 121 | 122 | return randomString 123 | } 124 | 125 | var glyphs = ["˜", "˘", "¨", "⁼", "⌜", "´", "˝", "∞", "¯", "•", "÷", "×", "¬", "⎉", "⚇", "⍟", "◶", "⊘", "⎊", "⍎", "⍕", "⟨", "⟩", "√", "⋆", "←", "→", "⊣", "⊢", "⋄", "↩", "·", "|", "∾", "≍", "≠", "‿"] 126 | var modules = ["bigint.bqn", "bignat.bqn", "csv.bqn", "datetime.bqn", "hashmap.bqn", "matrix.bqn", "min.bqn", "perlin.bqn", "polynomial.bqn", "primes.bqn", "roots.bqn", "strings.bqn"] 127 | let characterMap: [String: Character] = ["\\`": "˜", "\\1": "˘", "\\2": "¨", "\\3": "⁼", "\\4": "⌜", "\\5": "´", "\\6": "˝", "\\7": "7", "\\8": "∞", "\\9": "¯", "\\0": "•", "\\-": "÷", "\\=": "×", "\\~": "¬", "\\!": "⎉", "\\@": "⚇", "\\#": "⍟", "\\$": "◶", "\\%": "⊘", "\\^": "⎊", "\\&": "⍎", "\\*": "⍕", "\\(": "⟨", "\\)": "⟩", "\\_": "√", "\\+": "⋆", "\\q": "⌽", "\\w": "𝕨", "\\e": "∊", "\\r": "↑", "\\t": "∧", "\\y": "y", "\\u": "⊔", "\\i": "⊏", "\\o": "⊐", "\\p": "π", "\\[": "←", "\\]": "→", "\\Q": "↙", "\\W": "𝕎", "\\E": "⍷", "\\R": "𝕣", "\\T": "⍋", "\\Y": "Y", "\\U": "U", "\\I": "⊑", "\\O": "⊒", "\\P": "⍳", "\\{": "⊣", "\\}": "⊢", "\\a": "⍉", "\\s": "𝕤", "\\d": "↕", "\\f": "𝕗", "\\g": "𝕘", "\\h": "⊸", "\\j": "∘", "\\k": "○", "\\l": "⟜", "\\;": "⋄", "\\'": "↩", "\\A": "↖", "\\S": "𝕊", "\\D": "D", "\\F": "𝔽", "\\G": "𝔾", "\\H": "«", "\\J": "J", "\\K": "⌾", "\\L": "»", "\\:": "·", "\\|": "|", "\\z": "⥊", "\\x": "𝕩", "\\c": "↓", "\\v": "∨", "\\b": "⌊", "\\n": "n", "\\m": "≡", "\\,": "∾", "\\.": "≍", "\\/": "≠", "\\Z": "⋈", "\\X": "𝕏", "\\C": "C", "\\V": "⍒", "\\B": "⌈", "\\N": "N", "\\M": "≢", "\\<": "≤", "\\>": "≥", "\\?": "⇐", "\\ ": "‿"] 128 | -------------------------------------------------------------------------------- /Beacon/Utilities/bqnffi.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | /* 5 | FFI interface for interfacing with BQN implementations 6 | In general, the functions assume the argument(s) are of the expected type (if 7 | applicable), and cause undefined behavior if not 8 | */ 9 | typedef uint64_t BQNV; 10 | 11 | #ifdef __cplusplus 12 | extern "C" { 13 | #endif 14 | 15 | void bqn_init(void); 16 | 17 | void bqn_free(BQNV v); 18 | BQNV bqn_copy(BQNV v); // create a BQNV equivalent in value to `v`, which can be 19 | // freed separately from `v` 20 | 21 | double bqn_toF64(BQNV v); // includes bqn_free(v) 22 | uint32_t bqn_toChar(BQNV v); // includes bqn_free(v) 23 | double bqn_readF64(BQNV v); // doesn't include bqn_free(v) 24 | uint32_t bqn_readChar(BQNV v); // doesn't include bqn_free(v) 25 | void cbqn_runLine(char *ln, int len); 26 | int bqn_type(BQNV v); // equivalent of BQN •Type 27 | 28 | // Invoke BQN function; f can be any BQN object other than modifiers 29 | BQNV bqn_call1(BQNV f, BQNV x); 30 | BQNV bqn_call2(BQNV f, BQNV w, BQNV x); 31 | 32 | // Evaluate BQN code in a fresh environment 33 | BQNV bqn_eval(BQNV src); // src must be a character vector 34 | BQNV bqn_evalCStr( 35 | const char *str); // evaluates the null-terminated UTF8-encoded str; equal 36 | // to `BQNV s = bqn_makeUTF8Str(str, strlen(str)); result 37 | // = bqn_eval(s); bqn_free(s);` 38 | 39 | // Read array data 40 | size_t bqn_bound(BQNV a); // aka product of shape, aka "×´≢a" 41 | size_t bqn_rank(BQNV a); // "=a" 42 | void bqn_shape(BQNV a, size_t *buf); // writes bqn_rank(a) items in buf 43 | BQNV bqn_pick(BQNV a, size_t pos); // pos⊑⥊a 44 | 45 | // Functions for reading all elements of `a` into a pre-allocated buffer (whose 46 | // count must be at least `bqn_bound(a)`). Defined if and only if the input `a` 47 | // consists of elements whose types exactly fit in the wanted type. e.g. 48 | // bqn_readObjArr is always defined (assuming `a` is an array and `buf` isn't 49 | // null and has enough slots) but bqn_readI8Arr is illegal to invoke on 50 | // `⟨1.2,3.4⟩` or `⟨200,201⟩` 51 | void bqn_readI8Arr(BQNV a, int8_t *buf); 52 | void bqn_readI16Arr(BQNV a, int16_t *buf); 53 | void bqn_readI32Arr(BQNV a, int32_t *buf); 54 | void bqn_readF64Arr(BQNV a, double *buf); 55 | void bqn_readC8Arr(BQNV a, uint8_t *buf); 56 | void bqn_readC16Arr(BQNV a, uint16_t *buf); 57 | void bqn_readC32Arr(BQNV a, uint32_t *buf); 58 | void bqn_readObjArr(BQNV a, BQNV *buf); 59 | 60 | bool bqn_hasField( 61 | BQNV ns, 62 | BQNV name); // test if the namespace has the wanted field (result is 63 | // unspecified if `name` isn't lowercase or has underscores) 64 | BQNV bqn_getField( 65 | BQNV ns, BQNV name); // gives the value of the field with the requested 66 | // name. Assumes the field exists in the namespace. 67 | 68 | // Create objects 69 | BQNV bqn_makeF64(double d); 70 | BQNV bqn_makeChar(uint32_t c); 71 | BQNV bqn_makeI8Arr(size_t rank, const size_t *shape, const int8_t *data); 72 | BQNV bqn_makeI16Arr(size_t rank, const size_t *shape, const int16_t *data); 73 | BQNV bqn_makeI32Arr(size_t rank, const size_t *shape, const int32_t *data); 74 | BQNV bqn_makeF64Arr(size_t rank, const size_t *shape, const double *data); 75 | BQNV bqn_makeC8Arr(size_t rank, const size_t *shape, const uint8_t *data); 76 | BQNV bqn_makeC16Arr(size_t rank, const size_t *shape, const uint16_t *data); 77 | BQNV bqn_makeC32Arr(size_t rank, const size_t *shape, const uint32_t *data); 78 | BQNV bqn_makeObjArr(size_t rank, const size_t *shape, 79 | const BQNV *data); // frees the taken elements of data 80 | 81 | BQNV bqn_makeI8Vec(size_t len, const int8_t *data); 82 | BQNV bqn_makeI16Vec(size_t len, const int16_t *data); 83 | BQNV bqn_makeI32Vec(size_t len, const int32_t *data); 84 | BQNV bqn_makeF64Vec(size_t len, const double *data); 85 | BQNV bqn_makeC8Vec(size_t len, const uint8_t *data); 86 | BQNV bqn_makeC16Vec(size_t len, const uint16_t *data); 87 | BQNV bqn_makeC32Vec(size_t len, const uint32_t *data); 88 | BQNV bqn_makeObjVec(size_t len, 89 | const BQNV *data); // frees the taken elements of data 90 | BQNV bqn_makeUTF8Str( 91 | size_t len, 92 | const char *str); // len is the number of chars in str; result item count 93 | // will be lower if str contains non-ASCII characters 94 | 95 | typedef BQNV (*bqn_boundFn1)(BQNV obj, BQNV x); 96 | typedef BQNV (*bqn_boundFn2)(BQNV obj, BQNV w, BQNV x); 97 | 98 | // When the result is called, the first arg given to `f` will be `obj`, and the 99 | // rest will be the corresponding BQN arguments 100 | BQNV bqn_makeBoundFn1(bqn_boundFn1 f, BQNV obj); 101 | BQNV bqn_makeBoundFn2(bqn_boundFn2 f, BQNV obj); 102 | 103 | // Direct (zero copy) array item access 104 | typedef enum { 105 | elt_unk, 106 | elt_i8, 107 | elt_i16, 108 | elt_i32, 109 | elt_f64, 110 | elt_c8, 111 | elt_c16, 112 | elt_c32 113 | } BQNElType; // note that more types may be added in the future 114 | 115 | BQNElType bqn_directArrType(BQNV a); 116 | // A valid implementation of bqn_directArrType would be to always return 117 | // elt_unk, thus disallowing the use of direct access entirely. 118 | 119 | // The functions below can only be used if if bqn_directArrType returns the 120 | // exact equivalent type. Mutating the result, or using it after `a` is freed, 121 | // results in undefined behavior. Doing other FFI invocations between a direct 122 | // access request and the last read from the result is currently allowed in 123 | // CBQN, but that may not be true for an implementation which has a compacting 124 | // garbage collector. 125 | const int8_t *bqn_directI8(BQNV a); 126 | const int16_t *bqn_directI16(BQNV a); 127 | const int32_t *bqn_directI32(BQNV a); 128 | const double *bqn_directF64(BQNV a); 129 | const uint8_t *bqn_directC8(BQNV a); 130 | const uint16_t *bqn_directC16(BQNV a); 131 | const uint32_t *bqn_directC32(BQNV a); 132 | void cbqn_runLine(char *ln, int len); 133 | void repl_init(); 134 | #ifdef __cplusplus 135 | } 136 | #endif 137 | -------------------------------------------------------------------------------- /Beacon/Utilities/k.h: -------------------------------------------------------------------------------- 1 | // 2 | // k.h 3 | // Arrayground 4 | // 5 | 6 | #ifndef k_h 7 | #define k_h 8 | typedef long long K;typedef void V;typedef char C;typedef int I;typedef double F;typedef size_t N;typedef const C*Q; 9 | V kinit(),unref(K),CK(C*,K),IK(I*,K),FK(F*,K),LK(K*,K),*dK(K),KA(Q/*todo*/,K),KR(Q,V*,I);C TK(K),cK(K);N NK(K);I iK(K);F fK(K); 10 | K Kc(C),Ks(C*),Ki(I),Kf(F),KC(C*,N),KS(C**,N),KI(I*,N),KF(F*,N),ref(K),Kp(V*),KE(Q),KL(K*,N),K0(K*,Q,K*,I); 11 | #define Kx(s,a...) ({static K f;K0(&f,s,(K[]){a},sizeof((K[]){a})/sizeof(K));}) 12 | 13 | #endif /* k_h */ 14 | -------------------------------------------------------------------------------- /Beacon/Utilities/stdlib/bigint.bqn: -------------------------------------------------------------------------------- 1 | # Arithmetic on large integers. 2 | 3 | nat ← •args •Import "bignat.bqn" 4 | 5 | Canon ← 0⌾⊑⍟(0=·≠1⊸⊑) 6 | 7 | SubLE ← nat.Sub˜⌾(1⊸⊑) 8 | SubAbs← ≤nat._compare○(1⊸⊑)◶⟨SubLE˜,SubLE⟩ 9 | Add ⇐ Canon ≠○⊑◶⟨nat.Add⌾(1⊸⊑),SubAbs⟩ 10 | 11 | Neg ⇐ ¬⌾⊑⍟(nat.Signum 1⊸⊑) 12 | Abs ⇐ 0⌾⊑ 13 | Sub ⇐ Add⟜Neg 14 | 15 | Mul ⇐ Canon ≠○⊑ ⋈ nat.Mul○(1⊸⊑) 16 | 17 | _compare ⇐ {=○⊑◶⟨𝔽○(¬⊑), ⊑∘⊢◶({𝕏nat._compare○(1⊸⊑)}¨⟨𝔽,𝔽˜⟩)⟩} 18 | 19 | Signum ⇐ ⊑◶⟨nat.Signum 1⊸⊑,¯1⟩ 20 | Conj ⇐ ⊢ 21 | -------------------------------------------------------------------------------- /Beacon/Utilities/stdlib/bignat.bqn: -------------------------------------------------------------------------------- 1 | # Arithmetic on large natural numbers. 2 | 3 | base ← ⊑ •args ∾ 2⋆24 # Less than half 2⋆53 4 | 5 | _while_ ← {𝔽⍟𝔾∘𝔽_𝕣_𝔾∘𝔽⍟𝔾𝕩} 6 | 7 | _extend ← { 𝕨 𝔽○((𝕨⌈○≠𝕩)⊸↑) 𝕩 } 8 | 9 | Trim ← { 𝕩 ↑˜ -⟜1 _while_ (≥◶⟨0,0=-⊑𝕩˙⟩⟜1) ≠𝕩 } 10 | 11 | Carry ← { 12 | c ← 0 13 | r ← {𝕩+↩c⋄c↩⌊𝕩÷base⋄base|𝕩}¨ 𝕩 14 | r‿c 15 | } 16 | 17 | Add ⇐ { 18 | 0⊸<◶⊣‿∾´ Carry 𝕨 +_extend 𝕩 19 | } 20 | 21 | Sub ⇐ { 22 | ! 𝕨 ≥○≠ 𝕩 23 | s‿c ← Carry 𝕨 -_extend 𝕩 24 | ! 0 = c 25 | Trim s 26 | } 27 | 28 | Mul ⇐ { 29 | 0⊸<◶⟨Trim⊣,∾⟩´ Carry (≠⊸↑˜+⊢)⟜(0⊸∾)˝ 𝕨 ×⌜ 𝕩 30 | } 31 | 32 | _compare ⇐ { 33 | Full ← 0⊸≤◶⟨𝔽˜,⊑⟜𝕨𝔽⊑⟜𝕩⟩ · -⟜1 _while_ (0⊸≤◶⟨0,⊑⟜𝕨=⊑⟜𝕩⟩) -⟜1 34 | 𝕨 =◶𝔽‿Full○≠ 𝕩 35 | } 36 | 37 | Neg ⇐ (!0=≠)⊸⊢ 38 | Signum ⇐ ×∘≠ 39 | Abs ⇐ Conj ⇐ ⊢ 40 | -------------------------------------------------------------------------------- /Beacon/Utilities/stdlib/csv.bqn: -------------------------------------------------------------------------------- 1 | # Comma-separated values (.csv) 2 | ⟨ 3 | Split , Join # Convert between plain text and split cells 4 | SplitL, JoinL # Between list of lines and split cells 5 | ⟩⇐ 6 | 7 | # Control characters: double quote, comma, newline 8 | control ← { 9 | 0=≠•args ? ""","∾@+10 ; 10 | ("CSV: •args must consist of 3 values" ! ⟨3⟩≡≢)⊸⊢ ∾⍟(1<≡) •args 11 | } 12 | 13 | # Join by separator 𝕨 14 | J ← ∾1↓·⥊<⊸(≍˘) 15 | 16 | # CSV text to list of list of strings 17 | Split ← { 𝕊⁼𝕩: Join𝕩 ; 18 | [q,c,n] ← control=⌜𝕩 19 | e ← ≠`q # Escaped characters 20 | s ← e»e m -↩ 3 16 | (d-o) +´ ⌊ off +⌾(¯1⊸⊑) dur × (100 DivMod y-f) ∾ ⟨m+12×f⟩ 17 | } 18 | To ⇐ { 𝕊 t: 19 | c‿y‿m ← dur { d‿m ← 𝕨 DivMod 𝕩+t ⋄ t↩⌊m ⋄ d }¨ off 20 | m -↩ 12×10≤m 21 | ⟨(100×c)+y+m<0, 3+m, 1+t⟩ 22 | } 23 | } 24 | 25 | timestamp ← { 26 | d ← 24 × ×˜ m←60 27 | From ⇐ { 28 | (d × date.From 3↑𝕩) + m⊸×⊸+˜´⌽3↓𝕩 29 | } 30 | To ⇐ { 31 | day‿sec ← d DivMod 𝕩 32 | (date.To day) ∾ m|⌊∘÷⟜m⍟(⌽↕3)sec 33 | } 34 | } 35 | 36 | ToTimestamp‿FromTimestamp ← timestamp.To‿timestamp.From 37 | -------------------------------------------------------------------------------- /Beacon/Utilities/stdlib/hashmap.bqn: -------------------------------------------------------------------------------- 1 | # keys HashMap vals: return a mutable hash map h implementing 2 | # h.Count any: return number of keys defined by h 3 | # h.Has key: return 1 if key is present and 0 otherwise 4 | # [default] h.Get key: return corresponding value, default if not found 5 | # key h.Set val: set value (may overwrite); return h 6 | # h.Delete key: remove corresponding value; return h 7 | 8 | # 𝕗_hash is a function returning index in (2⋆n)-length table 9 | ⟨_hash⟩ ← { 10 | base ← 2 ⋆ b←32 11 | _hash ⇐ { bits _𝕣: 12 | ! 1≤bits 13 | d‿m←b(⌈∘÷˜⋈|)bits 14 | mod ← (0⊸× 1+⊢ 29 | table ↩ hlen ⥊ ¯1 30 | } 31 | ST ← {table 𝕨⌾(𝕩⊸⊑)↩⋄@} 32 | Count ⇐ {𝕊:len} 33 | 34 | # Lookup and modify 35 | Find ← { 𝕊 key: 36 | T ← ("Not found!"!¯1⊸≠)⊸⊢ ⊑⟜table 37 | table ⊑˜ Next•_while_(key≢keys⊑˜T) Ind key 38 | } 39 | Get ⇐ { 40 | 𝕊 key: vals ⊑˜ Find key ; 41 | d 𝕊 key: Next•_while_(¯1⊸≠◶⟨0,⊢{d↩𝕨⋄𝕩}⍟(¬⊢)key≢⊑⟜keys⟩⊑⟜table) Ind key ⋄ d 42 | } 43 | tombstone ← {⇐} 44 | Delete ⇐ { 𝕊 key: 45 | keys tombstone⌾((Find key)⊸⊑)↩ 46 | DecLen 1 47 | self 48 | } 49 | Has ⇐ { 𝕊 key: 50 | h←1 ⋄ Next•_while_(¯1⊸≠◶⟨{𝕊:h↩0},key≢⊑⟜keys⟩⊑⟜table) Ind key ⋄ h 51 | } 52 | DefKey ← { 𝕊 key: 53 | Next•_while_(¯1⊸≠◶⟨0,"Duplicate key"!key≢⊑⟜keys⟩⊑⟜table) Ind key 54 | } 55 | Set ⇐ { key 𝕊 val: 56 | New ← {len ST 𝕨 ⋄ keys∾↩‿<){ 16 | ! 2==𝕩 17 | ! ∧´⥊ (𝕩=0) ≥ 𝔽⌜´↕¨≢𝕩 18 | } 19 | Determinant ⇐ ×´Di 20 | # Inverse by recursive blocking 21 | p‿c ← {𝕏˜}¨⍟l ⋈‿≍ 22 | Inverse ⇐ { 23 | 1≥≠𝕩 ? ÷𝕩 ; 24 | l ← ≠𝕩 25 | m ← ⌈l÷2 26 | ai‿di ← Inverse¨ m‿m(↑P↓)𝕩 27 | b ← (m P m-l)↑𝕩 28 | x ← - ai MP b MP di 29 | z ← 0 ⥊˜ (l-m) P m 30 | ∾ (ai P x) C (z P di) 31 | } 32 | # Forward or backward substitution 33 | s←¯1⋆¬l ⋄ j←l-1 ⋄ rev ← l⊑{𝔽⌾⌽}‿{𝔽} 34 | Solve ⇐ { t 𝕊 b: 35 | ! t=○≠b 36 | >{ 37 | new←b÷○(j⊸⊏)𝕩 38 | b↩b-⟜(×⌜⟜new)○(s⊸↓)𝕩 39 | new 40 | }¨∘((s×↕∘≠)↓¨⊢)_rev <˘⍉t 41 | } 42 | } 43 | uTri‿lTri ← LUTri¨ ↕2 44 | 45 | # LU decomposition with pivoting 46 | lup ← { 47 | Compose ⇐ { 𝕊 p‿l‿u: p⊸⊏˘ l MP u } 48 | Verify ⇐ { 𝕊 p‿l‿u: 49 | ! ≤´ m‿n ← ≢u 50 | ! n‿n ≡ ≢l 51 | ! (∧p) ≡ ↕n 52 | uTri.Verify u 53 | lTri.Verify l 54 | ! ∧´ 1 = Di l 55 | } 56 | Inverse ⇐ { 𝕊 p‿l‿u: (⍋p) ⊏ (uTri.Inverse u) MP lTri.Inverse l } 57 | Solve ⇐ { p‿l‿u 𝕊 𝕩: (⍋p) ⊏ u uTri.Solve l lTri.Solve 𝕩 } 58 | Determinant ⇐ { 𝕊 p‿l‿u: 59 | s ← ¯1⋆+´∾(≠↑↑)⊸>p # Sign of permutation 60 | s × uTri.Determinant u 61 | } 62 | 63 | # Recursive method 64 | Decompose ⇐ (0<≠)◶{ ⟨↕¯1⊑≢𝕩 , 0‿0⥊0 , 𝕩⟩ }‿{ LU: 65 | 1 iter+↩1 ? 71 | ¯∞ < ⊑1⊑mins ? 72 | bx ← bounds - ⊑⊑mins 73 | (2×tol) < -⊸⌈´bx ? 74 | 75 | # Compute sign s, distance d, saved distance e 76 | s←@ ⋄ s‿d‿e ↩ { 77 | tol 2×a ? # Movement needs to decrease enough 83 | tol < -⊸⌊´ bx-dn ? # Stay away from bounds 84 | ⟨×dn,a,d⟩ 85 | ; 86 | # Non-interpolation method: golden split of smaller half 87 | a ← | b ← -⊸<´⊸⊑ bx 88 | ⟨×b,phi2×a,a⟩ 89 | } 90 | 91 | x ← ⊑⊑mins 92 | uf ← F u ← x + s×tol⌈d # Move at least tol from x 93 | 94 | i ← 0 < p ← ⊑ (1⊑mins) ⍋ uf # Position of u 95 | bounds ↩ (i⊑x‿u)˙⌾((i=0 iter+↩1 ? 128 | fi ← fp 129 | 130 | # Minimize in each direction successively, and record change in f 131 | df ← { f0←fp ⋄ p‿fp↩Min p‿𝕩 ⋄ f0-fp }¨ dp 132 | 133 | # Relative tolerance 134 | (2×|fi-fp) > tol × fi +○| fp ? 135 | 136 | dt ← p - pt 137 | fe ← Fn pe ← p + dt # Extrapolate 138 | pt ↩ p # Starting point for next dt 139 | 140 | # Now fi → fp → fe are successive values separated by dt 141 | # Consider adding dt to the direction set 142 | # Replace the direction of largest increase to maintain independence 143 | { fe < fi ? 144 | mdf ← ⌈´df # Largest decrease 145 | d2f ← fi+fe - 2×fp # Approximate second derivative wrt dt 146 | (2×d2f × ×˜ (fp+mdf)-fi) < mdf × ×˜ fe-fi ? 147 | p‿fp ↩ Min p‿dt 148 | dp dt⌾((⊑df⊐mdf)⊸⊑)↩ 149 | ;@} 150 | 1;0 151 | }@ 152 | 153 | p‿fp 154 | } 155 | 156 | _powell ← { 157 | tol ← 𝕨⊣1e¯10 158 | step ← ÷4 159 | ltol ← 1e¯4 160 | Powell_sub ⟨𝔽, 𝔽 _linmin {p‿d:𝕩⋄⟨p,step×d,ltol⟩}, 𝕩, tol, 50×≠𝕩⟩ 161 | } 162 | -------------------------------------------------------------------------------- /Beacon/Utilities/stdlib/perlin.bqn: -------------------------------------------------------------------------------- 1 | # Perlin noise generators in 1 and n dimensions 2 | 3 | S ← ט × 3-2⊸× 4 | 5 | Noise1 ← { ⟨bk,g1p⟩𝕊𝕩: 6 | (¬⊸≍ S 1|𝕩) +˝∘× g1p ⊏˜ bk | 0‿1+⌜⌊𝕩 7 | } 8 | 9 | # n-dimensional noise, where n is ≠𝕩 10 | NoiseN ← { ⟨bk,p,g⟩𝕊𝕩: 11 | f‿m ← (⌊⋈1⊸|) 𝕩 ⋄ d←G n←≠𝕩 12 | b ← +⌜⟜(⊏⟜p¨)˝ bk|f+⌜0‿1 13 | a ← (↕n⥊2) m⊸-⊸(+´×)⟜(<⊏¨d˙)¨ b 14 | <⁼ a ¬⊸⋈⊸(+˝×)´ ⌽ S m 15 | } 16 | 17 | # Generate random seeding values 18 | MakeData ← {𝕤 19 | bk ⇐ 16⋆2 20 | Sh ← (2×1+bk)⊸⥊ 21 | Rand ← -⟜¬ •rand.Range⟜0 22 | p ⇐ Sh •rand.Deal bk 23 | gc ← ⟨⟩‿⟨Sh Rand bk⟩ 24 | g1p ⇐ p⊏⊑1⊑gc 25 | GG ← (Sh¨ <˘÷⎉1·<+˝⌾(ט)) ·Rand ⋈⟜bk 26 | G ⇐ { 27 | (≠gc) {gc ∾↩ GG¨ 𝕨+↕𝕩¬𝕨}⍟≤ 𝕩 28 | 𝕩⊑gc 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Beacon/Utilities/stdlib/polynomial.bqn: -------------------------------------------------------------------------------- 1 | ⟨ 2 | Trim, Add, Sub, Mul 3 | Derivative, Integral 4 | Eval, _fn 5 | LaguerreRoots, AberthRoots, WeierstrassRoots 6 | ⟩⇐ 7 | 8 | # Arithmetic for real polynomials 9 | Trim ← (∨`⌾⌽0⊸≠)⊸/ 10 | Add ← +´ ((⌈´≠¨)↑¨⊢)⊘(⌈○≠↑¨⋈) # Like +´⊘+ 11 | Sub ← -´ ⌈○≠ ↑¨ ⋈ 12 | Mul ← +´¨ +⌜○(↕≠) ⊔ ×⌜ 13 | 14 | Derivative ← 1 ↓ ↕∘≠⊸× 15 | Integral ← {𝕊:(<𝕨⊣0)∾𝕩÷1+↕≠𝕩; 𝕊⁼:Derivative𝕩} 16 | 17 | _while_ ← {𝔽⍟𝔾∘𝔽_𝕣_𝔾∘𝔽⍟𝔾𝕩} 18 | 19 | complex ← { 20 | M ⇐ -´∘×⋈+´∘×⟜⌽ 21 | D ⇐ (-⌾(1⊸⊑) ÷ +˝∘(ט)){𝔽⊘(M⟜𝔽)} 22 | A2⇐ +´∘ט 23 | A ⇐ √A2 24 | Sqrt ⇐ { 0a‿b←𝕩 ⋄ -⍟t∘⌽⍟s (÷⟜2⋈b⊸÷) √2×m+|a ; 0‿0 } 25 | _poly ⇐ {+⟜(𝕩⊸M)´𝕗} 26 | _polyd_ ⇐ {(𝕘‿2⥊0) (»+𝕩⊸M˘∘⊢)´ 𝕗} 27 | _polyd_ek_ ⇐ { 28 | ek←0 ⋄ ax←A𝕩 29 | v ← (𝕘‿2⥊0) {ek↩(A⊏𝕩)+ax×ek⋄𝕩}∘(»+𝕩⊸M˘∘⊢)´ 𝕗 30 | v‿ek 31 | } 32 | } 33 | CPoly ← ⋈⟜0⍟(0==)¨ 34 | 35 | # Evaluate polynomial 36 | _fn ← {(CPoly𝕗)complex._poly} 37 | Eval ← {𝕨_fn 𝕩} 38 | 39 | # Analytical solutions to low-order polynomials 40 | exact ← { 41 | M‿D‿Sqrt ← complex 42 | Low ← !∘"Input must have degree at least 1" 43 | Lin ← -∘D´⊢ 44 | Quad ← { 𝕨 𝕊 c‿b‿a: 45 | b ÷↩ ¯2 46 | 0‿0⊸≢◶⟨⋈˜,c⊸D⋈D⟜a⟩ b(0≤+´∘×)◶⟨+,-⟩ Sqrt (M˜b) - a M c 47 | } 48 | _with ⇐ {(4⌊≠∘⊢)◶Low‿Low‿Lin‿Quad‿𝔽} 49 | } 50 | 51 | # Return all complex roots of little-endian polynomial 𝕩, using 52 | # simultaneous root-finding methods 53 | # 𝕨 gives the number of iterations 54 | # Result is a list of real‿imag pairs 55 | _allRoots_ ← { GetStep _𝕣_ deriv: 56 | M‿D‿A2‿_polyd_ek_ ← complex 57 | max_iter ← 100 58 | { 59 | eps ← 𝕨⊣1e¯16 60 | step ← GetStep n ← 1-˜≠𝕩 61 | Poly ← (M¨⟜(D¨¯1⊸⊏)𝕩) _polyd_ek_ deriv 62 | r ← <˘⍉> 1‿0 M⍟(↕n)˜ 4‿9÷10 # Initial roots: 0.4i0.9⋆↕n 63 | i ← 0 64 | ⊢_while_ {𝕤 65 | p‿ek ← Poly r 66 | ∨´ (eps × ×˜ek) ≤ A2 ⊏p ? 67 | r Step˜↩ p 68 | "Failed to converge" ! max_iter > i+↩1 69 | 1;0 70 | }@ 71 | <˘⍉> r 72 | }exact._with {𝕨𝔽CPoly𝕩} 73 | } 74 | ⟨WeierstrassRoots⇐WR, AberthRoots⇐AR⟩ ← { 75 | M‿D ← complex 76 | WR ⇐ { ⊢ - ⊏ ⊸ D ⟜(M˝·⍉(1‿0×⌜=⟜<↕𝕩)+·><⊸-¨) } _allRoots_ 1 77 | AR ⇐ { ⊢ - D˝⊸(⊣D 1‿0+M)⟜(¯1‿0+˝¨(⋈⟜0=⌜˜↕𝕩)D∘+-⌜˜¨) } _allRoots_ 2 78 | } 79 | 80 | # Find a root of the given polynomial with Laguerre's method 81 | _laguerre_ ← {poly _𝕣_ eps root: 82 | M‿D‿A‿A2‿Sqrt‿_polyd_ek_ ← complex 83 | Jump ← (•MakeRand 1).Range∘0 ⋄ jump_i ← 10 84 | 85 | nk2 ← 2 ÷ nrn ← ¬ rn ← ÷ 1-˜≠poly 86 | F ← (CPoly poly) _polyd_ek_ 3 87 | max_iter ← 200 88 | i ← 0 89 | ⊢_while_ {𝕤 90 | i < max_iter ? 91 | ⟨p‿dp‿d2p_h, ek⟩ ← <˘⌾⊑ F root 92 | 0 < a2p ← A2 p ? 93 | crit ← eps × ×˜ek # Square of stopping criterion 94 | stop ← { a2p ≥ crit ? 0 # keep going 95 | ; a2p ≥ 0.01×crit ? 1 # finish this iteration, then stop 96 | ; 2 } # return immediately 97 | 2 > stop ? 98 | dx ← { 99 | # Division by zero: jump in random direction 100 | 0‿0 ≡ dp ? (1 + A root) × (•math.Sin⋈•math.Cos) (2×π) × Jump i ; 101 | # Otherwise, Laguerre step 102 | fac ← p‿d2p_h M¨ ⊑) Sqrt 1‿0 - nk2 × M´ fac 104 | } 105 | (root -↩ dx) ≢ root ? 106 | ¬stop ? 107 | i+↩1 108 | # Randomly reduce length every few steps 109 | { 0=jump_i|i ? root +↩ dx × Jump i÷jump_i ;@} 110 | 1;0 111 | }@ 112 | root 113 | } 114 | 115 | # Find all roots, with linear/quadratic formulas and Laguerre 116 | _laguerreRootsPolish ← { 117 | eps ← 𝕨⊣1e¯16 118 | ⟨M⟩ ← complex 119 | Solve ← { 120 | root ← 𝕩 _laguerre_ eps 0‿0 121 | root <⊸∾ Solve M⟜root⊸+`⌾⌽ 1↓𝕩 122 | } exact._with 123 | {𝕨 _laguerre_ eps¨⌾(1⊸↓) 𝕩}⍟𝕗⟜Solve exact._with CPoly 𝕩 124 | } 125 | LaguerreRoots ← 1 _laguerreRootsPolish 126 | -------------------------------------------------------------------------------- /Beacon/Utilities/stdlib/primes.bqn: -------------------------------------------------------------------------------- 1 | ⟨ 2 | PrimesTo 3 | PrimesIn, SieveSegment 4 | NextPrime, PrevPrime 5 | IsPrime 6 | Pi 7 | NthPrime 8 | Factor, FactorExponents 9 | FactorCounts 10 | Totient 11 | ⟩⇐ 12 | 13 | # Wheel factorization 14 | MakeWheel ← { 15 | len ⇐ ×´primes ⇐ 𝕩 # Primes in wheel and wheel length 16 | mask ⇐ ∧´(len⥊0<↕)¨primes 17 | numc ⇐ ≠ coprime ⇐ /mask 18 | 19 | # Get prime mask on segment [start,end) with prime divisors pd 20 | # Assumes pd doesn't intersect primes, or [start,end) 21 | Sieve ⇐ {pd 𝕊 start‿end: 22 | w←coprime,wn←numc,wl←len 23 | bc‿ep ← wl (⌊∘÷˜ ⋈ w⍋|) (𝕩-1)÷⌜pd 24 | 25 | # Do first partial wheels together 26 | m ← ≠˝bc 27 | U←{⟨r←𝕩-𝕨,(⊒/r)+r/𝕨⟩} #{⟨r←𝕩-𝕨,((↕·⊑¯1⊸↑)+r/𝕨-»)+`r⟩} 28 | fr‿fk ← U⟜((m×wn)⊸⌈)˝ ep 29 | j ← (fr/pd) × (fr/wl×⊏bc) + fk⊏w 30 | 31 | # Then the remainder for each prime spanning multiple wheels 32 | Rem ← {p‿s‿e‿o: # prime, start, end, overflow 33 | pl←p×wl ⋄ pw←start-˜p×w 34 | ⟨⥊(pl×s+↕e-s)+⌜pw, (pl×e)+o↑pw⟩ 35 | } 36 | b ← Rem˘ ⍉>m⊸/¨⟨pd,1+⊏bc,1⊏bc,1⊏ep⟩ 37 | 38 | i ← ∾ ⟨j-start⟩∾⥊b 39 | 0¨⌾(i⊸⊏) (end-start)⥊start⌽mask 40 | } 41 | } 42 | 43 | # Prime state 44 | next ← 11 45 | ⟨Sieve⟩ ← wheel ← MakeWheel 2‿3‿5‿7 46 | wlen ← ≠ wheel.primes 47 | primes ← wheel.primes 48 | Extend ← { 49 | E ← { 50 | next ↩ ⌈ 𝕩 ⌊ ((2⋆24)⊸+ ⌊ ט) old←next 51 | primes ∾↩ old + / (wlen↓primes(⍋↑⊣)√next) Sieve old‿next 52 | 𝕊⍟(next⊸<) 𝕩 53 | } 54 | next E∘(2⊸×⊸⌈)⍟< 𝕩 55 | } 56 | 57 | CheckNum ← "Argument must be a non-negative number" ! (1=•Type)◶⟨0,0⊸≤⟩ 58 | CheckNat ← "Argument must be a natural number" ! (1=•Type)◶⟨0,|∘⌊⊸=⟩ 59 | 60 | PrimesTo ← { 61 | CheckNum 𝕩 62 | Extend 𝕩 63 | primes (⍋↑⊣) 𝕩 64 | } 65 | 66 | _getSegment ← {ind _𝕣: 67 | PRange ← { primes (⊣⊏˜·(⊣+↕∘-˜)´⍋) 𝕩-1 } 68 | sn ← {⊑∘⊢+/∘𝕏}⍟𝕗 sieve 69 | pr ← {-˜´ ↑ ·/⁼𝕏-⊑}⍟(¬𝕗) prange 70 | S ← {pd 𝕊 s‿e: 71 | n ← next⌊e 72 | (PR s‿n) ∾ <´◶⟨⟨⟩,primes⊸SN⟩ n‿e 73 | } 74 | # IsPrime¨⊸(𝕗◶⊣‿/) start(⊣+↕∘-˜)end 75 | {𝕊 start‿end: 76 | CheckNat¨ 𝕩 77 | "Range must be ordered" ! ≤´𝕩 78 | (wlen ↓ PrimesTo √end-1) (next≤start)◶S‿SN 𝕩 79 | } 80 | } 81 | SieveSegment ← 0 _getSegment # IsPrime¨ (⊣+↕∘-˜)´ 82 | PrimesIn ← 1 _getSegment # IsPrime¨⊸/ (⊣+↕∘-˜)´ 83 | 84 | NextPrime ← { (0<≠)◶⟨𝕊1⊑R, ⊑ ⟩ PrimesIn r← 𝕩+1‿65 }⚇0 85 | PrevPrime ← { !2<𝕩 ⋄ (0<≠)◶⟨𝕊0⊑R,¯1⊑⊢⟩ PrimesIn r←1⌈𝕩-64‿0 }⚇0 86 | 87 | IsPrime ← { 88 | CheckNat 𝕩 89 | p ← wheel.primes 90 | c ← 0=p|𝕩 91 | (∨´c)◶⟨(ט¯1⊑p)⊸<◶⟨1⊸≠,MillerRabin⟩, c⊑∘/⟜p⊸=⊢ ⟩ 𝕩 92 | }⚇0 93 | 94 | # Compute n|𝕨×𝕩 in high precision 95 | _modMul ← { n _𝕣: 96 | # Split each argument into two 26-bit numbers, with the remaining 97 | # mantissa bit encoded in the sign of the lower-order part. 98 | q←1+2⋆27 99 | Split ← { h←(q×𝕩)(⊣--)𝕩 ⋄ ⟨𝕩-h,h⟩ } 100 | # The product, and an error relative to precise split multiplication. 101 | Mul ← × (⊣ ⋈ -⊸(+´)) ·⥊×⌜○Split 102 | ((n×<⟜0)⊸+ -⟜n+⊢)´ n | Mul 103 | } 104 | MillerRabin ← { 𝕊 n: 105 | # n = 1 + d×2⋆s 106 | s ← 0 {𝕨 2⊸|◶⟨+⟜1𝕊2⌊∘÷˜⊢,⊣⟩ 𝕩} n-1 107 | d ← (n-1) ÷ 2⋆s 108 | 109 | # Arithmetic mod n 110 | Mul ← n _modMul 111 | Pow ← Mul{𝔽´𝔽˜⍟(/2|⌊∘÷⟜2⍟(↕1+·⌊2⋆⁼⊢)𝕩)𝕨} 112 | 113 | # Miller-Rabin test 114 | MR ← { 115 | 1 =𝕩 ? 𝕨≠s ; 116 | (n-1)=𝕩 ? 0 ; 117 | 𝕨≤1 ? 1 ; 118 | (𝕨-1) 𝕊 Mul˜𝕩 119 | } 120 | C ← { 𝕊a: s MR a Pow d } # Is composite 121 | 0 {𝕨<⟜≠◶⟨1,C∘⊑◶⟨+⟜1⊸𝕊,0⟩⟩𝕩} Witnesses 𝕩 122 | } 123 | 124 | witnesses ← { (1↓𝕨)⊸⍋⌾< ⊑ 𝕩˙ }˝ ⍉∘‿2⥊ ⟨ 125 | 0 , ⟨1948244569546278⟩ 126 | 212321 , 15‿5511855321103177 127 | 624732421 , 15‿7363882082‿992620450144556 128 | 273919523041 , 2‿2570940‿211991001‿3749873356 129 | 47636622961201 , 2‿2570940‿880937‿610386380‿4130785767 130 | 3770579582154547 , 2‿325‿9375‿28178‿450775‿9780504‿1795265022 131 | ⟩ 132 | 133 | # Number of primes less than or equal to 𝕩 134 | Pi ← ((0=≡) ⊑∘⊢⍟⊣ {𝕩 LargePi∘⊣¨⌾((next<𝕩)⊸/) primes⍋𝕩}⌾⥊)∘⌊⚇1 135 | LargePi ← { 136 | # Meissel-Lehmer algorithm 137 | Extend 2×√𝕩 # Need one past √𝕩 138 | a‿b‿c ← primes ⍋ 4‿2‿3 √ 𝕩 139 | 140 | ph ← -´ +´¨ 2⌊∘÷˜1+ (↓⥊𝕩) (⊢∾⟜(0⊸<⊸/)¨·⌽⌊∘÷˜)´ 1↓a↑primes # φ(𝕩,a) 141 | 142 | p ← a↓b↑primes 143 | w ← 𝕩 ÷ p 144 | v ← w ↑˜ ca←c-a 145 | j ← (primes ⍋ √v) - a+↕ca 146 | r ← +´Pi w ∾ (j/v)÷(⊒⊸+/j)⊏p 147 | is ← (b+a-2) × (b¬a) ÷ 2 148 | js ← +´ j × (a+↕≠j)+(j-1)÷2 149 | ph + is + js - r 150 | } 151 | 152 | NthPrime ← {primes≠⊸≤◶⟨⊑˜,NP⟩𝕩}⚇0 153 | NP ← { 154 | a ← 2⌈⌈ (1-˜⋆⁼⍟2(++-⟜2⊸÷)⋆⁼)⊸× 𝕩 # Approximation 155 | d ← 𝕩 - Pi a-1 # Primes remaining 156 | p ← ⋆⁼a # Number→distance multiplier 157 | e ← 8××d-0.5 # Go a few primes further 158 | a { 𝕩 (≥⟜-∧<)⟜≠◶⟨n𝕊⊣-×⊸×⟜≠,⊑⟩ PrimesIn ∧𝕨⋈n←𝕨+⌊p×𝕩+e } d 159 | } 160 | 161 | # Prime factors and exponents 162 | FactorExponents ← { 163 | CheckNat 𝕩 164 | 2⊸⌊◶⟨!∘"Can't factor 0", 2‿0⊸⥊, IsPrime◶⟨FactorTrial, ≍˘⋈⟜1⟩⟩ 𝕩 165 | }⚇0 166 | FactorTrial ← { 𝕊n: 167 | r ← 0‿2⥊0 # Transposed result 168 | Div ← {𝕊p: # Add exponents of p to result 169 | D←0=p|⊢ 170 | e←0 ⋄ n↩{e+↩1⋄𝕊⍟D𝕩÷p}n 171 | r∾↩p‿e 172 | } 173 | Try ← { 174 | 𝕩 ⌊↩ 1+⌊√n 175 | 𝕨<𝕩 ? 176 | Div¨ (0=|⟜n)⊸/ PrimesIn 𝕨‿𝕩 177 | {r∾↩⍉PollardFactors n⋄n↩1⋄𝕩}⍟¬ 𝕩⟜0)⊣)𝕩} 189 | # Return a divisor of n other than 1. Can be n if the algorithm fails. 190 | # c should be in ↕n but not 0 or n-2. 191 | PollardRho ← { c 𝕊 n: 192 | x←ys←y ← 2 193 | q ← 1 194 | Mul ← n _modMul 195 | Adv ← {n-˜⍟≤c+Mul˜𝕩} 196 | NextY ← {𝕤⋄ |x-(y Adv↩)} 197 | g ← { 𝕊 r: 198 | x ↩ y 199 | y Adv⍟r↩ 200 | k ← 0 201 | m ← 100 # Check GCD to see if we can stop every m iterations 202 | FindG ← {𝕤 203 | k0 ← k 204 | k ↩ r ⌊ k+m 205 | ys ↩ y 206 | q Mul⟜NextY⍟(k-k0)↩ 207 | n GCD q 208 | } _while_ {k0. 9 | # Return a value at a distance of at most 𝕨⊣1e¯10 from a root of F. 10 | _ITP ← { 𝕨 F _𝕣 x: 11 | e ← 𝕨⊣1e¯10 # Tolerance 12 | w ← -˜´x # Initial width 13 | c ← 0.8÷w, n0←1 # c←k1×2⋆k2←2 14 | r0← (n0+⌈)⌾(2⋆⁼÷⟜e)w # Expected radius upper bound 15 | ! <○(0⊸<)´ y ← F¨x # Require bracketed and increasing 16 | xi←0 # Result 17 | ⊢_while_ {𝕤 18 | xh‿r ← (+⋈-˜)´x÷2 # Midpoint and radius 19 | xi↩xh ⋄ e○(⌈`(1+↕∘≠)⊸×)⟜¬ isdig 95 | bm ← l/ici 122 | f←l⥊1+0=↕3 123 | M←((+´f)⥊0<↕4) × f⊸/ 124 | a‿b←K64 l 125 | v←a (⌊∘÷˜ «⊸+○M b×|) i 126 | (v⊏b64)∾(3|-l)⥊'=' 127 | } 128 | FromBase64 ← {𝕊⁼𝕩: ToBase64𝕩; 129 | p←64>i←b64⊐𝕩 130 | "Invalid Base64 characters" ! ∧`⊸≡ p 131 | i↑˜↩l←+´p 132 | a‿b←K64 +´f←l⥊0<↕4 133 | @ + (256|a×(«f)/i) + b⌊∘÷˜f/i 134 | } 135 | 136 | # Parse numbers from a string, treating non-numeric characters as 137 | # separators 138 | # Natural numbers recognize digits only 139 | NN ← (>⟜«0⊸≤) / 0(0⊸≤××⟜10⊸+)`⊢ 140 | ToNats ← { NN 10⊸≤⊸(¬⊸×-⊣) 𝕩-'0' } 141 | 142 | # General numbers recognize digits and eE.¯-π∞ (mild extension of BQN) 143 | ToNums ← { 144 | T←⌈`× ⋄ I1T←(1+↕∘≠)⊸T 145 | cd←≠dig←('0'+↕10)∾"π∞" ⋄ val←(↕10)∾π‿1‿¯1 # ∞ as 1 to avoid ∞×0 146 | e‿d‿n‿p‿i←"e.¯π∞"=<𝕩 ⋄ e‿n∨↩"E-"=<𝕩 147 | m←d∨cd>j←dig⊐𝕩 148 | s←d∨c←e∨z←(∧`⌾⌽<»⊸<)zz←¬e∨n∨m 149 | "Negative sign in the middle of a number"! ∧´n≤1»c 150 | "Portion of a number is empty"! ∧´¬(1«s)∧n∨s 151 | "Ill-formed decimal or exponent use"! ∧´(0⊸=∨»⊸<)s/d+2×e 152 | "π and ∞ must occur alone"! ∧´(p∨i)≤1(»∧(p∧«e)∨«)zz∨n>»e 153 | f←(17≥¬(⊢-T)+`)⊸∧g←(«≤(d○I1T¬)⊸∧m # No leading 0s; max 17 digits 154 | vs←1‿¯1⊏˜(r←>⟜»m)/»n # Negate if ¯ 155 | v←vs×NN val⊏˜(¬d)/(cd׬f)⌈j # Numeric values—mantissas and exponents 156 | vm←c/○(1⌾⊑)z # Mask of mantissas in v 157 | dp←vm/f(--»⊸-(<×⊢)⊏⟜(I1T«d)⊸-)○(/>⟜«)g # Decimal position 158 | q←10⋆|ee←dp-˜vm/«v׬vm # Power of 10 159 | q÷˜⌾((0>ee)⊸/)q×⌾((0○≠){𝕩𝔽¨𝔽`𝕨∾¨""<⊸»𝕩}˝ (=⌜⥊¨⊣)⟜⌽ 165 | Levenshtein ← ¯1⊑{𝕨((1⊸+⥊+)○≠(⌊`⊢⌊⊏⊸»∘⊢-0∾1+=⟜𝕩)´⌽∘⊣)𝕩} 166 | -------------------------------------------------------------------------------- /Beacon/Views/BuffersView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BuffersView.swift 3 | // Arrayground 4 | // 5 | 6 | import SwiftUI 7 | 8 | struct BuffersView: View { 9 | @Binding var buffers: [String: [Entry]] 10 | @Binding var sel: String 11 | 12 | var body: some View { 13 | Section { 14 | Text("Buffers") 15 | .font(.system(.body, design: .monospaced, weight: .semibold)) 16 | .padding() 17 | 18 | ScrollView(.vertical) { 19 | VStack(alignment: .leading) { 20 | ForEach(Array(buffers.keys), id: \.self) { b in 21 | Button(action: { 22 | self.sel = b 23 | }) { 24 | HStack { 25 | Text(b) 26 | .font(.system(.body, design: .monospaced)) 27 | .padding() 28 | .background(self.sel == b ? Color.blue.opacity(0.1) : Color.gray.opacity(0.1)) // Change colour if selected 29 | .cornerRadius(8) 30 | Spacer() 31 | Button(action: { 32 | buffers[b] = nil 33 | }) { 34 | Image(systemName: "minus.circle.fill") 35 | .foregroundColor(.red) 36 | } 37 | .padding(.trailing) 38 | } 39 | } 40 | } 41 | }.padding(.horizontal) 42 | HStack { 43 | Spacer() 44 | Button(action: { 45 | sel = genRandBuffer(length: 8) 46 | buffers[sel] = [] 47 | }) { 48 | Image(systemName: "plus.circle.fill") 49 | .foregroundColor(.green) 50 | .font(.system(size: 36)) // Increase the size here 51 | } 52 | .padding(.trailing) 53 | Spacer() 54 | } 55 | } 56 | } 57 | } 58 | } 59 | 60 | // #Preview { 61 | // BuffersView(buffers: ["key1": "value1", "key2": "value2"], sel: .constant("1")) 62 | // } 63 | -------------------------------------------------------------------------------- /Beacon/Views/ConfigView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ConfigView.swift 3 | // Arrayground 4 | // 5 | 6 | import SwiftUI 7 | 8 | enum Appearance: Int { 9 | case system = 0 10 | case light = 1 11 | case dark = 2 12 | } 13 | 14 | enum AppFont: Int { 15 | case bqn386 = 0 16 | case iosevka = 1 17 | case apl = 2 18 | } 19 | 20 | enum Language: Int, Codable { 21 | case bqn = 0 22 | case k = 1 23 | } 24 | 25 | func languageToString(l: Language) -> String { 26 | if l == .bqn { 27 | return "BQN" 28 | } else { 29 | return "K" 30 | } 31 | } 32 | 33 | enum Behavior: Int { 34 | case inlineEdit = 0 35 | case duplicate = 1 36 | } 37 | 38 | struct ConfigView: View { 39 | @AppStorage("scheme") private var scheme: Appearance = .system 40 | @AppStorage("font") private var font: AppFont = .bqn386 41 | @AppStorage("lang") private var lang: Language = .k 42 | @AppStorage("editType") private var editType: Behavior = .duplicate 43 | 44 | var body: some View { 45 | NavigationView { 46 | VStack { 47 | List { 48 | Section { 49 | HStack { 50 | Text("Language") 51 | Picker(selection: $lang) { 52 | Text("BQN") 53 | .tag(Language.bqn) 54 | Text("K") 55 | .tag(Language.k) 56 | } label: { 57 | Text("") 58 | } 59 | .pickerStyle(.menu) 60 | } 61 | } header: { 62 | Text("Language Settings") 63 | }.headerProminence(.increased) 64 | Section { 65 | HStack { 66 | Text("Input Click Behavior") 67 | Picker(selection: $editType) { 68 | Text("Inline edit") 69 | .tag(Behavior.inlineEdit) 70 | Text("Duplicate") 71 | .tag(Behavior.duplicate) 72 | } label: { 73 | Text("") 74 | } 75 | .pickerStyle(.menu) 76 | } 77 | } header: { 78 | Text("App Behavior") 79 | }.headerProminence(.increased) 80 | Section { 81 | HStack { 82 | Text("Colorscheme") 83 | Picker(selection: $scheme) { 84 | Text("System") 85 | .tag(Appearance.system) 86 | Text("Light") 87 | .tag(Appearance.light) 88 | Text("Dark") 89 | .tag(Appearance.dark) 90 | } label: { 91 | Text("") 92 | } 93 | } 94 | .pickerStyle(.menu) 95 | HStack { 96 | Text("Font") 97 | Picker(selection: $font) { 98 | Text("BQN386") 99 | .tag(AppFont.bqn386) 100 | Text("Iosevka") 101 | .tag(AppFont.iosevka) 102 | Text("APL") 103 | .tag(AppFont.apl) 104 | } label: { 105 | Text("") 106 | } 107 | .pickerStyle(.menu) 108 | } 109 | } header: { 110 | Text("Appearances") 111 | }.headerProminence(.increased) 112 | } 113 | } 114 | } 115 | } 116 | } 117 | 118 | #Preview { 119 | ConfigView() 120 | } 121 | -------------------------------------------------------------------------------- /Beacon/Views/ContentView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ContentView.swift 3 | // BQN 4 | // 5 | 6 | import Combine 7 | import CoreSpotlight 8 | import Foundation 9 | import MobileCoreServices 10 | import SwiftUI 11 | import UIKit 12 | 13 | struct ContentView: View { 14 | @State var input: String = "" 15 | @State var ephemerals: [Int: [String]] = [:] 16 | @State var showSettings: Bool = false 17 | @State var showHelp: Bool = false 18 | @State var showBuffers: Bool = false 19 | @State var curBuffer: String = "default" 20 | @State var inpPos: Int = -1 21 | @State var move: (Int) -> Void = { _ in } 22 | @AppStorage("lang") var lang: Language = .bqn 23 | @AppStorage("editType") var editType: Behavior = .inlineEdit 24 | @FocusState var isFocused: Bool 25 | @ObservedObject var viewModel: HistoryModel 26 | 27 | func onMySubmit(input: String) { 28 | switch input { 29 | case "clear": 30 | viewModel.clear(b: curBuffer) 31 | self.input = "" 32 | case _ where input.hasPrefix(#"\,"#): 33 | let components = input.components(separatedBy: " ") 34 | if let lastWord = components.last { 35 | curBuffer = lastWord 36 | } 37 | default: 38 | if !input.isEmpty { 39 | // FIXME, below is a hacky workaround for appstorage not syncing? 40 | let output = UserDefaults.standard.integer(forKey: "lang") == Language.bqn.rawValue 41 | ? e(input: input) 42 | : ke(input: input) 43 | 44 | let attr = CSSearchableItemAttributeSet(contentType: .item) 45 | attr.title = input 46 | attr.contentDescription = output 47 | attr.displayName = input 48 | let uid = UUID().uuidString 49 | let item = CSSearchableItem(uniqueIdentifier: uid, domainIdentifier: "arrscience.beacons", attributeSet: attr) 50 | CSSearchableIndex.default().indexSearchableItems([item]) 51 | 52 | viewModel.addMessage(with: input, out: output, lang: lang, for: curBuffer) 53 | } else { 54 | isFocused = false 55 | } 56 | self.input = "" 57 | } 58 | } 59 | 60 | var body: some View { 61 | ScrollViewReader { scrollView in 62 | VStack { 63 | ScrollView(.vertical) { 64 | VStack(spacing: 12) { 65 | if viewModel.history[curBuffer, default: []].isEmpty { 66 | VStack { 67 | Text("ngn/k, (c) 2019-2023") 68 | .font(Font.custom("BQN386 Unicode", size: 16)) 69 | .foregroundColor(.primary) 70 | Text("dzaima/cbqn, (c) 2019-2023") 71 | .font(Font.custom("BQN386 Unicode", size: 16)) 72 | .foregroundColor(.primary) 73 | } 74 | } else { 75 | ForEach(Array(viewModel.history[curBuffer, default: []].enumerated()), id: \.offset) { index, historyItem in 76 | HistoryView(index: index, historyItem: historyItem, curBuffer: curBuffer, onMySubmit: onMySubmit, input: $input, ephemerals: $ephemerals, editType: $editType, viewModel: viewModel) 77 | }.listRowBackground(Color.clear) 78 | .listRowSeparator(.hidden) 79 | } 80 | }.id("HistoryScrollView") 81 | .onChange(of: viewModel.history) { 82 | withAnimation { 83 | scrollView.scrollTo("HistoryScrollView", anchor: .bottom) 84 | } 85 | } 86 | } 87 | }.padding(EdgeInsets(top: 0, leading: 10, bottom: 0, trailing: 10)) 88 | .padding(.bottom, 5) 89 | 90 | ReplInput(text: $input, 91 | helpOpen: $showHelp, 92 | settingsOpen: $showSettings, 93 | buffersOpen: $showBuffers, 94 | lang: self.lang, onSubmit: { onMySubmit(input: self.input) }, 95 | font: Font.custom("BQN386 Unicode", size: 20)) 96 | .padding(.bottom, 4) 97 | .focused($isFocused) 98 | .onTapGesture { 99 | scrollView.scrollTo("HistoryScrollView", anchor: .bottom) 100 | } 101 | .onReceive(Just(input)) { newV in 102 | if lang == .bqn { 103 | let oldCurPos = self.inpPos 104 | newV.matchingStrings(regex: "\\\\[a-zA-Z0-9]").forEach { NSR in 105 | let range = Range(NSR[0], in: newV)! 106 | if let res = characterMap[String(newV[range])] { 107 | let mod = newV.replacingCharacters(in: range, with: String(res)) 108 | self.input = mod 109 | } 110 | self.move(oldCurPos) 111 | } 112 | } 113 | } 114 | } 115 | .padding(.top, 0.1) 116 | .sheet(isPresented: $showSettings) { 117 | ConfigView() 118 | .presentationDetents([.medium]) 119 | } 120 | .sheet(isPresented: $showHelp) { 121 | HelpView() 122 | .presentationDetents([.large]) 123 | } 124 | .sheet(isPresented: $showBuffers) { 125 | BuffersView(buffers: $viewModel.history, sel: self.$curBuffer) 126 | .presentationDetents([.medium]) 127 | } 128 | .onAppear(perform: initRepl) 129 | } 130 | 131 | func initRepl() { 132 | viewModel.load(Buffers.get()) 133 | kinit() 134 | repl_init() 135 | // below is adapted from https://codeberg.org/ngn/k/src/branch/master/repl.k 136 | let k_formatter = """ 137 | (opn;sem;cls):"(;)" 138 | lines:cols:80 139 | upd:(lines;cols) 140 | lim:{(x<#y)(x#)/y} 141 | dd:{(x<#y)(,[;".."](x-2)#)/y} 142 | fmt:{upd[];$[(::)~x;"";(1<#x)&|/`m`M`A=@x;mMA x;(dd[cols]`k@lim[cols]x),"\n"]} 143 | fmtx:{$[(::)~x;"";`k[x],"\n"]} 144 | mMA:{(P;f;q):((,"!/+(";dct;,")");(("+![";" +(");tbl;")]");(,,"(";lst;,")"))`m`M`A?t:@x 145 | w:cols-#*P;u:w-#q;h:lines-2 146 | x:$[h<(`M=t)+#x;,[;,".."](h-1)#f[w;u;h#x];f[w;u;x]] 147 | ,[;"\n"]@"\n"/@[;-1+#x;,;q]P[!#x],'x} 148 | lst:{[w;u;x](((-1+#x)#w),u)dd'`k'lim[cols]'x} 149 | dct:{[w;u;x]k:(|/#'k)$k:`k'!x;par'(((-1+#x)#w-3),u-3)dd'sem/'+(k;`k'.x)} 150 | tbl:{[w;u;x]h:`k'!x;d:`k''.x;W:(#'h)|/'#''d 151 | r:,$[`S~@!x;dd[w](""opn),(""sem)/;par@dd[w-2]@sem/]W$'h 152 | r,par'dd[w-2]'sem/'+@[W;&~^`i`d?_@'.x;-:]$'} 153 | cell:{$[|/`i`d=@y;-x;x]$z} 154 | par:{opn,x,cls} 155 | line0:{c:{0x07~*-2#*x}{(l;r):x;(1:1;r,,(-2_l))}/(x;());"\n"/(*|c),,*c} 156 | line1:{$[#x;;:0];.[`1:(fmt;fmtx)[" "~*x]@.:;,x;{`0:`err[]}]} 157 | line:line1@line0@ 158 | """ 159 | let _ = runCmd(kCmd, k_formatter) 160 | } 161 | } 162 | -------------------------------------------------------------------------------- /Beacon/Views/DashboardView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // DashboardView.swift 3 | // Arrayground 4 | // 5 | 6 | import Charts 7 | import Combine 8 | import Foundation 9 | import SwiftUI 10 | 11 | struct DataElement: Identifiable, Comparable { 12 | var id = UUID() 13 | let key: String 14 | let value: Int 15 | 16 | static func < (lhs: DataElement, rhs: DataElement) -> Bool { 17 | return lhs.key < rhs.key 18 | } 19 | 20 | static func == (lhs: DataElement, rhs: DataElement) -> Bool { 21 | return lhs.key == rhs.key 22 | } 23 | } 24 | 25 | struct Card: Identifiable, Codable { 26 | let id: UUID 27 | var snippet: String 28 | } 29 | 30 | func parseData(s: String) -> [String: Int] { 31 | if s != "" { 32 | let components = s.components(separatedBy: "!") 33 | let keysString = components[0].trimmingCharacters(in: CharacterSet(charactersIn: "()\"")) 34 | let valuesString = components[1] 35 | let keys = keysString.components(separatedBy: ";") 36 | let values = valuesString.split(separator: " ").map { Int($0) } 37 | assert(keys.count == values.count, "Keys and values count mismatch!") 38 | var dict: [String: Int] = [:] 39 | for (index, key) in keys.enumerated() { 40 | dict[key.replacingOccurrences(of: "\"", with: #""#)] = values[index] 41 | } 42 | return dict 43 | } else { 44 | return [:] 45 | } 46 | } 47 | 48 | class DashboardViewModel: ObservableObject { 49 | @Published var cards: [Card] = [] { 50 | didSet { 51 | let encoder = JSONEncoder() 52 | if let encoded = try? encoder.encode(cards) { 53 | UserDefaults.standard.set(encoded, forKey: "cards") 54 | } 55 | } 56 | } 57 | 58 | func removeCard(at index: Int) { 59 | cards.remove(at: index) 60 | } 61 | 62 | init() { 63 | if let cardsData = UserDefaults.standard.data(forKey: "cards") { 64 | let decoder = JSONDecoder() 65 | if let loadedCards = try? decoder.decode([Card].self, from: cardsData) { 66 | cards = loadedCards 67 | return 68 | } 69 | } 70 | cards = [Card(id: UUID(), snippet: "")] 71 | } 72 | } 73 | 74 | struct Dashboard: View { 75 | @StateObject var viewModel = DashboardViewModel() 76 | var body: some View { 77 | VStack { 78 | Text("Dashboard") 79 | .font(.largeTitle) 80 | .fontWeight(.bold) 81 | .padding(.bottom, 20) 82 | Spacer() 83 | ScrollView(.vertical, showsIndicators: false) { 84 | VStack { 85 | ForEach(viewModel.cards.indices, id: \.self) { index in 86 | CardView(card: $viewModel.cards[index], removeCard: { 87 | viewModel.removeCard(at: index) 88 | }) 89 | .padding(.horizontal) 90 | } 91 | 92 | Button(action: { 93 | viewModel.cards.append(Card(id: UUID(), snippet: "")) 94 | }) { 95 | HStack { Image(systemName: "plus") } 96 | .padding() 97 | .foregroundColor(.white) 98 | .background(Color.blue) 99 | .cornerRadius(10) 100 | } 101 | .padding(.horizontal) 102 | } 103 | } 104 | Spacer() 105 | } 106 | .padding() 107 | } 108 | } 109 | 110 | struct CardView: View { 111 | @Binding var card: Card 112 | let removeCard: () -> Void 113 | @State private var barSelection: String? 114 | @State private var isLoading: Bool = false 115 | @State private var isEditing: Bool = false 116 | @State var output: String = "" 117 | @State var snippet: String = "" 118 | var refreshRate: Double = 60.0 119 | var data: [String: Int] { return parseData(s: output) } 120 | let timer = Timer.publish(every: 15, on: .main, in: .common).autoconnect() 121 | 122 | var body: some View { 123 | VStack { 124 | ZStack { 125 | VStack { 126 | HStack { 127 | Spacer() 128 | Button(action: { self.removeCard() }) { 129 | Image(systemName: "xmark.circle.fill") 130 | .font(.title2) 131 | .foregroundColor(.red) 132 | } 133 | Button(action: { 134 | self.isEditing = true 135 | }) { 136 | Image(systemName: "pencil.circle.fill") 137 | .font(.title2) 138 | .foregroundColor(.green) 139 | } 140 | .padding(.trailing) 141 | } 142 | if self.isEditing || self.card.snippet.isEmpty { 143 | TextEditor(text: $snippet) 144 | .padding(.horizontal) 145 | .navigationTitle("snippet") 146 | .onChange(of: snippet) { 147 | if snippet.suffix(2) == "\n\n" { 148 | self.snippet = self.snippet.trimmingLastOccurrence(of: "\n\n") 149 | self.card.snippet = self.snippet 150 | self.isEditing = false 151 | self.refresh() 152 | } 153 | } 154 | .textFieldStyle(RoundedBorderTextFieldStyle()) 155 | .font(Font.system(.body, design: .monospaced)) 156 | .foregroundColor(.accentColor) // Text color 157 | .frame(width: 350, height: 350) 158 | .border(.yellow) 159 | .padding() 160 | } else { 161 | ZStack { 162 | if isLoading { 163 | ProgressView().frame(width: 350, height: 350) 164 | } 165 | VStack { 166 | VStack { 167 | if !output.contains("Error") && output.contains("!") { // FIXME: need a better check if the output is a dict 168 | Chart { 169 | ForEach(data.map { DataElement(key: $0.key, value: $0.value) }.sorted()) { item in 170 | BarMark( 171 | x: .value("Key", item.key), 172 | y: .value("Count", item.value) 173 | ) 174 | .cornerRadius(8) 175 | .foregroundStyle(by: .value("Result Color", item.key)) 176 | } 177 | if let barSelection { 178 | RuleMark(x: .value("Key", barSelection)) 179 | .foregroundStyle(.gray.opacity(0.35)) 180 | .zIndex(-10) 181 | .offset(yStart: -15) 182 | .annotation( 183 | position: .top, 184 | spacing: 0, 185 | overflowResolution: .init(x: .disabled, y: .disabled) 186 | ) { 187 | ChartPopOverView(xval: barSelection, yval: data[barSelection] ?? 0) 188 | } 189 | } 190 | } 191 | .chartXSelection(value: $barSelection) 192 | .chartLegend(position: .bottom, alignment: .leading, spacing: 25) 193 | .padding(.all, 15) 194 | .chartYAxis { 195 | AxisMarks(position: .leading) { _ in 196 | AxisValueLabel() 197 | } 198 | } 199 | .chartXAxis { 200 | AxisMarks(position: .bottom) { _ in 201 | AxisValueLabel() 202 | } 203 | } 204 | } else { 205 | Text(output) 206 | .font(.body) 207 | .padding() 208 | Spacer() 209 | } 210 | /* 211 | ProgressView(value: updater.timeRemaining, total: updater.refreshRate) 212 | .accentColor(.green) 213 | .frame(height: 8.0) 214 | .scaleEffect(x: 1, y: 2, anchor: .center) 215 | */ 216 | } 217 | .frame(width: 350, height: 350) 218 | } 219 | } 220 | // .border(.blue) 221 | } 222 | } 223 | .padding() 224 | } 225 | }.onAppear(perform: { 226 | self.snippet = card.snippet 227 | refresh() 228 | }).onReceive(timer) { _ in 229 | refresh() 230 | } 231 | } 232 | 233 | func refresh() { 234 | if !isEditing { 235 | Task.init { 236 | self.isLoading = true 237 | let snippets = snippet.split(separator: "\n") 238 | for snippet in snippets { 239 | let to = UserDefaults.standard.integer(forKey: "lang") == Language.bqn.rawValue 240 | ? e(input: String(snippet)) 241 | : ke(input: String(snippet)) 242 | if snippet == snippets.last { 243 | self.output = to 244 | } 245 | } 246 | self.isLoading = false 247 | } 248 | } 249 | } 250 | 251 | @ViewBuilder 252 | func ChartPopOverView(xval: String, yval: Int) -> some View { 253 | VStack(alignment: .leading, spacing: 6) { 254 | HStack(spacing: 4) { 255 | Text(String(yval)) 256 | .font(.title3) 257 | Text(xval) 258 | .font(.title3) 259 | .textScale(.secondary) 260 | } 261 | } 262 | .padding() 263 | .background(.cyan, in: .rect(cornerRadius: 8)) 264 | } 265 | } 266 | -------------------------------------------------------------------------------- /Beacon/Views/HelpView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // HelpView.swift 3 | // Arrayground 4 | // 5 | 6 | import Foundation 7 | import SwiftUI 8 | 9 | func toDict(h: String) -> [String: String] { 10 | var helpDict: [String: String] = [:] 11 | let components = h.components(separatedBy: "--------------------------------------------------------------------------------") 12 | for component in components.dropFirst() { 13 | let lines = component.components(separatedBy: "\n") 14 | let key = String(lines[1]) 15 | let value = lines[2...].joined(separator: "\n") 16 | helpDict[key] = value 17 | } 18 | return helpDict 19 | } 20 | 21 | // taken from ngn/k/repl.k 22 | let kh: String = """ 23 | -------------------------------------------------------------------------------- 24 | General 25 | Types: 26 | list atom 27 | `A generic list () ,"ab" (0;`1;"2";{3};%) 28 | `I `i int 0N -9223372036854775807 01b 29 | `F `f float -0w -0.0 0.0 0w 1.2e308 0n 30 | `C `c char "a" 0x6263 "d\\0\\"\\n\\r\\t" 31 | `S `s symbol ` `a `"file.txt" `b`cd`"ef" 32 | `M `m table&dict +`a`b!(0 1;"23") (0#`)!() 33 | `o lambda {1+x*y#z} {[a;b]+/*/2#,a,b} 34 | `p projection 1+ {z}[0;1] @[;i;;] 35 | `q composition *|: {1+x*y}@ 36 | `r derived verb +/ 2\\ {y,x}': 37 | `u monadic verb +: 0:: 38 | `v dyadic verb + 0: 39 | `w adverb ' /: 40 | `x external func 41 | -------------------------------------------------------------------------------- 42 | IO 43 | I/O verbs 44 | 0:x read lines 45 | x 0:y write lines 46 | 1:x read bytes 47 | x 1:y write bytes 48 | i close >fd 50 | 51 | x can be a file descriptor (int) or symbol or string such as 52 | "file.txt" 53 | "/path/to/file" 54 | "host:port" 55 | ":port" /host defaults to 127.0.0.1 56 | -------------------------------------------------------------------------------- 57 | Primitives 58 | Verbs: : + - * % ! & | < > = ~ , ^ # _ $ ? @ . 0: 1: 59 | notation: [c]har [i]nt [n]umber(int|float|char) [s]ymbol [a]tom [d]ict 60 | [f]unc(monad) [F]unc(dyad) [xyz]any 61 | special: var:y set a:1;a -> 1 62 | var::y global a:1;{a::2}[];a -> 2 63 | (v;..):y unpack (b;(c;d)):(2 3;4 5);c -> 4 64 | :x return {:x+1;2}[3] -> 4 65 | :[x;y;..] cond :[0;`a;"\\0";`b;`;`c;();`d;`e] -> `e 66 | o[..] recur {:[x<2;x;+/o'x-1 2]}9 -> 34 67 | [..] progn [0;1;2;3] -> 3 68 | 69 | :: self f:(::);f 12 -> 12 70 | : right f:(:);f[1;2] -> 2 "abc":'"d" -> "ddd" 71 | +x flip +("ab";"cd") -> ("ac";"bd") 72 | N+N add 1 2+3 -> 4 5 73 | -N negate - 1 2 -> -1 -2 74 | N-N subtract 1-2 3 -> -1 -2 75 | *x first *`a`b -> `a *(0 1;"cd") -> 0 1 76 | N*N multiply 1 2*3 4 -> 3 8 77 | %N sqrt %25 -> 5.0 %-1 -> 0n 78 | N%N divide 2 3%4 -> 0.5 0.75 79 | !i enum !3 -> 0 1 2 !-3 -> -3 -2 -1 80 | !I odometer !2 3 -> (0 0 0 1 1 1;0 1 2 0 1 2) 81 | !d keys !`a`b!0 1 -> `a`b 82 | !S ns keys a.b.c:1;a.b.d:2;!`a`b -> `c`d 83 | x!y dict `a`b!1 2 -> `a`b!1 2 84 | i!I div -10!1234 567 -> 123 56 85 | i!I mod 10!1234 567 -> 4 7 86 | &I where &3 -> 0 0 0 &1 0 1 4 2 -> 0 2 3 3 3 3 4 4 87 | &x deepwhere &(0 1 0;1 0 0;1 1 1) -> (0 1 2 2 2;1 0 0 1 2) 88 | N&N min/and 2&-1 3 -> -1 2 0 0 1 1&0 1 0 1 -> 0 0 0 1 89 | |x reverse |"abc" -> "cba" |12 -> 12 90 | N|N max/or 2|-1 3 -> 2 3 0 0 1 1|0 1 0 1 -> 0 1 1 1 91 | 0 2 1 3 5 4 92 | >X descend >"abacus" -> 4 5 3 1 0 2 93 | i close >fd 95 | N 1 0 96 | N>N more 0 1>0 2 -> 0 0 97 | =X group ="abracadabra" -> "abrcd"!(0 3 5 7 10;1 8;2 9;,4;,6) 98 | =i unitmat =3 -> (1 0 0;0 1 0;0 0 1) 99 | N=N equal 0 1 2=0 1 3 -> 1 1 0 100 | ~x not ~(0 2;``a;"a \\0";::;{}) -> (1 0;1 0;0 0 1;1;0) 101 | x~y match 2 3~2 3 -> 1 "4"~4 -> 0 0~0.0 -> 0 102 | ,x enlist ,0 -> ,0 ,0 1 -> ,0 1 ,`a!1 -> +(,`a)!,,1 103 | x,y concat 0,1 2 -> 0 1 2 "a",1 -> ("a";1) 104 | d,d merge (`a`b!0 1),`b`c!2 3 -> `a`b`c!0 2 3 105 | ^x null ^(" a";0 1 0N;``a;0.0 0n) -> (1 0;0 0 1;1 0;0 1) 106 | a^y fill 1^0 0N 2 3 0N -> 0 1 2 3 1 "b"^" " -> "b" 107 | X^y without "abracadabra"^"bc" -> "araadara" 108 | #x length #"abc" -> 3 #4 -> 1 #`a`b`c!0 1 0 -> 3 109 | i#y take 5#"abc" -> "abcab" -5#`a`b`c -> `b`c`a`b`c 110 | X#d take keys `c`d`f#`a`b`c`d!1 2 3 4 -> `c`d`f!3 4 0N 111 | I#y reshape 2 3#` -> (```;```) 112 | f#y replicate (3>#:')#(0;2 1 3;5 4) -> (0;5 4) {2}#"ab" -> "aabb" 113 | _n floor _12.34 -12.34 -> 12 -13 114 | _c lowercase _"Ab" -> "ab" 115 | i_Y drop 2_"abcde" -> "cde" -2_`a`b`c -> ,`a 116 | X_d drop keys `a`c_`a`b`c!0 1 2 -> (,`b)!,1 117 | I_Y cut 2 4 4_"abcde" -> ("cd";"";,"e") 118 | f_Y weed out (3>#:')_(0;2 1 3;5 4) -> ,2 1 3 119 | X_i delete "abcde"_2 -> "abde" 120 | $x string $(12;"ab";`cd;+) -> ("12";(,"a";,"b");"cd";,"+") 121 | i$C pad 5$"abc" -> "abc " -3$"a" -> " a" 122 | s$y cast `c$97 -> "a" `i$-1.2 -> -1 `$"a" -> `a 123 | s$y int `I$"-12" -> -12 124 | ?X distinct ?"abacus" -> "abcus" 125 | ?i uniform ?2 -> 0.6438163747387873 0.8852656305774402 /random 126 | X?y find "abcde"?"bfe" -> 1 0N 4 127 | i?x roll 3?1000 -> 11 398 293 1?0 -> ,-8164324247243690787 128 | i?x deal -3?1000 -> 11 398 293 /guaranteed distinct 129 | @x type @1 -> `i @"ab" -> `C @() -> `A @(@) -> `v 130 | x@y apply(1) {x+1}@2 -> 3 "abc"@1 -> "b" (`a`b!0 1)@`b -> 1 131 | .S get a:1;.`a -> 1 b.c:2;.`b`c -> 2 132 | .C eval ."1+2" -> 3 133 | .d values .`a`b!0 1 -> 0 1 134 | x.y apply(n) {x*y+1}. 2 3 -> 8 (`a`b`c;`d`e`f). 1 0 -> `d 135 | 136 | @[x;y;f] amend @["ABC";1;_:] -> "AbC" @[2 3;1;{-x}] -> 2 -3 137 | @[x;y;F;z] amend @["abc";1;:;"x"] -> "axc" @[2 3;0;+;4] -> 6 3 138 | .[x;y;f] drill .[("AB";"CD");1 0;_:] -> ("AB";"cD") 139 | .[x;y;F;z] drill .[("ab";"cd");1 0;:;"x"] -> ("ab";"xd") 140 | .[f;y;f] try .[+;1 2;"E:",] -> 3 .[+;1,`;"E:",] -> "E:'type\\n" 141 | ?[x;y;z] splice ?["abcd";1 3;"xyz"] -> "axyzd" 142 | -------------------------------------------------------------------------------- 143 | Special Symbols 144 | `j?C parse json `j?"{\\"a\\":1,\\"b\\":[true,\\"c\\"]}" -> `a`b!(1.0;(1;,"c")) 145 | `k@x pretty-print `k("ab";2 3) -> "(\\"ab\\";2 3)" 146 | `p@C parse k 147 | `hex@C hexadecimal `hex"ab" -> "6162" 148 | `pri@i primes `pri 20 -> 2 3 5 7 11 13 17 19 149 | `x@x fork-exec `x(("/bin/wc";"-l");"a\\nbc\\nd\\n") -> "3\\n" 150 | `t[] current time (microseconds) 151 | `argv[] list of cmd line args (also in global variable x) 152 | `env[] dict of env variables 153 | `prng[] `prng@I get/set pseudo-random number generator internal state 154 | s:`prng[];r:9?0;`prng s;r~9?0 -> 1 155 | `prng@0 use current time to set state 156 | `err@C throw error 157 | `sin@N trigonometry `sin 12.34 -> -0.22444212919135995 158 | `exp@N exponential `exp 1 -> 2.7182818284590455 159 | `ln@N logarithm `ln 2 -> 0.6931471805599453 160 | `exit@i exit 161 | -------------------------------------------------------------------------------- 162 | Adverbs 163 | f' each1 #'("abc";3 4 5 6) -> 3 4 164 | x F' each2 2 3#'"ab" -> ("aa";"bbb") 165 | X' binsearch 1 3 5 7 9'8 9 0 -> 3 4 -1 166 | F/ fold +/1 2 3 -> 6 167 | F\\ scan +\\1 2 3 -> 1 3 6 168 | x F/ seeded / 10+/1 2 3 -> 16 169 | x F\\ seeded \\ 10+\\1 2 3 -> 11 13 16 170 | i f/ n-do 5(2*)/1 -> 32 171 | i f\\ n-dos 5(2*)\\1 -> 1 2 4 8 16 32 172 | f f/ while (1<){:[2!x;1+3*x;-2!x]}/3 -> 1 173 | f f\\ whiles (1<){:[2!x;1+3*x;-2!x]}\\3 -> 3 10 5 16 8 4 2 1 174 | f/ converge {1+1.0%x}/1 -> 1.618033988749895 175 | f\\ converges (-2!)\\100 -> 100 50 25 12 6 3 1 0 176 | C/ join "ra"/("ab";"cadab";"") -> "abracadabra" 177 | C\\ split "ra"\\"abracadabra" -> ("ab";"cadab";"") 178 | I/ decode 24 60 60/1 2 3 -> 3723 2/1 1 0 1 -> 13 179 | I\\ encode 24 60 60\\3723 -> 1 2 3 2\\13 -> 1 1 0 1 180 | i': window 3':"abcdef" -> ("abc";"bcd";"cde";"def") 181 | i f': stencil 3{x,"."}':"abcde" -> ("abc.";"bcd.";"cde.") 182 | F': eachprior -':12 13 11 17 14 -> 12 1 -2 6 -3 183 | x F': seeded ': 10-':12 13 11 17 14 -> 2 1 -2 6 -3 184 | x F/: eachright 1 2*/:3 4 -> (3 6;4 8) 185 | x F\\: eachleft 1 2*\\:3 4 -> (3 4;6 8) 186 | -------------------------------------------------------------------------------- 187 | Grammar 188 | : SET RETURN :[c;t;f] COND 189 | + add flip 190 | - subtract negate ' each|slide|bin 191 | * multiply first / fold|join |dec|comment 192 | % divide sqrt \\ scan|split|enc|trace 193 | ! mod|dict enum|key ': eachprior 194 | & min|and where /: eachright 195 | | max|or reverse \\: eachleft 196 | < less ascend 197 | > more descend / 198 | = equal group multiline comment 199 | ~ match not \\ 200 | , concat enlist 201 | ^ without null 0: lines i/o 202 | # reshape length 1: bytes i/o 203 | _ drop|cut floor 204 | $ cast string 205 | ? find|rnd uniq ?[a;i;b] splice 206 | @ apply(1) type @[x;i;[f;]y] amend 207 | . apply(n) eval .[x;i;[f;]y] drill 208 | grammar: E:E;e|e e:nve|te| t:n|v v:tA|V n:t[E]|(E)|{E}|N 209 | limits: 8 args, 16 locals, 256 bytecode, 2048 stack 210 | """ 211 | 212 | struct HelpCard: View { 213 | let key: String 214 | let value: String 215 | @State var isExpanded: Bool = false 216 | 217 | var body: some View { 218 | VStack { 219 | Button(action: { self.isExpanded.toggle() }) { 220 | Text(key) 221 | .font(.headline) 222 | .frame(maxWidth: .infinity, alignment: .leading) 223 | .padding() 224 | } 225 | if isExpanded { 226 | Text(value) 227 | .font(.monospaced(.body)()) 228 | .lineLimit(nil) 229 | .fixedSize(horizontal: false, vertical: true) 230 | .padding() 231 | .frame(maxWidth: .infinity, alignment: .leading) 232 | } 233 | } 234 | .background(Color.gray.opacity(0.2)) 235 | .cornerRadius(8) 236 | .padding([.top, .horizontal]) 237 | } 238 | } 239 | 240 | struct HelpView: View { 241 | let helpDict: [String: String] 242 | 243 | init() { 244 | helpDict = toDict(h: kh) 245 | } 246 | 247 | var body: some View { 248 | ScrollView { 249 | ForEach(helpDict.keys.sorted(), id: \.self) { key in 250 | if let value = helpDict[key] { 251 | HelpCard(key: key, value: value) 252 | } 253 | } 254 | } 255 | } 256 | } 257 | 258 | #Preview { 259 | HelpView() 260 | } 261 | -------------------------------------------------------------------------------- /Beacon/Views/HistoryView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // HistoryView.swift 3 | // Arrayground 4 | // 5 | 6 | import Foundation 7 | import SwiftUI 8 | 9 | struct HistoryView: View { 10 | var index: Int 11 | var historyItem: Entry 12 | var curBuffer: String 13 | var onMySubmit: (String) -> Void 14 | @Binding var input: String 15 | @Binding var ephemerals: [Int: [String]] 16 | @Binding var editType: Behavior 17 | @ObservedObject var viewModel: HistoryModel 18 | @Environment(\.colorScheme) var scheme: ColorScheme 19 | 20 | var body: some View { 21 | VStack(alignment: .leading) { 22 | if editType == Behavior.inlineEdit { 23 | TextField("Source", text: Binding( 24 | get: { 25 | if index < viewModel.history[curBuffer, default: []].count { 26 | return self.viewModel.history[curBuffer, default: []][index].src 27 | } else { 28 | return "" 29 | } 30 | }, 31 | set: { 32 | if index < viewModel.history[curBuffer, default: []].count { 33 | self.viewModel.history[curBuffer, default: []][index].src = $0 34 | ephemerals[index, default: []].append($0) 35 | } 36 | } 37 | )) 38 | .onSubmit { 39 | onMySubmit(self.viewModel.history[curBuffer, default: []][index].src) 40 | for k in ephemerals.keys { 41 | self.viewModel.history[curBuffer, default: []][k].src = ephemerals[k, default: []].first! 42 | } 43 | ephemerals = [:] // reset all virtual textfield edits 44 | } 45 | .font(Font.custom("BQN386 Unicode", size: 18)) 46 | .foregroundColor(.blue) 47 | } else if editType == Behavior.duplicate { 48 | VStack(spacing: 1) { 49 | ForEach(Array(historyItem.tokens.enumerated()), id: \.offset) { _, line in 50 | HStack(spacing: 0) { 51 | ForEach(line, id: \.id) { token in 52 | let isDarkTheme = (scheme == .dark) 53 | let col = historyItem.lang == Language.k ? colorK(token.type, isDarkTheme) : colorBQN(token.type) 54 | Text(token.value) 55 | .lineLimit(1) // HACK to stop long tokens from messing alignment 56 | .foregroundColor(col) 57 | .font(Font.custom("BQN386 Unicode", size: 18)) 58 | .onTapGesture { 59 | self.input = historyItem.src 60 | } 61 | } 62 | }.frame(maxWidth: .infinity, alignment: .leading) 63 | } 64 | } 65 | } 66 | Text("\(trimLongText(historyItem.out))") 67 | .foregroundStyle(.primary.opacity(0.8)) 68 | .font(Font.custom("BQN386 Unicode", size: 18)) 69 | .foregroundColor(historyItem.out.starts(with: "Error:") || historyItem.out.starts(with: "\"Error:") ? .red : .primary) 70 | .multilineTextAlignment(.leading) 71 | .onTapGesture { 72 | self.input = historyItem.out 73 | } 74 | }.frame(maxWidth: .infinity, alignment: .leading) 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /Fonts/BQN386.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/x86y/arrayground/996108fc1d4024570b9cf75fdabec0ea3ba85184/Fonts/BQN386.ttf -------------------------------------------------------------------------------- /Keyboard/BQNInputSetProvider.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BQNInputSetProvider.swift 3 | // KeyboardUnicode 4 | // 5 | // Created by Daniel Saidi on 2022-02-04. 6 | // Copyright © 2022 Daniel Saidi. All rights reserved. 7 | // 8 | 9 | import KeyboardKit 10 | 11 | /** 12 | This demo-specific input set provider can be used to create 13 | a custom, Unicode-based input set. 14 | 15 | ``KeyboardViewController`` registers it to show how you can 16 | register and use a custom input set provider. 17 | 18 | Note that for some Unicode keyboards, it makes little sense 19 | to have a numeric and a symbolic keyboard. If so, you could 20 | create a custom layout that removes all these switcher keys. 21 | */ 22 | class BQNSP: InputSetProvider { 23 | let baseProvider = EnglishInputSetProvider() 24 | 25 | var alphabeticInputSet: AlphabeticInputSet { 26 | AlphabeticInputSet(rows: [ 27 | // .init(lowercased: "‿[{+-×÷}]", uppercased: "‿[{+-×÷}]"), 28 | .init(lowercased: "⌽𝕨∊↑∧⊔⊏⊐π←", uppercased: "⌽𝕎⍷↑∧⍋⊔⊑⊐π←"), 29 | .init(lowercased: "⍉𝕤↕𝕗𝕘⊸∘○⟜", uppercased: "⍉𝕊↕𝔽𝔾«∘⌾»"), 30 | .init( 31 | phoneLowercased: "⥊𝕩↓∨⌊≡∾", 32 | phoneUppercased: "⋈𝕏↓⍒⌈≢≤", 33 | padLowercased: "⥊𝕩↓∨⌊≡∾≤≍", 34 | padUppercased: "⋈𝕏↓⍒⌈≢≍≥≥" 35 | ), 36 | ]) 37 | } 38 | 39 | var numericInputSet: NumericInputSet { 40 | NumericInputSet(rows: [ 41 | .init(chars: "1234567890"), 42 | .init(phone: "˘¨⁼⌜´)&@”", pad: "1"), 43 | .init(phone: ".,?!’", pad: "%-+=/;:!?"), 44 | ]) 45 | } 46 | 47 | var symbolicInputSet: SymbolicInputSet { 48 | baseProvider.symbolicInputSet 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /Keyboard/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | NSExtension 6 | 7 | NSExtensionAttributes 8 | 9 | IsASCIICapable 10 | 11 | PrefersRightToLeft 12 | 13 | PrimaryLanguage 14 | en-US 15 | RequestsOpenAccess 16 | 17 | 18 | NSExtensionPointIdentifier 19 | com.apple.keyboard-service 20 | NSExtensionPrincipalClass 21 | $(PRODUCT_MODULE_NAME).KeyboardViewController 22 | 23 | UIAppFonts 24 | 25 | Fonts/BQN386.ttf 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Keyboard/KbViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // KbViewController.swift 3 | // KeyboardKit 4 | // 5 | 6 | import KeyboardKit 7 | import SwiftUI 8 | 9 | class KbViewController: KeyboardInputViewController { 10 | override func viewDidLoad() { 11 | keyboardContext.setLocale(.english) 12 | keyboardContext.keyboardDictationReplacement = .keyboardType(.emojis) 13 | autocompleteProvider = FakeAutocompleteProvider() 14 | keyboardStyleProvider = DemoKeyboardAppearance(keyboardContext: keyboardContext) 15 | keyboardActionHandler = DemoKeyboardActionHandler(inputViewController: self) 16 | keyboardLayoutProvider = DemoKeyboardLayoutProvider( 17 | keyboardContext: keyboardContext, 18 | inputSetProvider: inputSetProvider 19 | ) 20 | super.viewDidLoad() 21 | } 22 | 23 | override func viewWillSetupKeyboard() { 24 | super.viewWillSetupKeyboard() 25 | setup { KeyboardView(controller: $0) } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Keyboard/KeyboardActionHandler.swift: -------------------------------------------------------------------------------- 1 | // 2 | // KeyboardActionHandler.swift 3 | // 4 | 5 | import KeyboardKit 6 | import UIKit 7 | 8 | class DemoKeyboardActionHandler: StandardKeyboardActionHandler { 9 | // MARK: - Overrides 10 | 11 | override func action( 12 | for gesture: KeyboardGesture, 13 | on action: KeyboardAction 14 | ) -> KeyboardAction.GestureAction? { 15 | let standard = super.action(for: gesture, on: action) 16 | switch gesture { 17 | case .longPress: return longPressAction(for: action) ?? standard 18 | default: return standard 19 | } 20 | } 21 | 22 | // MARK: - Custom actions 23 | 24 | func longPressAction(for action: KeyboardAction) -> KeyboardAction.GestureAction? { 25 | switch action { 26 | case let .image(_, _, imageName): return { [weak self] _ in self?.saveImage(named: imageName) } 27 | default: return nil 28 | } 29 | } 30 | 31 | func tapAction(for action: KeyboardAction) -> KeyboardAction.GestureAction? { 32 | switch action { 33 | case let .image(_, _, imageName): return { [weak self] _ in self?.copyImage(named: imageName) } 34 | default: return nil 35 | } 36 | } 37 | 38 | // MARK: - Functions 39 | 40 | func alert(_: String) { 41 | print("Implement alert functionality if you want, or just place a breakpoint here.") 42 | } 43 | 44 | func copyImage(named imageName: String) { 45 | guard let image = UIImage(named: imageName) else { return } 46 | guard keyboardContext.hasFullAccess else { return alert("You must enable full access to copy images.") } 47 | guard image.copyToPasteboard() else { return alert("The image could not be copied.") } 48 | alert("Copied to pasteboard!") 49 | } 50 | 51 | func saveImage(named imageName: String) { 52 | guard let image = UIImage(named: imageName) else { return } 53 | guard keyboardContext.hasFullAccess else { return alert("You must enable full access to save images.") } 54 | image.saveToPhotos(completion: handleImageDidSave) 55 | alert("Saved to photos!") 56 | } 57 | } 58 | 59 | private extension DemoKeyboardActionHandler { 60 | func handleImageDidSave(withError error: Error?) { 61 | if error == nil { alert("Saved!") } 62 | else { alert("Failed!") } 63 | } 64 | } 65 | 66 | private extension UIImage { 67 | func copyToPasteboard(_ pasteboard: UIPasteboard = .general) -> Bool { 68 | guard let data = pngData() else { return false } 69 | pasteboard.setData(data, forPasteboardType: "public.png") 70 | return true 71 | } 72 | } 73 | 74 | private extension UIImage { 75 | func saveToPhotos(completion: @escaping (Error?) -> Void) { 76 | ImageService.default.saveImageToPhotos(self, completion: completion) 77 | } 78 | } 79 | 80 | private class ImageService: NSObject { 81 | public typealias Completion = (Error?) -> Void 82 | 83 | public private(set) static var `default` = ImageService() 84 | 85 | private var completions = [Completion]() 86 | 87 | public func saveImageToPhotos(_ image: UIImage, completion: @escaping (Error?) -> Void) { 88 | completions.append(completion) 89 | UIImageWriteToSavedPhotosAlbum(image, self, #selector(saveImageToPhotosDidComplete), nil) 90 | } 91 | 92 | @objc func saveImageToPhotosDidComplete(_: UIImage, error: NSError?, contextInfo _: UnsafeRawPointer) { 93 | guard completions.count > 0 else { return } 94 | completions.removeFirst()(error) 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /Keyboard/KeyboardAppearance.swift: -------------------------------------------------------------------------------- 1 | // 2 | // KeyboardAppearance.swift 3 | // Keyboard 4 | // 5 | // 6 | 7 | import KeyboardKit 8 | import SwiftUI 9 | 10 | class DemoKeyboardAppearance: StandardKeyboardStyleProvider { 11 | override func buttonStyle( 12 | for action: KeyboardAction, 13 | isPressed: Bool 14 | ) -> KeyboardStyle.Button { 15 | var style = super.buttonStyle(for: action, isPressed: isPressed) 16 | // style.cornerRadius = 10 17 | // style.backgroundColor = .blue 18 | // style.foregroundColor = .yellow 19 | if action != KeyboardAction.space && action != KeyboardAction.backspace && action != KeyboardAction.primary(.return) { 20 | style.font = KeyboardFont.custom("BQN386 Unicode", size: 24) 21 | } 22 | return style 23 | } 24 | 25 | override var inputCalloutStyle: KeyboardStyle.InputCallout { 26 | var style = super.inputCalloutStyle 27 | style.font = KeyboardFont.custom("BQN386 Unicode", size: 24) 28 | return style 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Keyboard/KeyboardLayoutProvider.swift: -------------------------------------------------------------------------------- 1 | // 2 | // KeyboardLayoutProvider.swift 3 | // 4 | // 5 | 6 | import KeyboardKit 7 | 8 | class DemoKeyboardLayoutProvider: StandardKeyboardLayoutProvider { 9 | override func keyboardLayout(for context: KeyboardContext) -> KeyboardLayout { 10 | let layout = super.keyboardLayout(for: context) 11 | guard layout.hasRows && context.hasMultipleLocales else { return layout } 12 | layout.tryInsertLocaleSwitcher() 13 | return layout 14 | } 15 | } 16 | 17 | private extension KeyboardContext { 18 | var hasMultipleLocales: Bool { 19 | locales.count > 1 20 | } 21 | } 22 | 23 | private extension KeyboardLayout { 24 | var bottomRowIndex: Int { 25 | itemRows.count - 1 26 | } 27 | 28 | var hasRows: Bool { 29 | itemRows.count > 0 30 | } 31 | 32 | var localeSwitcherTemplate: KeyboardLayoutItem? { 33 | itemRows[bottomRowIndex].first { $0.action.isSystemAction } 34 | } 35 | 36 | func tryInsertLocaleSwitcher() { 37 | guard let template = localeSwitcherTemplate else { return } 38 | let switcher = KeyboardLayoutItem(action: .nextLocale, size: template.size, insets: template.insets) 39 | itemRows.insert(switcher, after: .space, atRow: bottomRowIndex) 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /Keyboard/KeyboardView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // KeyboardView.swift 3 | // KeyboardKitDemo 4 | // 5 | 6 | import KeyboardKit 7 | import SwiftUI 8 | 9 | struct KeyboardView: View { 10 | @EnvironmentObject 11 | private var autocompleteContext: AutocompleteContext 12 | unowned var controller: KeyboardInputViewController 13 | @EnvironmentObject 14 | private var keyboardContext: KeyboardContext 15 | @EnvironmentObject 16 | private var keyboardTextContext: KeyboardTextContext 17 | 18 | var body: some View { 19 | VStack(spacing: 0) { 20 | if keyboardContext.keyboardType != .emojis { 21 | autocompleteToolbar 22 | } 23 | SystemKeyboard( 24 | controller: controller, 25 | autocompleteToolbar: .none 26 | ) 27 | } 28 | } 29 | } 30 | 31 | // MARK: - Private Views 32 | 33 | private extension KeyboardView { 34 | var autocompleteToolbar: some View { 35 | AutocompleteToolbar( 36 | suggestions: autocompleteContext.suggestions, 37 | locale: keyboardContext.locale, 38 | suggestionAction: controller.insertAutocompleteSuggestion 39 | ).font(Font.custom("BQN386 Unicode", size: 24)).opacity(keyboardContext.prefersAutocomplete ? 1 : 0) // Still allocate height 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /Keyboard/KeyboardViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // KeyboardViewController.swift 3 | // 4 | 5 | import KeyboardKit 6 | import SwiftUI 7 | 8 | class KeyboardViewController: KbViewController { 9 | override func viewDidLoad() { 10 | inputSetProvider = BQNSP() 11 | keyboardFeedbackSettings.enableHapticFeedback() 12 | super.viewDidLoad() 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

iBeacon

2 |

3 | A (mostly) SwiftUI application to interface with CBQN and ngn/k libraries into a (mostly) working repl. 4 |

5 | 6 | Features: 7 | - ngn/k support 8 | - BQN support (custom keyboard shipped with the app, \KEY combination also works for transliteration) 9 | - bqnlibs shipped out of the box 10 | - Buffer manager 11 | - Select between k/bqn and color themes by typing `config` 12 | - Type `\\:` to see all k help pages and `\:`, `\h`, `\'`, \\\`, `\+` to see the single help pages 13 | - Toolbar for adverbs/modifiers and buffers/help/setting buttons 14 | 15 |

16 | demo 17 | demo 18 | demo 19 | demo 20 | demo 21 |

22 |

23 | demo 24 | demo 25 |

26 | 27 | [WIP] Desired features: 28 | - Always blinking cursor on the main input 29 | - Better BQN keyboard design 30 | - Http client capabilities 31 | - Explore more native API's 32 | - Sliding through the buffers with gestures 33 | --------------------------------------------------------------------------------