├── .github └── workflows │ └── mainPackage.yml ├── .gitignore ├── CODE_OF_CONDUCT.md ├── LICENSE ├── README.md ├── SimpleAuth.Droid.CustomTabs.nuspec ├── SimpleAuth.Facebook.Droid.nuspec ├── SimpleAuth.Facebook.iOS.nuspec ├── SimpleAuth.Google.Droid.nuspec ├── SimpleAuth.Google.iOS.nuspec ├── SimpleAuth.nuspec ├── ext └── portable-headers │ └── System.Net.Http.dll ├── samples ├── .nuget │ └── NuGet.Config ├── Sample.Droid │ ├── Assets │ │ └── AboutAssets.txt │ ├── MainActivity.cs │ ├── Properties │ │ ├── AndroidManifest.xml │ │ └── AssemblyInfo.cs │ ├── Resources │ │ ├── AboutResources.txt │ │ ├── Resource.Designer.cs │ │ ├── drawable │ │ │ └── Icon.png │ │ ├── layout │ │ │ └── Main.axml │ │ └── values │ │ │ └── Strings.xml │ └── Sample.Droid.csproj ├── Sample.Forms │ ├── Sample.Forms.Droid │ │ ├── Assets │ │ │ └── AboutAssets.txt │ │ ├── MainActivity.cs │ │ ├── Properties │ │ │ ├── AndroidManifest.xml │ │ │ └── AssemblyInfo.cs │ │ ├── Resources │ │ │ ├── AboutResources.txt │ │ │ ├── Resource.Designer.cs │ │ │ ├── drawable-hdpi │ │ │ │ └── icon.png │ │ │ ├── drawable-xhdpi │ │ │ │ └── icon.png │ │ │ ├── drawable-xxhdpi │ │ │ │ └── icon.png │ │ │ └── drawable │ │ │ │ └── icon.png │ │ ├── Sample.Forms.Droid.csproj │ │ └── SimpleAuth.keystore │ ├── Sample.Forms.UWP │ │ ├── App.xaml │ │ ├── App.xaml.cs │ │ ├── Assets │ │ │ ├── LockScreenLogo.scale-200.png │ │ │ ├── SplashScreen.scale-200.png │ │ │ ├── Square150x150Logo.scale-200.png │ │ │ ├── Square44x44Logo.scale-200.png │ │ │ ├── Square44x44Logo.targetsize-24_altform-unplated.png │ │ │ ├── StoreLogo.png │ │ │ └── Wide310x150Logo.scale-200.png │ │ ├── MainPage.xaml │ │ ├── MainPage.xaml.cs │ │ ├── Package.appxmanifest │ │ ├── Properties │ │ │ ├── AssemblyInfo.cs │ │ │ └── Default.rd.xml │ │ ├── Sample.Forms.UWP.csproj │ │ ├── Sample.Forms.UWP.nuget.props │ │ └── Sample.Forms.UWP.nuget.targets │ ├── Sample.Forms.WinPhone │ │ ├── App.xaml │ │ ├── App.xaml.cs │ │ ├── Assets │ │ │ ├── Logo.scale-240.png │ │ │ ├── SmallLogo.scale-240.png │ │ │ ├── SplashScreen.scale-240.png │ │ │ ├── Square71x71Logo.scale-240.png │ │ │ ├── StoreLogo.scale-240.png │ │ │ └── WideLogo.scale-240.png │ │ ├── MainPage.xaml │ │ ├── MainPage.xaml.cs │ │ ├── Package.appxmanifest │ │ ├── Properties │ │ │ └── AssemblyInfo.cs │ │ ├── Sample.Forms.WinPhone.csproj │ │ └── packages.config │ ├── Sample.Forms.Windows │ │ ├── App.xaml │ │ ├── App.xaml.cs │ │ ├── Assets │ │ │ ├── Logo.scale-100.png │ │ │ ├── SmallLogo.scale-100.png │ │ │ ├── SplashScreen.scale-100.png │ │ │ └── StoreLogo.scale-100.png │ │ ├── MainPage.xaml │ │ ├── MainPage.xaml.cs │ │ ├── Package.appxmanifest │ │ ├── Properties │ │ │ └── AssemblyInfo.cs │ │ ├── Sample.Forms.Windows.csproj │ │ └── packages.config │ ├── Sample.Forms.iOS │ │ ├── AppDelegate.cs │ │ ├── Entitlements.plist │ │ ├── Info.plist │ │ ├── Main.cs │ │ ├── Properties │ │ │ └── AssemblyInfo.cs │ │ ├── Resources │ │ │ ├── Default-568h@2x.png │ │ │ ├── Default-Portrait.png │ │ │ ├── Default-Portrait@2x.png │ │ │ ├── Default.png │ │ │ ├── Default@2x.png │ │ │ ├── Icon-60@2x.png │ │ │ ├── Icon-60@3x.png │ │ │ ├── Icon-76.png │ │ │ ├── Icon-76@2x.png │ │ │ ├── Icon-Small-40.png │ │ │ ├── Icon-Small-40@2x.png │ │ │ ├── Icon-Small-40@3x.png │ │ │ ├── Icon-Small.png │ │ │ ├── Icon-Small@2x.png │ │ │ ├── Icon-Small@3x.png │ │ │ └── LaunchScreen.storyboard │ │ ├── Sample.Forms.iOS.csproj │ │ ├── iTunesArtwork │ │ └── iTunesArtwork@2x │ └── Sample.Forms │ │ ├── App.cs │ │ ├── LoginPage.xaml │ │ ├── LoginPage.xaml.cs │ │ ├── Sample.Forms.projitems │ │ └── Sample.Forms.shproj ├── Sample.Mac │ ├── AppDelegate.cs │ ├── AppDelegate.designer.cs │ ├── Entitlements.plist │ ├── Info.plist │ ├── Main.cs │ ├── MainMenu.xib │ ├── MainWindow.cs │ ├── MainWindow.designer.cs │ ├── MainWindow.xib │ ├── MainWindowController.cs │ ├── MainWindowController.designer.cs │ ├── Resources │ │ └── Images.xcassets │ │ │ └── AppIcons.appiconset │ │ │ ├── AppIcon-128.png │ │ │ ├── AppIcon-128@2x.png │ │ │ ├── AppIcon-16.png │ │ │ ├── AppIcon-16@2x.png │ │ │ ├── AppIcon-256.png │ │ │ ├── AppIcon-256@2x.png │ │ │ ├── AppIcon-32.png │ │ │ ├── AppIcon-32@2x.png │ │ │ ├── AppIcon-512.png │ │ │ ├── AppIcon-512@2x.png │ │ │ └── Contents.json │ └── Sample.Mac.csproj ├── Sample.Maui │ ├── App.xaml │ ├── App.xaml.cs │ ├── LoginPage.xaml │ ├── LoginPage.xaml.cs │ ├── MauiProgram.cs │ ├── Platforms │ │ ├── Android │ │ │ ├── AndroidManifest.xml │ │ │ ├── MainActivity.cs │ │ │ ├── MainApplication.cs │ │ │ └── Resources │ │ │ │ └── values │ │ │ │ └── colors.xml │ │ ├── MacCatalyst │ │ │ ├── AppDelegate.cs │ │ │ ├── Info.plist │ │ │ └── Program.cs │ │ ├── Windows │ │ │ ├── App.xaml │ │ │ ├── App.xaml.cs │ │ │ ├── Package.appxmanifest │ │ │ └── app.manifest │ │ └── iOS │ │ │ ├── AppDelegate.cs │ │ │ ├── Info.plist │ │ │ └── Program.cs │ ├── Properties │ │ └── launchSettings.json │ ├── Resources │ │ ├── AppIcon │ │ │ ├── appicon.svg │ │ │ └── appiconfg.svg │ │ ├── Fonts │ │ │ ├── OpenSans-Regular.ttf │ │ │ └── OpenSans-Semibold.ttf │ │ ├── Images │ │ │ └── dotnet_bot.svg │ │ ├── Raw │ │ │ └── AboutAssets.txt │ │ ├── Splash │ │ │ └── splash.svg │ │ └── Styles │ │ │ ├── Colors.xaml │ │ │ └── Styles.xaml │ └── Sample.Maui.csproj ├── Sample.iOS │ ├── AppDelegate.cs │ ├── Entitlements.plist │ ├── Info.plist │ ├── Main.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── Resources │ │ └── LaunchScreen.xib │ ├── Sample.iOS.csproj │ └── Spinner.cs ├── SimpleAuth.Samples.Windows.sln └── SimpleAuth.Samples.sln └── src ├── .nuget └── NuGet.Config ├── SimpleAuth.Droid.CustomTabs ├── ActivityLifecycleCallbackManager.cs ├── NativeCustomTabsAuthenticator.cs ├── Properties │ └── AssemblyInfo.cs ├── Resources │ ├── AboutResources.txt │ └── Resource.Designer.cs ├── SimpleAuth.Droid.CustomTabs.csproj └── SimpleAuthCallbackActivity.cs ├── SimpleAuth.Droid ├── ActivityStateRepository.cs ├── App.config ├── AuthStorage.cs ├── LoginActvity.cs ├── Native.cs ├── Resources │ ├── AboutResources.txt │ ├── Resource.Designer.cs │ ├── Values │ │ └── Strings.xml │ └── layout │ │ └── login.axml ├── SimpleAuth.Droid.csproj ├── TypeForwarded.cs └── WebAuthenticatorActivity.cs ├── SimpleAuth.Facebook.Droid ├── ActivityLifecycleManager.cs ├── Facebook.cs ├── Properties │ └── AssemblyInfo.cs ├── Resources │ ├── AboutResources.txt │ ├── Resource.designer.cs │ └── values │ │ └── Strings.xml └── SimpleAuth.Facebook.Droid.csproj ├── SimpleAuth.Facebook.iOS ├── Facebook.cs ├── Properties │ └── AssemblyInfo.cs └── SimpleAuth.Facebook.iOS.csproj ├── SimpleAuth.Google.Droid ├── ActivityLifecycleManager.cs ├── Google.cs ├── Properties │ └── AssemblyInfo.cs ├── Resources │ ├── AboutResources.txt │ ├── Resource.designer.cs │ └── values │ │ └── Strings.xml └── SimpleAuth.Google.Droid.csproj ├── SimpleAuth.Google.iOS ├── Google.cs ├── Properties │ └── AssemblyInfo.cs └── SimpleAuth.Google.iOS.csproj ├── SimpleAuth.Mac.sln ├── SimpleAuth.Mac ├── AppleEventsHelper.cs ├── AuthStorage.cs ├── Entitlements.plist ├── Native.cs ├── NativeSafariAuthenticator.cs ├── SimpleAuth.Mac.csproj └── WebAuthenticator.cs ├── SimpleAuth.Net ├── AuthStorage.cs └── SimpleAuth.Net.csproj ├── SimpleAuth.Net6 └── SimpleAuth-net6.csproj ├── SimpleAuth.Tests ├── Helpers │ ├── FakeHttpHandler.cs │ ├── InMemoryAuthStorage.cs │ └── RequestMessage.cs ├── OAuth │ ├── OAuthApiTests.cs │ ├── OAuthData.cs │ └── OAuthTestApi.cs └── SimpleAuth.Tests.csproj ├── SimpleAuth.UWP ├── AuthStorage.cs ├── CustomWebAuthenticationBroker.cs ├── CustomWebAuthenticationResult.cs ├── SimpleAuth.UWP.csproj ├── SimpleAuth.UWP.nuget.props └── WebAuthenticatorWebView.cs ├── SimpleAuth.iOS ├── App.config ├── AuthStorage.cs ├── BasicAuthController.cs ├── Entitlements.plist ├── Native.cs ├── NativeSafariAuthenticator.cs ├── SimpleAuth.iOS.csproj ├── Twitter.cs ├── TypeForwarded.cs ├── WebAuthenticatorViewController.cs └── WebAuthenticatorWindow.cs ├── SimpleAuth.sln └── SimpleAuth ├── Api ├── Account.cs ├── Api.cs ├── ApiResponse.cs ├── Attributes.cs ├── AuthenticatedApi.cs ├── Authenticator.cs ├── JSonExtensions.cs └── WebAuthenticator.cs ├── ApiKey ├── ApiKeyApi.cs └── AuthLocation.cs ├── BasicAuth ├── BasicAuthAccount.cs ├── BasicAuthApi.cs ├── BasicAuthAuthenticator.cs └── IBasicAuthenicator.cs ├── Converters ├── Converter.cs └── JsonConverter.cs ├── Helpers ├── CookieHolder.cs ├── IAuthStorage.cs ├── Resolver.cs └── UrlUtility.cs ├── OAuth ├── OAuthAccount.cs ├── OAuthApi.cs ├── OAuthAuthenticator.cs ├── OAuthPasswordApi.cs ├── OauthApiKeyApi.cs └── OauthResponse.cs ├── Properties └── AssemblyInfo.cs ├── Providers ├── ADFS.cs ├── Amazon.cs ├── AzureB2CApi.cs ├── DropBox.cs ├── Facebook.cs ├── FitBitApi.cs ├── Github.cs ├── Google.cs ├── Instagram.cs ├── LinkedIn.cs ├── MicrosoftLiveConnectApi.cs └── Twitter.cs ├── SimpleAuth.projitems └── SimpleAuth.shproj /.github/workflows/mainPackage.yml: -------------------------------------------------------------------------------- 1 | name: .NET 2 | 3 | on: 4 | push: 5 | branches: [ "main" ] 6 | pull_request: 7 | branches: [ "main" ] 8 | 9 | jobs: 10 | build: 11 | name: Build SimpleAuth Nuget 12 | env: 13 | NUPKG_MAJOR: 0.2 14 | BASE: 334 15 | NUPKG_SUFFIX: -alpha 16 | runs-on: windows-latest 17 | 18 | steps: 19 | - uses: actions/checkout@v3 20 | - name: Setup .NET 21 | uses: actions/setup-dotnet@v3 22 | with: 23 | dotnet-version: 6.0.x 24 | - name: Add msbuild to PATH 25 | uses: microsoft/setup-msbuild@v1.1 26 | with: 27 | vs-prerelease: true 28 | 29 | - name: Install Maui Workload 30 | shell: pwsh 31 | run: | 32 | & dotnet workload install maui ` 33 | --skip-sign-check ` 34 | 35 | - name: install Xamarin 36 | shell: pwsh 37 | run: | 38 | dotnet tool install --global boots 39 | boots --stable Xamarin.iOS 40 | boots --stable Xamarin.Mac 41 | 42 | - name: Build 43 | run: msbuild /r src/SimpleAuth.sln 44 | 45 | - name: Nuget Pack step 46 | shell: bash 47 | run: | 48 | MINOR_VERSION=$(( $BASE + $GITHUB_RUN_NUMBER )) 49 | VERSION=$NUPKG_MAJOR.$MINOR_VERSION$NUPKG_SUFFIX 50 | echo "PACKAGE VERSION: $VERSION" 51 | nuget pack SimpleAuth.nuspec -version $VERSION -Symbols -SymbolPackageFormat snupkg 52 | 53 | - uses: actions/upload-artifact@v2 54 | name: Upload Nuget Artifact 55 | with: 56 | name: nuget-artifact.${{env.GITHUB_RUN_NUMBER}} 57 | path: | 58 | **\*.nupkg 59 | **\*.snupkg 60 | **\*.symbols.nupkg 61 | -------------------------------------------------------------------------------- /SimpleAuth.Droid.CustomTabs.nuspec: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Clancey.SimpleAuth.Droid.CustomTabs 5 | 1.0.3 6 | Clancey 7 | https://github.com/Clancey/SimpleAuth/blob/master/LICENSE 8 | https://github.com/clancey/SimpleAuth 9 | false 10 | Adds CustomTabs support to SimpleAuth 11 | Updated dependencies 12 | James Clancey 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /SimpleAuth.Facebook.Droid.nuspec: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Clancey.SimpleAuth.Facebook.Droid 5 | 1.0.6 6 | Clancey 7 | https://github.com/Clancey/SimpleAuth/blob/master/LICENSE 8 | https://github.com/clancey/SimpleAuth 9 | false 10 | Native Facebook support for SimpleAuth 11 | Updated dependencies 12 | James Clancey 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /SimpleAuth.Facebook.iOS.nuspec: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Clancey.SimpleAuth.Facebook.iOS 5 | 1.0.7 6 | Clancey 7 | https://github.com/Clancey/SimpleAuth/blob/master/LICENSE 8 | https://github.com/clancey/SimpleAuth 9 | false 10 | Native Facebook support for SimpleAuth 11 | Added hookeups for Simplified plugins 12 | Required Callbacks: 13 | SimpleAuth.Providers.Facebook.Init(app, options); 14 | SimpleAuth.Native.OpenUrl(application, url, options); 15 | Updated Dependencies 16 | James Clancey 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /SimpleAuth.Google.Droid.nuspec: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Clancey.SimpleAuth.Google.Droid 5 | 1.0.13 6 | Clancey 7 | https://github.com/Clancey/SimpleAuth/blob/master/LICENSE 8 | https://github.com/clancey/SimpleAuth 9 | false 10 | Native Google support for SimpleAuth 11 | Updated dependencies 12 | James Clancey 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /SimpleAuth.Google.iOS.nuspec: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Clancey.SimpleAuth.Google.iOS 5 | 1.0.4 6 | Clancey 7 | https://github.com/Clancey/SimpleAuth/blob/master/LICENSE 8 | https://github.com/clancey/SimpleAuth 9 | false 10 | Native Google support for SimpleAuth 11 | Just call 12 | SimpleAuth.Providers.Google.Init(); 13 | Required Callbacks: 14 | SimpleAuth.Native.OpenUrl(application, url, options); 15 | Updated dependencies 16 | James Clancey 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /SimpleAuth.nuspec: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Clancey.SimpleAuth 5 | 1.0.56 6 | Clancey 7 | https://github.com/Clancey/SimpleAuth/blob/master/LICENSE 8 | https://github.com/clancey/SimpleAuth 9 | false 10 | The Simplest OAuth client for Xamarin and UWP 11 | Every API needs authentication, yet no developer wants to deal with authentication. Simple Auth embeds authentication into the API so you dont need to deal with it. 12 | Added WKWebView for iOS 13 | James Clancey 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /ext/portable-headers/System.Net.Http.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Clancey/SimpleAuth/4317c3a53e6665014f896788fd8baee02a0bf54b/ext/portable-headers/System.Net.Http.dll -------------------------------------------------------------------------------- /samples/.nuget/NuGet.Config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /samples/Sample.Droid/Assets/AboutAssets.txt: -------------------------------------------------------------------------------- 1 | Any raw assets you want to be deployed with your application can be placed in 2 | this directory (and child directories) and given a Build Action of "AndroidAsset". 3 | 4 | These files will be deployed with you package and will be accessible using Android's 5 | AssetManager, like this: 6 | 7 | public class ReadAsset : Activity 8 | { 9 | protected override void OnCreate (Bundle bundle) 10 | { 11 | base.OnCreate (bundle); 12 | 13 | InputStream input = Assets.Open ("my_asset.txt"); 14 | } 15 | } 16 | 17 | Additionally, some Android functions will automatically load asset files: 18 | 19 | Typeface tf = Typeface.CreateFromAsset (Context.Assets, "fonts/samplefont.ttf"); -------------------------------------------------------------------------------- /samples/Sample.Droid/Properties/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /samples/Sample.Droid/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | using Android.App; 5 | 6 | // General Information about an assembly is controlled through the following 7 | // set of attributes. Change these attribute values to modify the information 8 | // associated with an assembly. 9 | [assembly: AssemblyTitle("Sample.Droid")] 10 | [assembly: AssemblyDescription("")] 11 | [assembly: AssemblyConfiguration("")] 12 | [assembly: AssemblyCompany("")] 13 | [assembly: AssemblyProduct("Sample.Droid")] 14 | [assembly: AssemblyCopyright("Copyright © 2015")] 15 | [assembly: AssemblyTrademark("")] 16 | [assembly: AssemblyCulture("")] 17 | [assembly: ComVisible(false)] 18 | 19 | // Version information for an assembly consists of the following four values: 20 | // 21 | // Major Version 22 | // Minor Version 23 | // Build Number 24 | // Revision 25 | // 26 | // You can specify all the values or you can default the Build and Revision Numbers 27 | // by using the '*' as shown below: 28 | // [assembly: AssemblyVersion("1.0.*")] 29 | [assembly: AssemblyVersion("1.0.0.0")] 30 | [assembly: AssemblyFileVersion("1.0.0.0")] 31 | -------------------------------------------------------------------------------- /samples/Sample.Droid/Resources/AboutResources.txt: -------------------------------------------------------------------------------- 1 | Images, layout descriptions, binary blobs and string dictionaries can be included 2 | in your application as resource files. Various Android APIs are designed to 3 | operate on the resource IDs instead of dealing with images, strings or binary blobs 4 | directly. 5 | 6 | For example, a sample Android app that contains a user interface layout (main.xml), 7 | an internationalization string table (strings.xml) and some icons (drawable-XXX/icon.png) 8 | would keep its resources in the "Resources" directory of the application: 9 | 10 | Resources/ 11 | drawable-hdpi/ 12 | icon.png 13 | 14 | drawable-ldpi/ 15 | icon.png 16 | 17 | drawable-mdpi/ 18 | icon.png 19 | 20 | layout/ 21 | main.xml 22 | 23 | values/ 24 | strings.xml 25 | 26 | In order to get the build system to recognize Android resources, set the build action to 27 | "AndroidResource". The native Android APIs do not operate directly with filenames, but 28 | instead operate on resource IDs. When you compile an Android application that uses resources, 29 | the build system will package the resources for distribution and generate a class called 30 | "Resource" that contains the tokens for each one of the resources included. For example, 31 | for the above Resources layout, this is what the Resource class would expose: 32 | 33 | public class Resource { 34 | public class drawable { 35 | public const int icon = 0x123; 36 | } 37 | 38 | public class layout { 39 | public const int main = 0x456; 40 | } 41 | 42 | public class strings { 43 | public const int first_string = 0xabc; 44 | public const int second_string = 0xbcd; 45 | } 46 | } 47 | 48 | You would then use R.drawable.icon to reference the drawable/icon.png file, or Resource.layout.main 49 | to reference the layout/main.xml file, or Resource.strings.first_string to reference the first 50 | string in the dictionary file values/strings.xml. -------------------------------------------------------------------------------- /samples/Sample.Droid/Resources/drawable/Icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Clancey/SimpleAuth/4317c3a53e6665014f896788fd8baee02a0bf54b/samples/Sample.Droid/Resources/drawable/Icon.png -------------------------------------------------------------------------------- /samples/Sample.Droid/Resources/layout/Main.axml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 13 |