├── .github └── workflows │ ├── publish-experimental.yml │ └── publish.yml ├── .gitignore ├── Directory.Build.props ├── GoLive.Generator.RazorPageRoute.Generator ├── GoLive.Generator.RazorPageRoute.Generator.csproj ├── IsExternalInit.cs ├── PageRoute.cs ├── PageRouteGenerator.cs ├── Properties │ └── launchSettings.json ├── RouteConstraint.cs ├── RouteTemplate.cs ├── Scanner.cs ├── Settings.cs ├── Slug.cs ├── SlugOptions.cs ├── SourceStringBuilder.cs ├── StringSegmentAccumulator.cs ├── TemplateParser.cs ├── TemplateSegment.cs └── UrlValueConstraint.cs ├── GoLive.Generator.RazorPageRoute.Tests.BlazorWebAsssembly ├── App.razor ├── GoLive.Generator.RazorPageRoute.Tests.BlazorWebAsssembly.csproj ├── PageRoute.cs ├── Pages │ ├── Counter.razor │ ├── FetchData.razor │ └── Index.razor ├── Program.cs ├── Properties │ └── launchSettings.json ├── RazorPageRoutes.json ├── Shared │ ├── MainLayout.razor │ ├── MainLayout.razor.css │ ├── NavMenu.razor │ ├── NavMenu.razor.css │ └── SurveyPrompt.razor ├── _Imports.razor └── wwwroot │ ├── css │ ├── app.css │ ├── bootstrap │ │ ├── bootstrap.min.css │ │ └── bootstrap.min.css.map │ └── open-iconic │ │ ├── FONT-LICENSE │ │ ├── ICON-LICENSE │ │ ├── README.md │ │ └── font │ │ ├── css │ │ └── open-iconic-bootstrap.min.css │ │ └── fonts │ │ ├── open-iconic.eot │ │ ├── open-iconic.otf │ │ ├── open-iconic.svg │ │ ├── open-iconic.ttf │ │ └── open-iconic.woff │ ├── favicon.ico │ ├── icon-192.png │ ├── index.html │ ├── jsinvokable.js │ └── sample-data │ └── weather.json ├── GoLive.Generator.RazorPageRoute.Tests.BlazorWebAsssembly2 ├── App.razor ├── GoLive.Generator.RazorPageRoute.Tests.BlazorWebAsssembly2.csproj ├── Pages │ ├── Counter.razor │ ├── FetchData.razor │ └── Index.razor ├── Program.cs ├── Properties │ └── launchSettings.json ├── Shared │ ├── MainLayout.razor │ ├── MainLayout.razor.css │ ├── NavMenu.razor │ ├── NavMenu.razor.css │ └── SurveyPrompt.razor ├── _Imports.razor └── wwwroot │ ├── css │ ├── app.css │ ├── bootstrap │ │ ├── bootstrap.min.css │ │ └── bootstrap.min.css.map │ └── open-iconic │ │ ├── FONT-LICENSE │ │ ├── ICON-LICENSE │ │ ├── README.md │ │ └── font │ │ ├── css │ │ └── open-iconic-bootstrap.min.css │ │ └── fonts │ │ ├── open-iconic.eot │ │ ├── open-iconic.otf │ │ ├── open-iconic.svg │ │ ├── open-iconic.ttf │ │ └── open-iconic.woff │ ├── favicon.ico │ ├── icon-192.png │ ├── index.html │ └── sample-data │ └── weather.json ├── GoLive.Generator.RazorPageRoute.sln ├── LICENSE └── README.md /.github/workflows/publish-experimental.yml: -------------------------------------------------------------------------------- 1 | name: Publish Experimental 2 | on: 3 | workflow_dispatch: 4 | 5 | jobs: 6 | publish: 7 | env: 8 | MainProject: 'GoLive.Generator.RazorPageRoute.Generator/GoLive.Generator.RazorPageRoute.Generator.csproj' 9 | BUILD_VER : '2.0' 10 | name: build, pack & publish 11 | runs-on: windows-latest 12 | steps: 13 | - uses: actions/checkout@v3 14 | - name: Setup dotnet 15 | uses: actions/setup-dotnet@v3 16 | with: 17 | dotnet-version: 8.0.x 18 | - name: Setup NuGet 19 | uses: nuget/setup-nuget@v1 20 | - name: Get Build Version 21 | run: | 22 | echo "BUILD_VERSION=${{ format('{0}.{1}', env.BUILD_VER, github.run_number ) }}-alpha" >> $GITHUB_ENV 23 | - name: Build Main 24 | run: dotnet pack $MainProject --configuration Release -p:Version=$BUILD_VERSION -p:PackageVersion=$BUILD_VERSION -p:NuGetVersion=$BUILD_VERSION -p:GeneratePackageOnBuild=false 25 | - name: Publish 26 | run: nuget push **\*.nupkg -Source 'https://api.nuget.org/v3/index.json' -ApiKey ${{secrets.NUGET_KEY}} -------------------------------------------------------------------------------- /.github/workflows/publish.yml: -------------------------------------------------------------------------------- 1 | name: Publish to Nuget 2 | on: 3 | push: 4 | branches: 5 | - master # Default release branch 6 | workflow_dispatch: 7 | 8 | jobs: 9 | publish: 10 | name: build, pack & publish 11 | runs-on: windows-latest 12 | steps: 13 | - uses: actions/checkout@v2 14 | 15 | - name: Setup dotnet 16 | uses: actions/setup-dotnet@v1 17 | with: 18 | dotnet-version: 5.0.101 19 | - name: Publish 20 | id: publish_nuget 21 | uses: rohith/publish-nuget@v2 22 | with: 23 | PROJECT_FILE_PATH: GoLive.Generator.RazorPageRoute.Generator/GoLive.Generator.RazorPageRoute.Generator.csproj 24 | VERSION_FILE_PATH: Directory.Build.props 25 | VERSION_REGEX: ^\s*(.*)<\/Version>\s*$ 26 | NUGET_KEY: ${{secrets.NUGET_KEY}} 27 | INCLUDE_SYMBOLS: false 28 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Created by https://www.toptal.com/developers/gitignore/api/rider,visualstudio,visualstudiocode 3 | # Edit at https://www.toptal.com/developers/gitignore?templates=rider,visualstudio,visualstudiocode 4 | 5 | ### Rider ### 6 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider 7 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 8 | 9 | # User-specific stuff 10 | .idea/**/workspace.xml 11 | .idea/**/tasks.xml 12 | .idea/**/usage.statistics.xml 13 | .idea/**/dictionaries 14 | .idea/**/shelf 15 | 16 | # AWS User-specific 17 | .idea/**/aws.xml 18 | 19 | # Generated files 20 | .idea/**/contentModel.xml 21 | 22 | # Sensitive or high-churn files 23 | .idea/**/dataSources/ 24 | .idea/**/dataSources.ids 25 | .idea/**/dataSources.local.xml 26 | .idea/**/sqlDataSources.xml 27 | .idea/**/dynamic.xml 28 | .idea/**/uiDesigner.xml 29 | .idea/**/dbnavigator.xml 30 | 31 | # Gradle 32 | .idea/**/gradle.xml 33 | .idea/**/libraries 34 | 35 | # Gradle and Maven with auto-import 36 | # When using Gradle or Maven with auto-import, you should exclude module files, 37 | # since they will be recreated, and may cause churn. Uncomment if using 38 | # auto-import. 39 | # .idea/artifacts 40 | # .idea/compiler.xml 41 | # .idea/jarRepositories.xml 42 | # .idea/modules.xml 43 | # .idea/*.iml 44 | # .idea/modules 45 | # *.iml 46 | # *.ipr 47 | 48 | # CMake 49 | cmake-build-*/ 50 | 51 | # Mongo Explorer plugin 52 | .idea/**/mongoSettings.xml 53 | 54 | # File-based project format 55 | *.iws 56 | 57 | # IntelliJ 58 | out/ 59 | 60 | # mpeltonen/sbt-idea plugin 61 | .idea_modules/ 62 | 63 | # JIRA plugin 64 | atlassian-ide-plugin.xml 65 | 66 | # Cursive Clojure plugin 67 | .idea/replstate.xml 68 | 69 | # Crashlytics plugin (for Android Studio and IntelliJ) 70 | com_crashlytics_export_strings.xml 71 | crashlytics.properties 72 | crashlytics-build.properties 73 | fabric.properties 74 | 75 | # Editor-based Rest Client 76 | .idea/httpRequests 77 | 78 | # Android studio 3.1+ serialized cache file 79 | .idea/caches/build_file_checksums.ser 80 | 81 | ### VisualStudioCode ### 82 | .vscode/* 83 | !.vscode/settings.json 84 | !.vscode/tasks.json 85 | !.vscode/launch.json 86 | !.vscode/extensions.json 87 | *.code-workspace 88 | 89 | # Local History for Visual Studio Code 90 | .history/ 91 | 92 | ### VisualStudioCode Patch ### 93 | # Ignore all local history of files 94 | .history 95 | .ionide 96 | 97 | # Support for Project snippet scope 98 | !.vscode/*.code-snippets 99 | 100 | ### VisualStudio ### 101 | ## Ignore Visual Studio temporary files, build results, and 102 | ## files generated by popular Visual Studio add-ons. 103 | ## 104 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 105 | 106 | # User-specific files 107 | *.rsuser 108 | *.suo 109 | *.user 110 | *.userosscache 111 | *.sln.docstates 112 | 113 | # User-specific files (MonoDevelop/Xamarin Studio) 114 | *.userprefs 115 | 116 | # Mono auto generated files 117 | mono_crash.* 118 | 119 | # Build results 120 | [Dd]ebug/ 121 | [Dd]ebugPublic/ 122 | [Rr]elease/ 123 | [Rr]eleases/ 124 | x64/ 125 | x86/ 126 | [Ww][Ii][Nn]32/ 127 | [Aa][Rr][Mm]/ 128 | [Aa][Rr][Mm]64/ 129 | bld/ 130 | [Bb]in/ 131 | [Oo]bj/ 132 | [Ll]og/ 133 | [Ll]ogs/ 134 | 135 | # Visual Studio 2015/2017 cache/options directory 136 | .vs/ 137 | # Uncomment if you have tasks that create the project's static files in wwwroot 138 | #wwwroot/ 139 | 140 | # Visual Studio 2017 auto generated files 141 | Generated\ Files/ 142 | 143 | # MSTest test Results 144 | [Tt]est[Rr]esult*/ 145 | [Bb]uild[Ll]og.* 146 | 147 | # NUnit 148 | *.VisualState.xml 149 | TestResult.xml 150 | nunit-*.xml 151 | 152 | # Build Results of an ATL Project 153 | [Dd]ebugPS/ 154 | [Rr]eleasePS/ 155 | dlldata.c 156 | 157 | # Benchmark Results 158 | BenchmarkDotNet.Artifacts/ 159 | 160 | # .NET Core 161 | project.lock.json 162 | project.fragment.lock.json 163 | artifacts/ 164 | 165 | # ASP.NET Scaffolding 166 | ScaffoldingReadMe.txt 167 | 168 | # StyleCop 169 | StyleCopReport.xml 170 | 171 | # Files built by Visual Studio 172 | *_i.c 173 | *_p.c 174 | *_h.h 175 | *.ilk 176 | *.meta 177 | *.obj 178 | *.iobj 179 | *.pch 180 | *.pdb 181 | *.ipdb 182 | *.pgc 183 | *.pgd 184 | *.rsp 185 | *.sbr 186 | *.tlb 187 | *.tli 188 | *.tlh 189 | *.tmp 190 | *.tmp_proj 191 | *_wpftmp.csproj 192 | *.log 193 | *.tlog 194 | *.vspscc 195 | *.vssscc 196 | .builds 197 | *.pidb 198 | *.svclog 199 | *.scc 200 | 201 | # Chutzpah Test files 202 | _Chutzpah* 203 | 204 | # Visual C++ cache files 205 | ipch/ 206 | *.aps 207 | *.ncb 208 | *.opendb 209 | *.opensdf 210 | *.sdf 211 | *.cachefile 212 | *.VC.db 213 | *.VC.VC.opendb 214 | 215 | # Visual Studio profiler 216 | *.psess 217 | *.vsp 218 | *.vspx 219 | *.sap 220 | 221 | # Visual Studio Trace Files 222 | *.e2e 223 | 224 | # TFS 2012 Local Workspace 225 | $tf/ 226 | 227 | # Guidance Automation Toolkit 228 | *.gpState 229 | 230 | # ReSharper is a .NET coding add-in 231 | _ReSharper*/ 232 | *.[Rr]e[Ss]harper 233 | *.DotSettings.user 234 | 235 | # TeamCity is a build add-in 236 | _TeamCity* 237 | 238 | # DotCover is a Code Coverage Tool 239 | *.dotCover 240 | 241 | # AxoCover is a Code Coverage Tool 242 | .axoCover/* 243 | !.axoCover/settings.json 244 | 245 | # Coverlet is a free, cross platform Code Coverage Tool 246 | coverage*.json 247 | coverage*.xml 248 | coverage*.info 249 | 250 | # Visual Studio code coverage results 251 | *.coverage 252 | *.coveragexml 253 | 254 | # NCrunch 255 | _NCrunch_* 256 | .*crunch*.local.xml 257 | nCrunchTemp_* 258 | 259 | # MightyMoose 260 | *.mm.* 261 | AutoTest.Net/ 262 | 263 | # Web workbench (sass) 264 | .sass-cache/ 265 | 266 | # Installshield output folder 267 | [Ee]xpress/ 268 | 269 | # DocProject is a documentation generator add-in 270 | DocProject/buildhelp/ 271 | DocProject/Help/*.HxT 272 | DocProject/Help/*.HxC 273 | DocProject/Help/*.hhc 274 | DocProject/Help/*.hhk 275 | DocProject/Help/*.hhp 276 | DocProject/Help/Html2 277 | DocProject/Help/html 278 | 279 | # Click-Once directory 280 | publish/ 281 | 282 | # Publish Web Output 283 | *.[Pp]ublish.xml 284 | *.azurePubxml 285 | # Note: Comment the next line if you want to checkin your web deploy settings, 286 | # but database connection strings (with potential passwords) will be unencrypted 287 | *.pubxml 288 | *.publishproj 289 | 290 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 291 | # checkin your Azure Web App publish settings, but sensitive information contained 292 | # in these scripts will be unencrypted 293 | PublishScripts/ 294 | 295 | # NuGet Packages 296 | *.nupkg 297 | # NuGet Symbol Packages 298 | *.snupkg 299 | # The packages folder can be ignored because of Package Restore 300 | **/[Pp]ackages/* 301 | # except build/, which is used as an MSBuild target. 302 | !**/[Pp]ackages/build/ 303 | # Uncomment if necessary however generally it will be regenerated when needed 304 | #!**/[Pp]ackages/repositories.config 305 | # NuGet v3's project.json files produces more ignorable files 306 | *.nuget.props 307 | *.nuget.targets 308 | 309 | # Nuget personal access tokens and Credentials 310 | # nuget.config 311 | 312 | # Microsoft Azure Build Output 313 | csx/ 314 | *.build.csdef 315 | 316 | # Microsoft Azure Emulator 317 | ecf/ 318 | rcf/ 319 | 320 | # Windows Store app package directories and files 321 | AppPackages/ 322 | BundleArtifacts/ 323 | Package.StoreAssociation.xml 324 | _pkginfo.txt 325 | *.appx 326 | *.appxbundle 327 | *.appxupload 328 | 329 | # Visual Studio cache files 330 | # files ending in .cache can be ignored 331 | *.[Cc]ache 332 | # but keep track of directories ending in .cache 333 | !?*.[Cc]ache/ 334 | 335 | # Others 336 | ClientBin/ 337 | ~$* 338 | *~ 339 | *.dbmdl 340 | *.dbproj.schemaview 341 | *.jfm 342 | *.pfx 343 | *.publishsettings 344 | orleans.codegen.cs 345 | 346 | # Including strong name files can present a security risk 347 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 348 | #*.snk 349 | 350 | # Since there are multiple workflows, uncomment next line to ignore bower_components 351 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 352 | #bower_components/ 353 | 354 | # RIA/Silverlight projects 355 | Generated_Code/ 356 | 357 | # Backup & report files from converting an old project file 358 | # to a newer Visual Studio version. Backup files are not needed, 359 | # because we have git ;-) 360 | _UpgradeReport_Files/ 361 | Backup*/ 362 | UpgradeLog*.XML 363 | UpgradeLog*.htm 364 | ServiceFabricBackup/ 365 | *.rptproj.bak 366 | 367 | # SQL Server files 368 | *.mdf 369 | *.ldf 370 | *.ndf 371 | 372 | # Business Intelligence projects 373 | *.rdl.data 374 | *.bim.layout 375 | *.bim_*.settings 376 | *.rptproj.rsuser 377 | *- [Bb]ackup.rdl 378 | *- [Bb]ackup ([0-9]).rdl 379 | *- [Bb]ackup ([0-9][0-9]).rdl 380 | 381 | # Microsoft Fakes 382 | FakesAssemblies/ 383 | 384 | # GhostDoc plugin setting file 385 | *.GhostDoc.xml 386 | 387 | # Node.js Tools for Visual Studio 388 | .ntvs_analysis.dat 389 | node_modules/ 390 | 391 | # Visual Studio 6 build log 392 | *.plg 393 | 394 | # Visual Studio 6 workspace options file 395 | *.opt 396 | 397 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 398 | *.vbw 399 | 400 | # Visual Studio LightSwitch build output 401 | **/*.HTMLClient/GeneratedArtifacts 402 | **/*.DesktopClient/GeneratedArtifacts 403 | **/*.DesktopClient/ModelManifest.xml 404 | **/*.Server/GeneratedArtifacts 405 | **/*.Server/ModelManifest.xml 406 | _Pvt_Extensions 407 | 408 | # Paket dependency manager 409 | .paket/paket.exe 410 | paket-files/ 411 | 412 | # FAKE - F# Make 413 | .fake/ 414 | 415 | # CodeRush personal settings 416 | .cr/personal 417 | 418 | # Python Tools for Visual Studio (PTVS) 419 | __pycache__/ 420 | *.pyc 421 | 422 | # Cake - Uncomment if you are using it 423 | # tools/** 424 | # !tools/packages.config 425 | 426 | # Tabs Studio 427 | *.tss 428 | 429 | # Telerik's JustMock configuration file 430 | *.jmconfig 431 | 432 | # BizTalk build output 433 | *.btp.cs 434 | *.btm.cs 435 | *.odx.cs 436 | *.xsd.cs 437 | 438 | # OpenCover UI analysis results 439 | OpenCover/ 440 | 441 | # Azure Stream Analytics local run output 442 | ASALocalRun/ 443 | 444 | # MSBuild Binary and Structured Log 445 | *.binlog 446 | 447 | # NVidia Nsight GPU debugger configuration file 448 | *.nvuser 449 | 450 | # MFractors (Xamarin productivity tool) working folder 451 | .mfractor/ 452 | 453 | # Local History for Visual Studio 454 | .localhistory/ 455 | 456 | # BeatPulse healthcheck temp database 457 | healthchecksdb 458 | 459 | # Backup folder for Package Reference Convert tool in Visual Studio 2017 460 | MigrationBackup/ 461 | 462 | # Ionide (cross platform F# VS Code tools) working folder 463 | .ionide/ 464 | 465 | # Fody - auto-generated XML schema 466 | FodyWeavers.xsd 467 | 468 | # VS Code files for those working on multiple tools 469 | 470 | # Local History for Visual Studio Code 471 | 472 | # Windows Installer files from build outputs 473 | *.cab 474 | *.msi 475 | *.msix 476 | *.msm 477 | *.msp 478 | 479 | # JetBrains Rider 480 | .idea/ 481 | *.sln.iml 482 | 483 | ### VisualStudio Patch ### 484 | # Additional files built by Visual Studio 485 | 486 | # End of https://www.toptal.com/developers/gitignore/api/rider,visualstudio,visualstudiocode -------------------------------------------------------------------------------- /Directory.Build.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 1.3.0 4 | 5 | -------------------------------------------------------------------------------- /GoLive.Generator.RazorPageRoute.Generator/GoLive.Generator.RazorPageRoute.Generator.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netstandard2.0 5 | 9.0 6 | 7 | GoLive.Generator.RazorPageRoute 8 | SurgicalCoder 9 | N/A 10 | true 11 | Generates strongly typed methods that return full URL for Razor and Blazor pages. 12 | Copyright 2022 - SurgicalCoder 13 | false 14 | MIT 15 | true 16 | true 17 | true 18 | analyzers\cs 19 | true 20 | true 21 | $(BaseIntermediateOutputPath)Generated 22 | false 23 | true 24 | https://github.com/surgicalcoder/RazorPageRouteGenerator 25 | https://github.com/surgicalcoder/RazorPageRouteGenerator 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | $(GetTargetPathDependsOn);GetDependencyTargetPaths 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 54 | 55 | 56 | 57 | 58 | @(NuGetPackageId -> Distinct()) 59 | 60 | 61 | 62 | 63 | 64 | @(PackageReferenceDependency -> '%(Pack)') 65 | 66 | 67 | <_PackageFiles Include="@(RuntimeCopyLocalItems)" PackagePath="analyzers/dotnet/cs/%(Filename)%(Extension)" /> 68 | 69 | 70 | 71 | 72 | 73 | -------------------------------------------------------------------------------- /GoLive.Generator.RazorPageRoute.Generator/IsExternalInit.cs: -------------------------------------------------------------------------------- 1 | namespace System.Runtime.CompilerServices 2 | { 3 | public class IsExternalInit { } 4 | } -------------------------------------------------------------------------------- /GoLive.Generator.RazorPageRoute.Generator/PageRoute.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using Microsoft.CodeAnalysis; 3 | 4 | namespace GoLive.Generator.RazorPageRoute.Generator 5 | { 6 | public record PageRoute(string Name, string Route, List QueryString); 7 | 8 | public record PageRouteQuerystringParameter(string Name, ITypeSymbol Type); 9 | } -------------------------------------------------------------------------------- /GoLive.Generator.RazorPageRoute.Generator/PageRouteGenerator.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Diagnostics; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Text.Json; 7 | using System.Text.Json.Serialization; 8 | using Microsoft.CodeAnalysis; 9 | using Microsoft.CodeAnalysis.CSharp; 10 | 11 | namespace GoLive.Generator.RazorPageRoute.Generator 12 | { 13 | [Generator] 14 | public class PageRouteGenerator : ISourceGenerator 15 | { 16 | private GeneratorExecutionContext executionContext; 17 | private StringBuilder logBuilder; 18 | private static SymbolDisplayFormat symbolDisplayFormat = new SymbolDisplayFormat(typeQualificationStyle: SymbolDisplayTypeQualificationStyle.NameAndContainingTypesAndNamespaces); 19 | public void Initialize(GeneratorInitializationContext context) 20 | { 21 | //if (!Debugger.IsAttached) 22 | //{ 23 | // Debugger.Launch(); 24 | //} 25 | } 26 | 27 | public void Execute(GeneratorExecutionContext context) 28 | { 29 | executionContext = context; 30 | logBuilder = new StringBuilder(); 31 | 32 | 33 | var config = LoadConfig(context, defaultNamespace:context.Compilation.Assembly.Name); 34 | 35 | if (config == null) 36 | { 37 | return; 38 | } 39 | 40 | try 41 | { 42 | logBuilder.AppendLine("Output file : " + config.OutputToFile); 43 | 44 | string source = Generate(config, context); 45 | logBuilder.AppendLine(source); 46 | logBuilder.AppendLine(); 47 | logBuilder.AppendLine(); 48 | logBuilder.AppendLine(); 49 | logBuilder.AppendLine(); 50 | logBuilder.AppendLine(); 51 | 52 | if (!string.IsNullOrWhiteSpace(source)) 53 | { 54 | if (string.IsNullOrWhiteSpace(config.OutputToFile) && config.OutputToFiles.Count == 0) 55 | { 56 | context.AddSource("PageRoutes.g.cs", source); 57 | } 58 | else 59 | { 60 | if (config.OutputToFiles.Count > 0) 61 | { 62 | foreach (var configOutputToFile in config.OutputToFiles) 63 | { 64 | if (File.Exists(configOutputToFile)) 65 | { 66 | File.Delete(configOutputToFile); 67 | } 68 | 69 | File.WriteAllText(configOutputToFile, source); 70 | } 71 | } 72 | 73 | if (!string.IsNullOrWhiteSpace(config.OutputToFile)) 74 | { 75 | if (File.Exists(config.OutputToFile)) 76 | { 77 | logBuilder.AppendLine("Output file exists, deleting"); 78 | File.Delete(config.OutputToFile); 79 | } 80 | 81 | File.WriteAllText(config.OutputToFile, source); 82 | } 83 | } 84 | } 85 | else 86 | { 87 | ReportEmptyFile(); 88 | logBuilder.AppendLine("Source is empty"); 89 | } 90 | } 91 | catch (Exception e) when (e.GetType() != typeof(IOException)) 92 | { 93 | ReportError(e, Location.None); 94 | logBuilder.AppendLine(e.ToString()); 95 | throw; 96 | } 97 | catch (Exception e) 98 | { 99 | ReportError(e); 100 | } 101 | finally 102 | { 103 | if (!string.IsNullOrWhiteSpace(config.DebugOutputFile)) 104 | { 105 | File.WriteAllText(config.DebugOutputFile.Replace("(id)", Guid.NewGuid().ToString("N")), logBuilder.ToString()); 106 | } 107 | } 108 | 109 | 110 | if (config.Invokables is { Enabled: true }) 111 | { 112 | GenerateJSInvokable(config, context); 113 | } 114 | } 115 | 116 | private readonly DiagnosticDescriptor _errorRuleWithLog = new DiagnosticDescriptor("RPG0001", "RPG0001: Error in source generator", "Error in source generator<{0}>: '{1}'. Log file details: '{2}'.", "SourceGenerator", DiagnosticSeverity.Error, isEnabledByDefault: true); 117 | private readonly DiagnosticDescriptor _infoRule = new DiagnosticDescriptor("RPG0002", "RPG0002: Source code generated", "Source code generated<{0}>", "SourceGenerator", DiagnosticSeverity.Info, isEnabledByDefault: true); 118 | private readonly DiagnosticDescriptor _emptyFileRule = new DiagnosticDescriptor("RPG0003", "RPG0003: Source code output is empty", "Source code was not outputted", "SourceGenerator", DiagnosticSeverity.Warning, isEnabledByDefault: true); 119 | 120 | private void ReportEmptyFile() 121 | { 122 | executionContext.ReportDiagnostic(Diagnostic.Create(_emptyFileRule, Location.None)); 123 | } 124 | 125 | public void ReportInformation(Location? location = null) 126 | { 127 | if (location == null) 128 | { 129 | location = Location.None; 130 | } 131 | 132 | executionContext.ReportDiagnostic(Diagnostic.Create(_infoRule, location, GetType().Name)); 133 | } 134 | 135 | public void ReportError(Exception e, Location? location = null) 136 | { 137 | if (location == null) 138 | { 139 | location = Location.None; 140 | } 141 | executionContext.ReportDiagnostic(Diagnostic.Create(_errorRuleWithLog, location, GetType().Name, e.Message)); 142 | } 143 | 144 | 145 | private string Generate(Settings config, GeneratorExecutionContext context) 146 | { 147 | var source = new SourceStringBuilder(); 148 | 149 | if (config.OutputLastCreatedTime) 150 | { 151 | source.AppendLine($"// This file was generated on {DateTime.Now:R}"); 152 | } 153 | source.AppendLine("using System;"); 154 | source.AppendLine("using System.Net.Http;"); 155 | source.AppendLine("using System.Threading.Tasks;"); 156 | source.AppendLine("using System.Net.Http.Json;"); 157 | source.AppendLine("using System.Collections.Generic;"); 158 | 159 | if (config.OutputExtensionMethod) 160 | { 161 | source.AppendLine("using Microsoft.AspNetCore.Components;"); 162 | } 163 | 164 | logBuilder.AppendLine("Adding namespaces"); 165 | 166 | var routes = context.Compilation.SyntaxTrees.Select(t => context.Compilation.GetSemanticModel(t)).Select(Scanner.ScanForPageRoutes).SelectMany(c => c).ToArray(); 167 | logBuilder.AppendLine("Got Routes"); 168 | source.AppendLine($"namespace {config.Namespace}"); 169 | source.AppendOpenCurlyBracketLine(); 170 | source.AppendLine($"public static partial class {config.ClassName}"); 171 | source.AppendOpenCurlyBracketLine(); 172 | 173 | if (routes.Length == 0) 174 | { 175 | logBuilder.AppendLine("Routes is 0 length"); 176 | return null; 177 | } 178 | 179 | logBuilder.AppendLine("Foreach route"); 180 | 181 | foreach (var pageRoute in routes) 182 | { 183 | var routeTemplate = TemplateParser.ParseTemplate(pageRoute.Route); 184 | 185 | string SlugName = Slug.Create(pageRoute.Route.Length > 1 ? string.Join(".", routeTemplate.Segments.Where(f => !f.IsParameter).Select(f => f.Value)) : "Home"); 186 | 187 | if (string.IsNullOrEmpty(SlugName)) 188 | { 189 | SlugName = pageRoute.Name; 190 | } 191 | 192 | var routeSegments = routeTemplate.Segments.Where(e => e.IsParameter).Select(delegate(TemplateSegment segment) 193 | { 194 | var constraint = segment.Constraints.Any() ? segment.Constraints.FirstOrDefault().GetConstraintType() : null; 195 | 196 | if (constraint == null) 197 | { 198 | return $"string {segment.Value}"; 199 | } 200 | 201 | return segment.IsOptional ? $"{constraint.FullName}? {segment.Value}" : $"{constraint.FullName} {segment.Value}"; 202 | }).ToList(); 203 | 204 | if (pageRoute.QueryString is {Count: > 0}) 205 | { 206 | routeSegments.AddRange(pageRoute.QueryString.Select(prqp => $"{prqp.Type.ToDisplayString()}{(prqp.Type.IsReferenceType ? "?" : "")} {prqp.Name} = default")); 207 | } 208 | 209 | var parameterString = string.Join(", ", routeSegments); 210 | 211 | OutputRouteStringMethod(source, SlugName, parameterString, routeTemplate, pageRoute); 212 | 213 | if (config.OutputExtensionMethod) 214 | { 215 | OutputRouteExtensionMethod(source, SlugName, parameterString, routeTemplate, pageRoute); 216 | } 217 | } 218 | logBuilder.AppendLine("Done, returning"); 219 | source.AppendCloseCurlyBracketLine(); 220 | source.AppendCloseCurlyBracketLine(); 221 | 222 | var outp = source.ToString(); 223 | 224 | return outp; 225 | } 226 | 227 | 228 | private void OutputRouteExtensionMethod(SourceStringBuilder source, string SlugName, string parameterString, RouteTemplate routeTemplate, PageRoute pageRoute) 229 | { 230 | logBuilder.AppendLine("OutputRouteExtensionMethod"); 231 | 232 | if (string.IsNullOrWhiteSpace(parameterString)) 233 | { 234 | source.AppendLine($"public static void {SlugName} (this NavigationManager manager, bool forceLoad = false, bool replace=false)"); 235 | } 236 | else 237 | { 238 | source.AppendLine($"public static void {SlugName} (this NavigationManager manager, {parameterString}, bool forceLoad = false, bool replace=false)"); 239 | } 240 | source.AppendOpenCurlyBracketLine(); 241 | 242 | if (routeTemplate.Segments.Any(e => e.IsParameter)) 243 | { 244 | source.AppendIndent(); 245 | source.Append("string url = $\"", false); 246 | 247 | foreach (var seg in routeTemplate.Segments) 248 | { 249 | if (seg.IsParameter) 250 | { 251 | source.Append($"/{{{seg.Value}.ToString()}}", false); 252 | } 253 | else 254 | { 255 | source.Append($"/{seg.Value}", false); 256 | } 257 | } 258 | 259 | source.Append("\";\n", false); 260 | } 261 | else 262 | { 263 | source.AppendLine($"string url = \"{pageRoute.Route}\";"); 264 | } 265 | 266 | if (pageRoute.QueryString is { Count: > 0 }) 267 | { 268 | source.AppendLine("Dictionary queryString=new();"); 269 | 270 | foreach (var pageRouteQuerystringParameter in pageRoute.QueryString) 271 | { 272 | if (pageRouteQuerystringParameter.Type.ToDisplayString(symbolDisplayFormat) == "System.String") 273 | { 274 | source.AppendLine($"if (!string.IsNullOrWhiteSpace({pageRouteQuerystringParameter.Name})) "); 275 | } 276 | else 277 | { 278 | source.AppendLine($"if ({pageRouteQuerystringParameter.Name} != default) "); 279 | } 280 | 281 | source.AppendOpenCurlyBracketLine(); 282 | source.AppendLine($"queryString.Add(\"{pageRouteQuerystringParameter.Name}\", {pageRouteQuerystringParameter.Name}.ToString());"); 283 | source.AppendCloseCurlyBracketLine(); 284 | } 285 | 286 | source.AppendLine(""); 287 | source.AppendLine("url = Microsoft.AspNetCore.WebUtilities.QueryHelpers.AddQueryString(url, queryString);"); 288 | } 289 | 290 | source.AppendLine("manager.NavigateTo(url, forceLoad, replace);"); 291 | source.AppendCloseCurlyBracketLine(); 292 | } 293 | 294 | private void OutputRouteStringMethod(SourceStringBuilder source, string SlugName, string parameterString, RouteTemplate routeTemplate, PageRoute pageRoute) 295 | { 296 | logBuilder.AppendLine("Before creation #1"); 297 | 298 | source.AppendLine($"public static string {SlugName} ({parameterString})"); 299 | source.AppendOpenCurlyBracketLine(); 300 | logBuilder.AppendLine("Foreach Param"); 301 | 302 | if (routeTemplate.Segments.Any(e => e.IsParameter)) 303 | { 304 | source.AppendIndent(); 305 | source.Append("string url = $\"", false); 306 | 307 | foreach (var seg in routeTemplate.Segments) 308 | { 309 | if (seg.IsParameter) 310 | { 311 | source.Append($"/{{{seg.Value}.ToString()}}", false); 312 | } 313 | else 314 | { 315 | source.Append($"/{seg.Value}", false); 316 | } 317 | } 318 | 319 | source.Append("\";\n", false); 320 | } 321 | else 322 | { 323 | source.AppendLine($"string url = \"{pageRoute.Route}\";"); 324 | } 325 | 326 | if (pageRoute.QueryString is { Count: > 0 }) 327 | { 328 | source.AppendLine("Dictionary queryString=new();"); 329 | 330 | foreach (var pageRouteQuerystringParameter in pageRoute.QueryString) 331 | { 332 | if (pageRouteQuerystringParameter.Type.ToDisplayString(symbolDisplayFormat) == "System.String") 333 | { 334 | source.AppendLine($"if (!string.IsNullOrWhiteSpace({pageRouteQuerystringParameter.Name})) "); 335 | } 336 | else 337 | { 338 | source.AppendLine($"if ({pageRouteQuerystringParameter.Name} != default) "); 339 | } 340 | 341 | source.AppendOpenCurlyBracketLine(); 342 | source.AppendLine($"queryString.Add(\"{pageRouteQuerystringParameter.Name}\", {pageRouteQuerystringParameter.Name}.ToString());"); 343 | source.AppendCloseCurlyBracketLine(); 344 | } 345 | 346 | source.AppendLine(""); 347 | source.AppendLine("url = Microsoft.AspNetCore.WebUtilities.QueryHelpers.AddQueryString(url, queryString);"); 348 | } 349 | 350 | source.AppendLine($"return url;"); 351 | 352 | source.AppendCloseCurlyBracketLine(); 353 | } 354 | 355 | private Settings LoadConfig(GeneratorExecutionContext context, string defaultNamespace) 356 | { 357 | var configFilePath = context.AdditionalFiles.FirstOrDefault(e => e.Path.ToLowerInvariant().EndsWith("razorpageroutes.json")); 358 | 359 | if (configFilePath == null) 360 | { 361 | var settings = new Settings(); 362 | settings.Namespace = defaultNamespace; 363 | settings.ClassName = "PageRoutes"; 364 | return settings; 365 | } 366 | 367 | var jsonString = File.ReadAllText(configFilePath.Path); 368 | var config = JsonSerializer.Deserialize(jsonString); 369 | var configFileDirectory = Path.GetDirectoryName(configFilePath.Path); 370 | 371 | if (string.IsNullOrEmpty(config.Namespace)) 372 | { 373 | config.Namespace = defaultNamespace; 374 | } 375 | 376 | if (!string.IsNullOrWhiteSpace(config.OutputToFile)) 377 | { 378 | var fullPath = Path.Combine(configFileDirectory, config.OutputToFile); 379 | config.OutputToFile = Path.GetFullPath(fullPath); 380 | } 381 | 382 | if (config.Invokables != null && (!string.IsNullOrWhiteSpace(config.Invokables.OutputToFile) || config.Invokables.OutputToFiles.Count > 0)) 383 | { 384 | if (!string.IsNullOrWhiteSpace(config.Invokables.OutputToFile)) 385 | { 386 | var fullPath = Path.Combine(configFileDirectory, config.Invokables.OutputToFile); 387 | config.Invokables.OutputToFile = Path.GetFullPath(fullPath); 388 | } 389 | 390 | foreach (var outputFile in config.Invokables.OutputToFiles) 391 | { 392 | var fullPath = Path.Combine(configFileDirectory, outputFile); 393 | var index = config.Invokables.OutputToFiles.IndexOf(outputFile); 394 | config.Invokables.OutputToFiles[index] = Path.GetFullPath(fullPath); 395 | } 396 | } 397 | 398 | if (config.OutputToFiles != null && config.OutputToFiles.Any()) 399 | { 400 | config.OutputToFiles = config.OutputToFiles.Select(r => 401 | { 402 | var fullPath = Path.Combine(configFileDirectory, r); 403 | return fullPath; 404 | }).ToList(); 405 | } 406 | 407 | return config; 408 | } 409 | 410 | 411 | private void GenerateJSInvokable(Settings config, GeneratorExecutionContext context) 412 | { 413 | var invokables = context.Compilation.SyntaxTrees.Select(t => context.Compilation.GetSemanticModel(t)).Select(Scanner.ScanForInvokables).SelectMany(c => c).ToArray(); 414 | 415 | if (invokables.Length == 0) 416 | { 417 | return; 418 | } 419 | 420 | var jsBuilder = new StringBuilder(); 421 | jsBuilder.AppendLine($"const {config.Invokables.JSClassName} = {{"); 422 | 423 | foreach (var (methodName, invokableName) in invokables) 424 | { 425 | jsBuilder.AppendLine($"{methodName.Replace(".","_")}: \"{invokableName}\", "); 426 | } 427 | 428 | jsBuilder.AppendLine("};"); 429 | 430 | if (!string.IsNullOrWhiteSpace(config.Invokables.OutputToFile)) 431 | { 432 | File.WriteAllText(config.Invokables.OutputToFile, jsBuilder.ToString()); 433 | } 434 | 435 | if (config.Invokables.OutputToFiles.Count > 0) 436 | { 437 | foreach (var outputPath in config.Invokables.OutputToFiles) 438 | { 439 | File.WriteAllText(outputPath, jsBuilder.ToString()); 440 | } 441 | } 442 | } 443 | } 444 | } -------------------------------------------------------------------------------- /GoLive.Generator.RazorPageRoute.Generator/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json.schemastore.org/launchsettings.json", 3 | "profiles": { 4 | "GoLive.Generator.RazorPageRoute.Generator": { 5 | "commandName": "DebugRoslynComponent", 6 | "targetProject": "../GoLive.Generator.RazorPageRoute.Tests.BlazorWebAsssembly/GoLive.Generator.RazorPageRoute.Tests.BlazorWebAsssembly.csproj" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /GoLive.Generator.RazorPageRoute.Generator/RouteConstraint.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace GoLive.Generator.RazorPageRoute.Generator 4 | { 5 | internal static class RouteConstraint 6 | { 7 | public static UrlValueConstraint Parse(string template, string segment, string constraint) 8 | { 9 | if (string.IsNullOrEmpty(constraint)) 10 | { 11 | throw new ArgumentException($"Malformed segment '{segment}' in route '{template}' contains an empty constraint."); 12 | } 13 | 14 | var targetType = GetTargetType(constraint); 15 | if (targetType is null || !UrlValueConstraint.TryGetByTargetType(targetType, out var result)) 16 | { 17 | throw new ArgumentException($"Unsupported constraint '{constraint}' in route '{template}'."); 18 | } 19 | 20 | return result; 21 | } 22 | 23 | private static Type? GetTargetType(string constraint) => constraint switch 24 | { 25 | "bool" => typeof(bool), 26 | "datetime" => typeof(DateTime), 27 | "decimal" => typeof(decimal), 28 | "double" => typeof(double), 29 | "float" => typeof(float), 30 | "guid" => typeof(Guid), 31 | "int" => typeof(int), 32 | "long" => typeof(long), 33 | "nonfile" => typeof(string), 34 | _ => null, 35 | }; 36 | } 37 | } -------------------------------------------------------------------------------- /GoLive.Generator.RazorPageRoute.Generator/RouteTemplate.cs: -------------------------------------------------------------------------------- 1 | using System.Diagnostics; 2 | 3 | namespace GoLive.Generator.RazorPageRoute.Generator 4 | { 5 | [DebuggerDisplay("{TemplateText}")] 6 | internal class RouteTemplate 7 | { 8 | public RouteTemplate(string templateText, TemplateSegment[] segments) 9 | { 10 | TemplateText = templateText; 11 | Segments = segments; 12 | 13 | for (var i = 0; i < segments.Length; i++) 14 | { 15 | var segment = segments[i]; 16 | if (segment.IsOptional) 17 | { 18 | OptionalSegmentsCount++; 19 | } 20 | if (segment.IsCatchAll) 21 | { 22 | ContainsCatchAllSegment = true; 23 | } 24 | } 25 | } 26 | 27 | public string TemplateText { get; } 28 | 29 | public TemplateSegment[] Segments { get; } 30 | 31 | public int OptionalSegmentsCount { get; } 32 | 33 | public bool ContainsCatchAllSegment { get; } 34 | } 35 | } -------------------------------------------------------------------------------- /GoLive.Generator.RazorPageRoute.Generator/Scanner.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using Microsoft.CodeAnalysis; 5 | using Microsoft.CodeAnalysis.CSharp.Syntax; 6 | 7 | namespace GoLive.Generator.RazorPageRoute.Generator 8 | { 9 | public static class Scanner 10 | { 11 | public const string jsInvokableAttribute = "Microsoft.JSInterop.JSInvokableAttribute"; 12 | 13 | public static IEnumerable<(string MethodName, string InvokableName)> ScanForInvokables(SemanticModel semantic) 14 | { 15 | var baseClass = semantic.Compilation.GetTypeByMetadataName("Microsoft.AspNetCore.Components.ComponentBase"); 16 | 17 | if (baseClass == null) 18 | { 19 | yield break; 20 | } 21 | 22 | var allNodes = semantic.SyntaxTree.GetRoot().DescendantNodes().OfType(); 23 | 24 | foreach (var node in allNodes) 25 | { 26 | if (semantic.GetDeclaredSymbol(node) is INamedTypeSymbol classSymbol && InheritsFrom(classSymbol, baseClass)) 27 | { 28 | 29 | foreach (var member in classSymbol.GetMembers().OfType()) 30 | { 31 | // Check if the method has the attribute [JSInvokable(string)] 32 | if (member.GetAttributes().Any(attr => 33 | attr.AttributeClass?.ToString() == jsInvokableAttribute && 34 | attr.ConstructorArguments.Length > 0 && 35 | attr.ConstructorArguments[0].Value is string)) 36 | { 37 | // Extract method name 38 | string methodName = member.Name; 39 | 40 | // Extract parameter count 41 | int parameterCount = member.Parameters.Length; 42 | 43 | // Extract identifier in the attribute 44 | string identifier = member.GetAttributes().First(attr => 45 | attr.AttributeClass?.ToString() == jsInvokableAttribute && 46 | attr.ConstructorArguments.Length > 0 && 47 | attr.ConstructorArguments[0].Value is string) 48 | .ConstructorArguments[0].Value.ToString(); 49 | 50 | yield return ($"{member.ContainingType.ToDisplayString()}.{member.Name}", identifier); 51 | } 52 | } 53 | 54 | } 55 | } 56 | } 57 | 58 | public static IEnumerable ScanForPageRoutes(SemanticModel semantic) 59 | { 60 | var baseClass = semantic.Compilation.GetTypeByMetadataName("Microsoft.AspNetCore.Components.ComponentBase"); 61 | 62 | if (baseClass == null) 63 | { 64 | yield break; 65 | } 66 | 67 | var allNodes = semantic.SyntaxTree.GetRoot().DescendantNodes().OfType(); 68 | 69 | foreach (var node in allNodes) 70 | { 71 | if (semantic.GetDeclaredSymbol(node) is INamedTypeSymbol classSymbol && InheritsFrom(classSymbol, baseClass)) 72 | { 73 | var res = ToRoute(classSymbol); 74 | 75 | foreach (var pageRoute in res) 76 | { 77 | yield return pageRoute; 78 | } 79 | } 80 | } 81 | } 82 | 83 | private static IEnumerable ToRoute(INamedTypeSymbol classSymbol) 84 | { 85 | var attributes = FindAttributes(classSymbol, a => a.ToString() == "Microsoft.AspNetCore.Components.RouteAttribute"); 86 | 87 | var queryStringParams = classSymbol.GetMembers().OfType(); 88 | var querystringParameters = (from qsParam in queryStringParams let qsAttr = FindAttribute(qsParam, a => a.ToString() == "Microsoft.AspNetCore.Components.SupplyParameterFromQueryAttribute") where qsAttr != null select new PageRouteQuerystringParameter(qsAttr?.ConstructorArguments.FirstOrDefault().Value?.ToString() ?? qsParam.Name, qsParam.Type)).ToList(); 89 | 90 | foreach (var attributeData in attributes) 91 | { 92 | var route = attributeData?.ConstructorArguments.FirstOrDefault().Value?.ToString() ?? string.Empty; 93 | 94 | yield return new PageRoute(classSymbol.Name, route, querystringParameters); 95 | } 96 | } 97 | 98 | private static IEnumerable FindAttributes(ISymbol symbol, Func selectAttribute) => symbol.GetAttributes().Where(a => a?.AttributeClass != null && selectAttribute(a.AttributeClass)); 99 | 100 | private static AttributeData? FindAttribute(ISymbol symbol, Func selectAttribute) => symbol.GetAttributes().LastOrDefault(a => a?.AttributeClass != null && selectAttribute(a.AttributeClass)); 101 | 102 | private static bool InheritsFrom(INamedTypeSymbol classDeclaration, INamedTypeSymbol targetBaseType) 103 | { 104 | var currentDeclared = classDeclaration; 105 | 106 | while (currentDeclared.BaseType != null) 107 | { 108 | var currentBaseType = currentDeclared.BaseType; 109 | 110 | if (currentBaseType.Equals(targetBaseType, SymbolEqualityComparer.Default)) 111 | { 112 | return true; 113 | } 114 | 115 | currentDeclared = currentDeclared.BaseType; 116 | } 117 | 118 | return false; 119 | } 120 | } 121 | } -------------------------------------------------------------------------------- /GoLive.Generator.RazorPageRoute.Generator/Settings.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace GoLive.Generator.RazorPageRoute.Generator 4 | { 5 | public class Settings 6 | { 7 | public string Namespace { get; set; } 8 | public string ClassName { get; set; } 9 | 10 | public string OutputToFile { get; set; } 11 | public List OutputToFiles { get; set; } = new(); 12 | 13 | public string DebugOutputFile { get; set; } 14 | 15 | public bool OutputLastCreatedTime { get; set; } 16 | 17 | public bool OutputExtensionMethod { get; set; } 18 | 19 | public Settings_JSInvokables Invokables { get; set; } = new(); 20 | } 21 | 22 | public class Settings_JSInvokables 23 | { 24 | public bool Enabled { get; set; } 25 | public string OutputToFile { get; set; } 26 | public List OutputToFiles { get; set; } = new(); 27 | public string JSClassName { get; set; } 28 | 29 | } 30 | } -------------------------------------------------------------------------------- /GoLive.Generator.RazorPageRoute.Generator/Slug.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | using System.Text; 4 | 5 | namespace GoLive.Generator.RazorPageRoute.Generator 6 | { 7 | /// 8 | /// Defines a set of utilities for creating slug urls. 9 | /// 10 | public static class Slug 11 | { 12 | /// 13 | /// Creates a slug from the specified text. 14 | /// 15 | /// The text. If null if specified, null will be returned. 16 | /// 17 | /// A slugged text. 18 | /// 19 | public static string Create(string text) 20 | { 21 | return Create(text, (SlugOptions)null); 22 | } 23 | 24 | /// 25 | /// Creates a slug from the specified text. 26 | /// 27 | /// The text. If null if specified, null will be returned. 28 | /// The options. May be null. 29 | /// A slugged text. 30 | public static string Create(string text, SlugOptions options) 31 | { 32 | if (text == null) return null; 33 | 34 | if (options == null) 35 | { 36 | options = new SlugOptions(); 37 | } 38 | 39 | string normalised; 40 | 41 | if (options.EarlyTruncate && options.MaximumLength > 0 && text.Length > options.MaximumLength) 42 | { 43 | normalised = text.Substring(0, options.MaximumLength).Normalize(NormalizationForm.FormD); 44 | } 45 | else 46 | { 47 | normalised = text.Normalize(NormalizationForm.FormD); 48 | } 49 | 50 | int max = options.MaximumLength > 0 ? Math.Min(normalised.Length, options.MaximumLength) : normalised.Length; 51 | StringBuilder sb = new StringBuilder(max); 52 | 53 | for (int i = 0; i < normalised.Length; i++) 54 | { 55 | char c = normalised[i]; 56 | UnicodeCategory uc = char.GetUnicodeCategory(c); 57 | 58 | if (options.AllowedUnicodeCategories.Contains(uc) && options.IsAllowed(c)) 59 | { 60 | switch (uc) 61 | { 62 | case UnicodeCategory.UppercaseLetter: 63 | if (options.ToLower) 64 | { 65 | c = options.Culture != null ? char.ToLower(c, options.Culture) : char.ToLowerInvariant(c); 66 | } 67 | 68 | sb.Append(options.Replace(c)); 69 | 70 | break; 71 | 72 | case UnicodeCategory.LowercaseLetter: 73 | if (options.ToUpper) 74 | { 75 | c = options.Culture != null ? char.ToUpper(c, options.Culture) : char.ToUpperInvariant(c); 76 | } 77 | 78 | sb.Append(options.Replace(c)); 79 | 80 | break; 81 | 82 | default: 83 | sb.Append(options.Replace(c)); 84 | 85 | break; 86 | } 87 | } 88 | else if (uc == UnicodeCategory.NonSpacingMark) 89 | { 90 | // don't add a separator 91 | } 92 | else 93 | { 94 | if (options.Separator != null && !EndsWith(sb, options.Separator)) 95 | { 96 | sb.Append(options.Separator); 97 | } 98 | } 99 | 100 | if (options.MaximumLength > 0 && sb.Length >= options.MaximumLength) break; 101 | } 102 | 103 | string result = sb.ToString(); 104 | 105 | if (options.MaximumLength > 0 && result.Length > options.MaximumLength) 106 | { 107 | result = result.Substring(0, options.MaximumLength); 108 | } 109 | 110 | if (!options.CanEndWithSeparator && options.Separator != null && result.EndsWith(options.Separator)) 111 | { 112 | result = result.Substring(0, result.Length - options.Separator.Length); 113 | } 114 | 115 | return result.Normalize(NormalizationForm.FormC); 116 | } 117 | 118 | private static bool EndsWith(StringBuilder sb, string text) 119 | { 120 | if (sb.Length < text.Length) return false; 121 | 122 | for (int i = 0; i < text.Length; i++) 123 | { 124 | if (sb[sb.Length - 1 - i] != text[text.Length - 1 - i]) return false; 125 | } 126 | 127 | return true; 128 | } 129 | } 130 | } -------------------------------------------------------------------------------- /GoLive.Generator.RazorPageRoute.Generator/SlugOptions.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Globalization; 3 | 4 | namespace GoLive.Generator.RazorPageRoute.Generator 5 | { 6 | /// 7 | /// Defines options for the Slug utility class. 8 | /// 9 | public class SlugOptions 10 | { 11 | /// 12 | /// Defines the default maximum length. Currently equal to 80. 13 | /// 14 | public const int DefaultMaximumLength = 80; 15 | 16 | /// 17 | /// Defines the default separator. Currently equal to "-". 18 | /// 19 | public const string DefaultSeparator = "_"; 20 | 21 | private bool _toLower; 22 | private bool _toUpper; 23 | 24 | /// 25 | /// Initializes a new instance of the class. 26 | /// 27 | public SlugOptions() 28 | { 29 | MaximumLength = DefaultMaximumLength; 30 | Separator = DefaultSeparator; 31 | AllowedUnicodeCategories = new List(); 32 | AllowedUnicodeCategories.Add(UnicodeCategory.UppercaseLetter); 33 | AllowedUnicodeCategories.Add(UnicodeCategory.LowercaseLetter); 34 | AllowedUnicodeCategories.Add(UnicodeCategory.DecimalDigitNumber); 35 | AllowedRanges = new List>(); 36 | AllowedRanges.Add(new KeyValuePair((short)'a', (short)'z')); 37 | AllowedRanges.Add(new KeyValuePair((short)'A', (short)'Z')); 38 | AllowedRanges.Add(new KeyValuePair((short)'0', (short)'9')); 39 | } 40 | 41 | /// 42 | /// Gets the allowed unicode categories list. 43 | /// 44 | /// 45 | /// The allowed unicode categories list. 46 | /// 47 | public virtual IList AllowedUnicodeCategories { get; private set; } 48 | 49 | /// 50 | /// Gets the allowed ranges list. 51 | /// 52 | /// 53 | /// The allowed ranges list. 54 | /// 55 | public virtual IList> AllowedRanges { get; private set; } 56 | 57 | /// 58 | /// Gets or sets the maximum length. 59 | /// 60 | /// 61 | /// The maximum length. 62 | /// 63 | public virtual int MaximumLength { get; set; } 64 | 65 | /// 66 | /// Gets or sets the separator. 67 | /// 68 | /// 69 | /// The separator. 70 | /// 71 | public virtual string Separator { get; set; } 72 | 73 | /// 74 | /// Gets or sets the culture for case conversion. 75 | /// 76 | /// 77 | /// The culture. 78 | /// 79 | public virtual CultureInfo Culture { get; set; } 80 | 81 | /// 82 | /// Gets or sets a value indicating whether the string can end with a separator string. 83 | /// 84 | /// 85 | /// true if the string can end with a separator string; otherwise, false. 86 | /// 87 | public virtual bool CanEndWithSeparator { get; set; } 88 | 89 | /// 90 | /// Gets or sets a value indicating whether the string is truncated before normalization. 91 | /// 92 | /// 93 | /// true if the string is truncated before normalization; otherwise, false. 94 | /// 95 | public virtual bool EarlyTruncate { get; set; } 96 | 97 | /// 98 | /// Gets or sets a value indicating whether to lowercase the resulting string. 99 | /// 100 | /// 101 | /// true if the resulting string must be lowercased; otherwise, false. 102 | /// 103 | public virtual bool ToLower 104 | { 105 | get { return _toLower; } 106 | set 107 | { 108 | _toLower = value; 109 | 110 | if (_toLower) 111 | { 112 | _toUpper = false; 113 | } 114 | } 115 | } 116 | 117 | /// 118 | /// Gets or sets a value indicating whether to uppercase the resulting string. 119 | /// 120 | /// 121 | /// true if the resulting string must be uppercased; otherwise, false. 122 | /// 123 | public virtual bool ToUpper 124 | { 125 | get { return _toUpper; } 126 | set 127 | { 128 | _toUpper = value; 129 | 130 | if (_toUpper) 131 | { 132 | _toLower = false; 133 | } 134 | } 135 | } 136 | 137 | /// 138 | /// Determines whether the specified character is allowed. 139 | /// 140 | /// The character. 141 | /// true if the character is allowed; false otherwise. 142 | public virtual bool IsAllowed(char character) 143 | { 144 | foreach (var p in AllowedRanges) 145 | { 146 | if (character >= p.Key && character <= p.Value) return true; 147 | } 148 | 149 | return false; 150 | } 151 | 152 | /// 153 | /// Replaces the specified character by a given string. 154 | /// 155 | /// The character to replace. 156 | /// a string. 157 | public virtual string Replace(char character) 158 | { 159 | return character.ToString(); 160 | } 161 | } 162 | } -------------------------------------------------------------------------------- /GoLive.Generator.RazorPageRoute.Generator/SourceStringBuilder.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Text; 3 | using Microsoft.CodeAnalysis; 4 | using Microsoft.CodeAnalysis.CSharp; 5 | 6 | namespace GoLive.Generator.RazorPageRoute.Generator 7 | { 8 | public class SourceStringBuilder 9 | { 10 | private readonly string SingleIndent = new string(' ', 4); 11 | 12 | public int IndentLevel = 0; 13 | private readonly StringBuilder _stringBuilder; 14 | 15 | public SourceStringBuilder() 16 | { 17 | _stringBuilder = new StringBuilder(); 18 | } 19 | 20 | public void IncreaseIndent() 21 | { 22 | IndentLevel++; 23 | } 24 | 25 | public void DecreaseIndent() 26 | { 27 | IndentLevel--; 28 | } 29 | 30 | public void AppendOpenCurlyBracketLine() 31 | { 32 | AppendLine("{"); 33 | IncreaseIndent(); 34 | } 35 | 36 | public void AppendCloseCurlyBracketLine() 37 | { 38 | DecreaseIndent(); 39 | AppendLine("}"); 40 | } 41 | 42 | public void Append(string text, bool indent = true) 43 | { 44 | if (indent) 45 | { 46 | AppendIndent(); 47 | } 48 | 49 | _stringBuilder.Append(text); 50 | } 51 | 52 | public void AppendIndent() 53 | { 54 | for (int i = 0; i < IndentLevel; i++) 55 | { 56 | _stringBuilder.Append(SingleIndent); 57 | } 58 | } 59 | 60 | public void AppendLine() 61 | { 62 | _stringBuilder.Append(Environment.NewLine); 63 | } 64 | 65 | public void AppendLine(string text) 66 | { 67 | Append(text); 68 | AppendLine(); 69 | } 70 | 71 | public override string ToString() 72 | { 73 | var text = _stringBuilder.ToString(); 74 | return string.IsNullOrWhiteSpace(text) 75 | ? string.Empty 76 | : CSharpSyntaxTree.ParseText(text).GetRoot().NormalizeWhitespace().SyntaxTree.GetText().ToString(); 77 | } 78 | } 79 | } -------------------------------------------------------------------------------- /GoLive.Generator.RazorPageRoute.Generator/StringSegmentAccumulator.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace GoLive.Generator.RazorPageRoute.Generator 5 | { 6 | internal struct StringSegmentAccumulator 7 | { 8 | private int count; 9 | private ReadOnlyMemory _single; 10 | private List>? _multiple; 11 | 12 | public ReadOnlyMemory this[int index] 13 | { 14 | get 15 | { 16 | if (index >= count) 17 | { 18 | throw new IndexOutOfRangeException(); 19 | } 20 | 21 | return count == 1 ? _single : _multiple![index]; 22 | } 23 | } 24 | 25 | public int Count => count; 26 | 27 | public void SetSingle(ReadOnlyMemory value) 28 | { 29 | _single = value; 30 | 31 | if (count != 1) 32 | { 33 | if (count > 1) 34 | { 35 | _multiple = null; 36 | } 37 | 38 | count = 1; 39 | } 40 | } 41 | 42 | public void Add(ReadOnlyMemory value) 43 | { 44 | switch (count++) 45 | { 46 | case 0: 47 | _single = value; 48 | break; 49 | case 1: 50 | _multiple = new(); 51 | _multiple.Add(_single); 52 | _multiple.Add(value); 53 | _single = default; 54 | break; 55 | default: 56 | _multiple!.Add(value); 57 | break; 58 | } 59 | } 60 | } 61 | } -------------------------------------------------------------------------------- /GoLive.Generator.RazorPageRoute.Generator/TemplateParser.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace GoLive.Generator.RazorPageRoute.Generator 4 | { 5 | internal class TemplateParser 6 | { 7 | public static readonly char[] InvalidParameterNameCharacters = 8 | new char[] { '{', '}', '=', '.' }; 9 | 10 | internal static RouteTemplate ParseTemplate(string template) 11 | { 12 | var originalTemplate = template; 13 | template = template.Trim('/'); 14 | if (template == string.Empty) 15 | { 16 | // Special case "/"; 17 | return new RouteTemplate("/", Array.Empty()); 18 | } 19 | 20 | var segments = template.Split('/'); 21 | var templateSegments = new TemplateSegment[segments.Length]; 22 | for (int i = 0; i < segments.Length; i++) 23 | { 24 | var segment = segments[i]; 25 | if (string.IsNullOrEmpty(segment)) 26 | { 27 | throw new InvalidOperationException( 28 | $"Invalid template '{template}'. Empty segments are not allowed."); 29 | } 30 | 31 | if (segment[0] != '{') 32 | { 33 | if (segment[segment.Length - 1] == '}') 34 | { 35 | throw new InvalidOperationException( 36 | $"Invalid template '{template}'. Missing '{{' in parameter segment '{segment}'."); 37 | } 38 | if (segment.Substring(segment.Length - 1) == "?") 39 | { 40 | throw new InvalidOperationException( 41 | $"Invalid template '{template}'. '?' is not allowed in literal segment '{segment}'."); 42 | } 43 | templateSegments[i] = new TemplateSegment(originalTemplate, segment, isParameter: false); 44 | } 45 | else 46 | { 47 | if (segment[segment.Length - 1] != '}') 48 | { 49 | throw new InvalidOperationException( 50 | $"Invalid template '{template}'. Missing '}}' in parameter segment '{segment}'."); 51 | } 52 | 53 | if (segment.Length < 3) 54 | { 55 | throw new InvalidOperationException( 56 | $"Invalid template '{template}'. Empty parameter name in segment '{segment}' is not allowed."); 57 | } 58 | 59 | var invalidCharacter = segment.IndexOfAny(InvalidParameterNameCharacters, 1, segment.Length - 2); 60 | if (invalidCharacter != -1) 61 | { 62 | throw new InvalidOperationException( 63 | $"Invalid template '{template}'. The character '{segment[invalidCharacter]}' in parameter segment '{segment}' is not allowed."); 64 | } 65 | 66 | templateSegments[i] = new TemplateSegment(originalTemplate, segment.Substring(1, segment.Length - 2), isParameter: true); 67 | } 68 | } 69 | 70 | for (int i = 0; i < templateSegments.Length; i++) 71 | { 72 | var currentSegment = templateSegments[i]; 73 | 74 | if (currentSegment.IsCatchAll && i != templateSegments.Length - 1) 75 | { 76 | throw new InvalidOperationException($"Invalid template '{template}'. A catch-all parameter can only appear as the last segment of the route template."); 77 | } 78 | 79 | if (!currentSegment.IsParameter) 80 | { 81 | continue; 82 | } 83 | 84 | for (int j = i + 1; j < templateSegments.Length; j++) 85 | { 86 | var nextSegment = templateSegments[j]; 87 | 88 | if (currentSegment.IsOptional && !nextSegment.IsOptional && !nextSegment.IsCatchAll) 89 | { 90 | throw new InvalidOperationException($"Invalid template '{template}'. Non-optional parameters or literal routes cannot appear after optional parameters."); 91 | } 92 | 93 | if (string.Equals(currentSegment.Value, nextSegment.Value, StringComparison.OrdinalIgnoreCase)) 94 | { 95 | throw new InvalidOperationException( 96 | $"Invalid template '{template}'. The parameter '{currentSegment}' appears multiple times."); 97 | } 98 | } 99 | } 100 | 101 | return new RouteTemplate(template, templateSegments); 102 | } 103 | } 104 | } -------------------------------------------------------------------------------- /GoLive.Generator.RazorPageRoute.Generator/TemplateSegment.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace GoLive.Generator.RazorPageRoute.Generator 4 | { 5 | internal class TemplateSegment 6 | { 7 | public TemplateSegment(string template, string segment, bool isParameter) 8 | { 9 | IsParameter = isParameter; 10 | 11 | IsCatchAll = isParameter && segment.StartsWith('*'.ToString()); 12 | 13 | if (IsCatchAll) 14 | { 15 | // Only one '*' currently allowed 16 | Value = segment.Substring(1); 17 | 18 | var invalidCharacterIndex = Value.IndexOf('*'); 19 | if (invalidCharacterIndex != -1) 20 | { 21 | throw new InvalidOperationException($"Invalid template '{template}'. A catch-all parameter may only have one '*' at the beginning of the segment."); 22 | } 23 | } 24 | else 25 | { 26 | Value = segment; 27 | } 28 | 29 | // Process segments that parameters that do not contain a token separating a type constraint. 30 | if (IsParameter) 31 | { 32 | if (Value.IndexOf(':') < 0) 33 | { 34 | 35 | // Set the IsOptional flag to true for segments that contain 36 | // a parameter with no type constraints but optionality set 37 | // via the '?' token. 38 | var questionMarkIndex = Value.IndexOf('?'); 39 | if (questionMarkIndex == Value.Length - 1) 40 | { 41 | IsOptional = true; 42 | Value = Value.Substring(0, Value.Length - 1); 43 | } 44 | // If the `?` optional marker shows up in the segment but not at the very end, 45 | // then throw an error. 46 | else if (questionMarkIndex >= 0) 47 | { 48 | throw new ArgumentException($"Malformed parameter '{segment}' in route '{template}'. '?' character can only appear at the end of parameter name."); 49 | } 50 | 51 | Constraints = Array.Empty(); 52 | } 53 | else 54 | { 55 | var tokens = Value.Split(':'); 56 | if (tokens[0].Length == 0) 57 | { 58 | throw new ArgumentException($"Malformed parameter '{segment}' in route '{template}' has no name before the constraints list."); 59 | } 60 | 61 | Value = tokens[0]; 62 | IsOptional = tokens[tokens.Length - 1].EndsWith('?'.ToString()); 63 | if (IsOptional) 64 | { 65 | tokens[tokens.Length - 1] = tokens[tokens.Length - 1].Substring(0, tokens[tokens.Length - 1].Length - 1); 66 | } 67 | 68 | Constraints = new UrlValueConstraint[tokens.Length - 1]; 69 | for (var i = 1; i < tokens.Length; i++) 70 | { 71 | Constraints[i - 1] = RouteConstraint.Parse(template, segment, tokens[i]); 72 | } 73 | } 74 | } 75 | else 76 | { 77 | Constraints = Array.Empty(); 78 | } 79 | 80 | if (IsParameter) 81 | { 82 | if (IsOptional && IsCatchAll) 83 | { 84 | throw new InvalidOperationException($"Invalid segment '{segment}' in route '{template}'. A catch-all parameter cannot be marked optional."); 85 | } 86 | 87 | // Moving the check for this here instead of TemplateParser so we can allow catch-all. 88 | // We checked for '*' up above specifically for catch-all segments, this one checks for all others 89 | if (Value.IndexOf('*') != -1) 90 | { 91 | throw new InvalidOperationException($"Invalid template '{template}'. The character '*' in parameter segment '{{{segment}}}' is not allowed."); 92 | } 93 | } 94 | } 95 | 96 | // The value of the segment. The exact text to match when is a literal. 97 | // The parameter name when its a segment 98 | public string Value { get; } 99 | 100 | public bool IsParameter { get; } 101 | 102 | public bool IsOptional { get; } 103 | 104 | public bool IsCatchAll { get; } 105 | 106 | public UrlValueConstraint[] Constraints { get; } 107 | 108 | public bool Match(string pathSegment, out object? matchedParameterValue) 109 | { 110 | if (IsParameter) 111 | { 112 | matchedParameterValue = pathSegment; 113 | 114 | foreach (var constraint in Constraints) 115 | { 116 | if (!constraint.TryParse(pathSegment, out matchedParameterValue)) 117 | { 118 | return false; 119 | } 120 | } 121 | 122 | return true; 123 | } 124 | else 125 | { 126 | matchedParameterValue = null; 127 | return string.Equals(Value, pathSegment, StringComparison.OrdinalIgnoreCase); 128 | } 129 | } 130 | 131 | public override string ToString() => this switch 132 | { 133 | { IsParameter: true, IsOptional: false, IsCatchAll: false, Constraints: { Length: 0 } } => $"{{{Value}}}", 134 | { IsParameter: true, IsOptional: false, IsCatchAll: false, Constraints: { Length: > 0 } } => $"{{{Value}:{string.Join(':'.ToString(), (object[])Constraints)}}}", 135 | { IsParameter: true, IsOptional: true, Constraints: { Length: 0 } } => $"{{{Value}?}}", 136 | { IsParameter: true, IsOptional: true, Constraints: { Length: > 0 } } => $"{{{Value}:{string.Join(':'.ToString(), (object[])Constraints)}?}}", 137 | { IsParameter: true, IsCatchAll: true, Constraints: { Length: 0 } } => $"{{*{Value}}}", 138 | { IsParameter: true, IsCatchAll: true, Constraints: { Length: > 0 } } => $"{{*{Value}:{string.Join(':'.ToString(), (object[])Constraints)}?}}", 139 | { IsParameter: false } => Value, 140 | _ => throw new InvalidOperationException("Invalid template segment.") 141 | }; 142 | } 143 | } -------------------------------------------------------------------------------- /GoLive.Generator.RazorPageRoute.Generator/UrlValueConstraint.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Concurrent; 3 | using System.Globalization; 4 | 5 | namespace GoLive.Generator.RazorPageRoute.Generator 6 | { 7 | /// 8 | /// Shared logic for parsing tokens from route values and querystring values. 9 | /// 10 | internal abstract class UrlValueConstraint 11 | { 12 | public delegate bool TryParseDelegate(string str, out T result); 13 | 14 | 15 | 16 | private static readonly ConcurrentDictionary _cachedInstances = new(); 17 | 18 | public static bool TryGetByTargetType(Type targetType, out UrlValueConstraint result) 19 | { 20 | if (!_cachedInstances.TryGetValue(targetType, out result)) 21 | { 22 | result = Create(targetType); 23 | if (result is null) 24 | { 25 | return false; 26 | } 27 | 28 | _cachedInstances.TryAdd(targetType, result); 29 | } 30 | 31 | return true; 32 | } 33 | 34 | private static bool TryParse(string str, out string result) 35 | { 36 | result = str.ToString(); 37 | return true; 38 | } 39 | 40 | private static bool TryParse(string str, out DateTime result) 41 | => DateTime.TryParse(str.ToString(), CultureInfo.InvariantCulture, DateTimeStyles.None, out result); 42 | 43 | private static bool TryParse(string str, out decimal result) 44 | => decimal.TryParse(str.ToString(), NumberStyles.Number, CultureInfo.InvariantCulture, out result); 45 | 46 | private static bool TryParse(string str, out double result) 47 | => double.TryParse(str.ToString(), NumberStyles.Number, CultureInfo.InvariantCulture, out result); 48 | 49 | private static bool TryParse(string str, out float result) 50 | => float.TryParse(str.ToString(), NumberStyles.Number, CultureInfo.InvariantCulture, out result); 51 | 52 | private static bool TryParse(string str, out int result) 53 | => int.TryParse(str.ToString(), NumberStyles.Integer, CultureInfo.InvariantCulture, out result); 54 | 55 | private static bool TryParse(string str, out long result) 56 | => long.TryParse(str.ToString(), NumberStyles.Integer, CultureInfo.InvariantCulture, out result); 57 | 58 | private static UrlValueConstraint? Create(Type targetType) => targetType switch 59 | { 60 | var x when x == typeof(string) => new TypedUrlValueConstraint(TryParse), 61 | var x when x == typeof(bool) => new TypedUrlValueConstraint(bool.TryParse), 62 | var x when x == typeof(bool?) => new NullableTypedUrlValueConstraint(bool.TryParse), 63 | var x when x == typeof(DateTime) => new TypedUrlValueConstraint(TryParse), 64 | var x when x == typeof(DateTime?) => new NullableTypedUrlValueConstraint(TryParse), 65 | var x when x == typeof(decimal) => new TypedUrlValueConstraint(TryParse), 66 | var x when x == typeof(decimal?) => new NullableTypedUrlValueConstraint(TryParse), 67 | var x when x == typeof(double) => new TypedUrlValueConstraint(TryParse), 68 | var x when x == typeof(double?) => new NullableTypedUrlValueConstraint(TryParse), 69 | var x when x == typeof(float) => new TypedUrlValueConstraint(TryParse), 70 | var x when x == typeof(float?) => new NullableTypedUrlValueConstraint(TryParse), 71 | var x when x == typeof(Guid) => new TypedUrlValueConstraint(Guid.TryParse), 72 | var x when x == typeof(Guid?) => new NullableTypedUrlValueConstraint(Guid.TryParse), 73 | var x when x == typeof(int) => new TypedUrlValueConstraint(TryParse), 74 | var x when x == typeof(int?) => new NullableTypedUrlValueConstraint(TryParse), 75 | var x when x == typeof(long) => new TypedUrlValueConstraint(TryParse), 76 | var x when x == typeof(long?) => new NullableTypedUrlValueConstraint(TryParse), 77 | var x => null 78 | }; 79 | 80 | public abstract Type GetConstraintType(); 81 | 82 | public abstract bool TryParse(string value, out object result); 83 | 84 | public abstract object? Parse(string value, string destinationNameForMessage); 85 | 86 | public abstract Array ParseMultiple(StringSegmentAccumulator values, string destinationNameForMessage); 87 | 88 | private class TypedUrlValueConstraint : UrlValueConstraint 89 | { 90 | private readonly TryParseDelegate _parser; 91 | 92 | public TypedUrlValueConstraint(TryParseDelegate parser) 93 | { 94 | _parser = parser; 95 | } 96 | 97 | public override Type GetConstraintType() 98 | { 99 | return typeof(T); 100 | } 101 | 102 | public override bool TryParse(string value, out object result) 103 | { 104 | if (_parser(value, out var typedResult)) 105 | { 106 | result = typedResult!; 107 | return true; 108 | } 109 | else 110 | { 111 | result = null; 112 | return false; 113 | } 114 | } 115 | 116 | public override object? Parse(string value, string destinationNameForMessage) 117 | { 118 | if (!_parser(value, out var parsedValue)) 119 | { 120 | throw new InvalidOperationException($"Cannot parse the value '{value.ToString()}' as type '{typeof(T)}' for '{destinationNameForMessage}'."); 121 | } 122 | 123 | return parsedValue; 124 | } 125 | 126 | public override Array ParseMultiple(StringSegmentAccumulator values, string destinationNameForMessage) 127 | { 128 | var count = values.Count; 129 | if (count == 0) 130 | { 131 | return Array.Empty(); 132 | } 133 | 134 | var result = new T?[count]; 135 | 136 | for (var i = 0; i < count; i++) 137 | { 138 | if (!_parser(values[i].ToString(), out result[i])) 139 | { 140 | throw new InvalidOperationException($"Cannot parse the value '{values[i]}' as type '{typeof(T)}' for '{destinationNameForMessage}'."); 141 | } 142 | } 143 | 144 | return result; 145 | } 146 | } 147 | 148 | private sealed class NullableTypedUrlValueConstraint : TypedUrlValueConstraint where T : struct 149 | { 150 | public NullableTypedUrlValueConstraint(TryParseDelegate parser) 151 | : base(SupportNullable(parser)) 152 | { 153 | } 154 | 155 | private static TryParseDelegate SupportNullable(TryParseDelegate parser) 156 | { 157 | return TryParseNullable; 158 | 159 | bool TryParseNullable(string value, out T? result) 160 | { 161 | if (string.IsNullOrWhiteSpace(value)) 162 | { 163 | result = default; 164 | return true; 165 | } 166 | else if (parser(value, out var parsedValue)) 167 | { 168 | result = parsedValue; 169 | return true; 170 | } 171 | else 172 | { 173 | result = default; 174 | return false; 175 | } 176 | } 177 | } 178 | } 179 | } 180 | } -------------------------------------------------------------------------------- /GoLive.Generator.RazorPageRoute.Tests.BlazorWebAsssembly/App.razor: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | Not found 8 | 9 |

Sorry, there's nothing at this address.

10 |
11 |
12 |
13 | -------------------------------------------------------------------------------- /GoLive.Generator.RazorPageRoute.Tests.BlazorWebAsssembly/GoLive.Generator.RazorPageRoute.Tests.BlazorWebAsssembly.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net6.0 5 | enable 6 | enable 7 | 10.0 8 | false 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /GoLive.Generator.RazorPageRoute.Tests.BlazorWebAsssembly/PageRoute.cs: -------------------------------------------------------------------------------- 1 | // This file was generated on Wed, 19 Jun 2024 21:43:35 GMT 2 | using System; 3 | using System.Net.Http; 4 | using System.Threading.Tasks; 5 | using System.Net.Http.Json; 6 | using System.Collections.Generic; 7 | using Microsoft.AspNetCore.Components; 8 | 9 | namespace GoLive.Generator.RazorPageRoute.Tests.BlazorWebAsssembly 10 | { 11 | public static partial class PageRoutes 12 | { 13 | public static string counter(string? QSInput = default) 14 | { 15 | string url = "/counter"; 16 | Dictionary queryString = new(); 17 | if (!string.IsNullOrWhiteSpace(QSInput)) 18 | { 19 | queryString.Add("QSInput", QSInput.ToString()); 20 | } 21 | 22 | url = Microsoft.AspNetCore.WebUtilities.QueryHelpers.AddQueryString(url, queryString); 23 | return url; 24 | } 25 | 26 | public static void counter(this NavigationManager manager, string? QSInput = default, bool forceLoad = false, bool replace = false) 27 | { 28 | string url = "/counter"; 29 | Dictionary queryString = new(); 30 | if (!string.IsNullOrWhiteSpace(QSInput)) 31 | { 32 | queryString.Add("QSInput", QSInput.ToString()); 33 | } 34 | 35 | url = Microsoft.AspNetCore.WebUtilities.QueryHelpers.AddQueryString(url, queryString); 36 | manager.NavigateTo(url, forceLoad, replace); 37 | } 38 | 39 | public static string counter_view(string id, string? QSInput = default) 40 | { 41 | string url = $"/counter/view/{id.ToString()}"; 42 | Dictionary queryString = new(); 43 | if (!string.IsNullOrWhiteSpace(QSInput)) 44 | { 45 | queryString.Add("QSInput", QSInput.ToString()); 46 | } 47 | 48 | url = Microsoft.AspNetCore.WebUtilities.QueryHelpers.AddQueryString(url, queryString); 49 | return url; 50 | } 51 | 52 | public static void counter_view(this NavigationManager manager, string id, string? QSInput = default, bool forceLoad = false, bool replace = false) 53 | { 54 | string url = $"/counter/view/{id.ToString()}"; 55 | Dictionary queryString = new(); 56 | if (!string.IsNullOrWhiteSpace(QSInput)) 57 | { 58 | queryString.Add("QSInput", QSInput.ToString()); 59 | } 60 | 61 | url = Microsoft.AspNetCore.WebUtilities.QueryHelpers.AddQueryString(url, queryString); 62 | manager.NavigateTo(url, forceLoad, replace); 63 | } 64 | 65 | public static string counter_viewbyid(System.Int32 id, string? QSInput = default) 66 | { 67 | string url = $"/counter/viewbyid/{id.ToString()}"; 68 | Dictionary queryString = new(); 69 | if (!string.IsNullOrWhiteSpace(QSInput)) 70 | { 71 | queryString.Add("QSInput", QSInput.ToString()); 72 | } 73 | 74 | url = Microsoft.AspNetCore.WebUtilities.QueryHelpers.AddQueryString(url, queryString); 75 | return url; 76 | } 77 | 78 | public static void counter_viewbyid(this NavigationManager manager, System.Int32 id, string? QSInput = default, bool forceLoad = false, bool replace = false) 79 | { 80 | string url = $"/counter/viewbyid/{id.ToString()}"; 81 | Dictionary queryString = new(); 82 | if (!string.IsNullOrWhiteSpace(QSInput)) 83 | { 84 | queryString.Add("QSInput", QSInput.ToString()); 85 | } 86 | 87 | url = Microsoft.AspNetCore.WebUtilities.QueryHelpers.AddQueryString(url, queryString); 88 | manager.NavigateTo(url, forceLoad, replace); 89 | } 90 | 91 | public static string fetchdata() 92 | { 93 | string url = "/fetchdata"; 94 | return url; 95 | } 96 | 97 | public static void fetchdata(this NavigationManager manager, bool forceLoad = false, bool replace = false) 98 | { 99 | string url = "/fetchdata"; 100 | manager.NavigateTo(url, forceLoad, replace); 101 | } 102 | 103 | public static string Home() 104 | { 105 | string url = "/"; 106 | return url; 107 | } 108 | 109 | public static void Home(this NavigationManager manager, bool forceLoad = false, bool replace = false) 110 | { 111 | string url = "/"; 112 | manager.NavigateTo(url, forceLoad, replace); 113 | } 114 | } 115 | } -------------------------------------------------------------------------------- /GoLive.Generator.RazorPageRoute.Tests.BlazorWebAsssembly/Pages/Counter.razor: -------------------------------------------------------------------------------- 1 | @page "/counter" 2 | @page "/counter/view/{id}" 3 | @page "/counter/viewbyid/{id:int}" 4 | 5 | Counter 6 | 7 |

Counter

8 | 9 |

Current count: @currentCount

10 | 11 | 12 | 13 | @code { 14 | private int currentCount = 0; 15 | 16 | [SupplyParameterFromQuery] 17 | public string QSInput { get; set; } 18 | 19 | private void IncrementCount() 20 | { 21 | currentCount++; 22 | } 23 | 24 | [JSInvokable("GoLive.Generator.RazorPageRoute.Tests.BlazorWebAsssembly.Pages.Counter.Test")] 25 | public void Test() 26 | { 27 | 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /GoLive.Generator.RazorPageRoute.Tests.BlazorWebAsssembly/Pages/FetchData.razor: -------------------------------------------------------------------------------- 1 | @page "/fetchdata" 2 | @inject HttpClient Http 3 | 4 | Weather forecast 5 | 6 |

Weather forecast

7 | 8 |

This component demonstrates fetching data from the server.

9 | 10 | @if (forecasts == null) 11 | { 12 |

Loading...

13 | } 14 | else 15 | { 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | @foreach (var forecast in forecasts) 27 | { 28 | 29 | 30 | 31 | 32 | 33 | 34 | } 35 | 36 |
DateTemp. (C)Temp. (F)Summary
@forecast.Date.ToShortDateString()@forecast.TemperatureC@forecast.TemperatureF@forecast.Summary
37 | } 38 | 39 | @code { 40 | private WeatherForecast[]? forecasts; 41 | 42 | protected override async Task OnInitializedAsync() 43 | { 44 | forecasts = await Http.GetFromJsonAsync("sample-data/weather.json"); 45 | } 46 | 47 | public class WeatherForecast 48 | { 49 | public DateTime Date { get; set; } 50 | 51 | public int TemperatureC { get; set; } 52 | 53 | public string? Summary { get; set; } 54 | 55 | public int TemperatureF => 32 + (int)(TemperatureC / 0.5556); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /GoLive.Generator.RazorPageRoute.Tests.BlazorWebAsssembly/Pages/Index.razor: -------------------------------------------------------------------------------- 1 | @page "/" 2 | @inject NavigationManager navi 3 | 4 | Index 5 | 6 |

Hello, world!

7 | 8 | Welcome to your new app. 9 | 10 | 11 | 12 | 13 | @*@navi.counter_viewbyid(32)*@ -------------------------------------------------------------------------------- /GoLive.Generator.RazorPageRoute.Tests.BlazorWebAsssembly/Program.cs: -------------------------------------------------------------------------------- 1 | using GoLive.Generator.RazorPageRoute.Tests.BlazorWebAsssembly; 2 | using Microsoft.AspNetCore.Components.Web; 3 | using Microsoft.AspNetCore.Components.WebAssembly.Hosting; 4 | 5 | var builder = WebAssemblyHostBuilder.CreateDefault(args); 6 | builder.RootComponents.Add("#app"); 7 | builder.RootComponents.Add("head::after"); 8 | 9 | builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) }); 10 | 11 | await builder.Build().RunAsync(); 12 | -------------------------------------------------------------------------------- /GoLive.Generator.RazorPageRoute.Tests.BlazorWebAsssembly/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "iisSettings": { 3 | "windowsAuthentication": false, 4 | "anonymousAuthentication": true, 5 | "iisExpress": { 6 | "applicationUrl": "http://localhost:39406", 7 | "sslPort": 0 8 | } 9 | }, 10 | "profiles": { 11 | "GoLive.Generator.RazorPageRoute.Tests.BlazorWebAsssembly": { 12 | "commandName": "Project", 13 | "dotnetRunMessages": true, 14 | "launchBrowser": true, 15 | "inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}", 16 | "applicationUrl": "http://localhost:5178", 17 | "environmentVariables": { 18 | "ASPNETCORE_ENVIRONMENT": "Development" 19 | } 20 | }, 21 | "IIS Express": { 22 | "commandName": "IISExpress", 23 | "launchBrowser": true, 24 | "inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}", 25 | "environmentVariables": { 26 | "ASPNETCORE_ENVIRONMENT": "Development" 27 | } 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /GoLive.Generator.RazorPageRoute.Tests.BlazorWebAsssembly/RazorPageRoutes.json: -------------------------------------------------------------------------------- 1 | { 2 | "Namespace": "GoLive.Generator.RazorPageRoute.Tests.BlazorWebAsssembly", 3 | "ClassName": "PageRoutes", 4 | "OutputToFile":"PageRoute.cs", 5 | "OutputLastCreatedTime": true, 6 | "OutputExtensionMethod" : true, 7 | "Invokables":{ 8 | "Enabled": true, 9 | "JSClassName": "INVOKABLES", 10 | "OutputToFile": "wwwroot\\jsinvokable.js" 11 | } 12 | } -------------------------------------------------------------------------------- /GoLive.Generator.RazorPageRoute.Tests.BlazorWebAsssembly/Shared/MainLayout.razor: -------------------------------------------------------------------------------- 1 | @inherits LayoutComponentBase 2 | 3 |
4 | 7 | 8 |
9 |
10 | About 11 |
12 | 13 |
14 | @Body 15 |
16 |
17 |
18 | -------------------------------------------------------------------------------- /GoLive.Generator.RazorPageRoute.Tests.BlazorWebAsssembly/Shared/MainLayout.razor.css: -------------------------------------------------------------------------------- 1 | .page { 2 | position: relative; 3 | display: flex; 4 | flex-direction: column; 5 | } 6 | 7 | main { 8 | flex: 1; 9 | } 10 | 11 | .sidebar { 12 | background-image: linear-gradient(180deg, rgb(5, 39, 103) 0%, #3a0647 70%); 13 | } 14 | 15 | .top-row { 16 | background-color: #f7f7f7; 17 | border-bottom: 1px solid #d6d5d5; 18 | justify-content: flex-end; 19 | height: 3.5rem; 20 | display: flex; 21 | align-items: center; 22 | } 23 | 24 | .top-row ::deep a, .top-row ::deep .btn-link { 25 | white-space: nowrap; 26 | margin-left: 1.5rem; 27 | text-decoration: none; 28 | } 29 | 30 | .top-row ::deep a:hover, .top-row ::deep .btn-link:hover { 31 | text-decoration: underline; 32 | } 33 | 34 | .top-row ::deep a:first-child { 35 | overflow: hidden; 36 | text-overflow: ellipsis; 37 | } 38 | 39 | @media (max-width: 640.98px) { 40 | .top-row:not(.auth) { 41 | display: none; 42 | } 43 | 44 | .top-row.auth { 45 | justify-content: space-between; 46 | } 47 | 48 | .top-row ::deep a, .top-row ::deep .btn-link { 49 | margin-left: 0; 50 | } 51 | } 52 | 53 | @media (min-width: 641px) { 54 | .page { 55 | flex-direction: row; 56 | } 57 | 58 | .sidebar { 59 | width: 250px; 60 | height: 100vh; 61 | position: sticky; 62 | top: 0; 63 | } 64 | 65 | .top-row { 66 | position: sticky; 67 | top: 0; 68 | z-index: 1; 69 | } 70 | 71 | .top-row.auth ::deep a:first-child { 72 | flex: 1; 73 | text-align: right; 74 | width: 0; 75 | } 76 | 77 | .top-row, article { 78 | padding-left: 2rem !important; 79 | padding-right: 1.5rem !important; 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /GoLive.Generator.RazorPageRoute.Tests.BlazorWebAsssembly/Shared/NavMenu.razor: -------------------------------------------------------------------------------- 1 |  9 | 10 |
11 | 28 |
29 | 30 | @code { 31 | private bool collapseNavMenu = true; 32 | 33 | private string? NavMenuCssClass => collapseNavMenu ? "collapse" : null; 34 | 35 | private void ToggleNavMenu() 36 | { 37 | collapseNavMenu = !collapseNavMenu; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /GoLive.Generator.RazorPageRoute.Tests.BlazorWebAsssembly/Shared/NavMenu.razor.css: -------------------------------------------------------------------------------- 1 | .navbar-toggler { 2 | background-color: rgba(255, 255, 255, 0.1); 3 | } 4 | 5 | .top-row { 6 | height: 3.5rem; 7 | background-color: rgba(0,0,0,0.4); 8 | } 9 | 10 | .navbar-brand { 11 | font-size: 1.1rem; 12 | } 13 | 14 | .oi { 15 | width: 2rem; 16 | font-size: 1.1rem; 17 | vertical-align: text-top; 18 | top: -2px; 19 | } 20 | 21 | .nav-item { 22 | font-size: 0.9rem; 23 | padding-bottom: 0.5rem; 24 | } 25 | 26 | .nav-item:first-of-type { 27 | padding-top: 1rem; 28 | } 29 | 30 | .nav-item:last-of-type { 31 | padding-bottom: 1rem; 32 | } 33 | 34 | .nav-item ::deep a { 35 | color: #d7d7d7; 36 | border-radius: 4px; 37 | height: 3rem; 38 | display: flex; 39 | align-items: center; 40 | line-height: 3rem; 41 | } 42 | 43 | .nav-item ::deep a.active { 44 | background-color: rgba(255,255,255,0.25); 45 | color: white; 46 | } 47 | 48 | .nav-item ::deep a:hover { 49 | background-color: rgba(255,255,255,0.1); 50 | color: white; 51 | } 52 | 53 | @media (min-width: 641px) { 54 | .navbar-toggler { 55 | display: none; 56 | } 57 | 58 | .collapse { 59 | /* Never collapse the sidebar for wide screens */ 60 | display: block; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /GoLive.Generator.RazorPageRoute.Tests.BlazorWebAsssembly/Shared/SurveyPrompt.razor: -------------------------------------------------------------------------------- 1 | 
2 | 3 | @Title 4 | 5 | 6 | Please take our 7 | brief survey 8 | 9 | and tell us what you think. 10 |
11 | 12 | @code { 13 | // Demonstrates how a parent component can supply parameters 14 | [Parameter] 15 | public string? Title { get; set; } 16 | } 17 | -------------------------------------------------------------------------------- /GoLive.Generator.RazorPageRoute.Tests.BlazorWebAsssembly/_Imports.razor: -------------------------------------------------------------------------------- 1 | @using System.Net.Http 2 | @using System.Net.Http.Json 3 | @using Microsoft.AspNetCore.Components.Forms 4 | @using Microsoft.AspNetCore.Components.Routing 5 | @using Microsoft.AspNetCore.Components.Web 6 | @using Microsoft.AspNetCore.Components.Web.Virtualization 7 | @using Microsoft.AspNetCore.Components.WebAssembly.Http 8 | @using Microsoft.JSInterop 9 | @using GoLive.Generator.RazorPageRoute.Tests.BlazorWebAsssembly 10 | @using GoLive.Generator.RazorPageRoute.Tests.BlazorWebAsssembly.Shared 11 | -------------------------------------------------------------------------------- /GoLive.Generator.RazorPageRoute.Tests.BlazorWebAsssembly/wwwroot/css/app.css: -------------------------------------------------------------------------------- 1 | @import url('open-iconic/font/css/open-iconic-bootstrap.min.css'); 2 | 3 | html, body { 4 | font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; 5 | } 6 | 7 | h1:focus { 8 | outline: none; 9 | } 10 | 11 | a, .btn-link { 12 | color: #0071c1; 13 | } 14 | 15 | .btn-primary { 16 | color: #fff; 17 | background-color: #1b6ec2; 18 | border-color: #1861ac; 19 | } 20 | 21 | .content { 22 | padding-top: 1.1rem; 23 | } 24 | 25 | .valid.modified:not([type=checkbox]) { 26 | outline: 1px solid #26b050; 27 | } 28 | 29 | .invalid { 30 | outline: 1px solid red; 31 | } 32 | 33 | .validation-message { 34 | color: red; 35 | } 36 | 37 | #blazor-error-ui { 38 | background: lightyellow; 39 | bottom: 0; 40 | box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2); 41 | display: none; 42 | left: 0; 43 | padding: 0.6rem 1.25rem 0.7rem 1.25rem; 44 | position: fixed; 45 | width: 100%; 46 | z-index: 1000; 47 | } 48 | 49 | #blazor-error-ui .dismiss { 50 | cursor: pointer; 51 | position: absolute; 52 | right: 0.75rem; 53 | top: 0.5rem; 54 | } 55 | 56 | .blazor-error-boundary { 57 | background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTYiIGhlaWdodD0iNDkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIG92ZXJmbG93PSJoaWRkZW4iPjxkZWZzPjxjbGlwUGF0aCBpZD0iY2xpcDAiPjxyZWN0IHg9IjIzNSIgeT0iNTEiIHdpZHRoPSI1NiIgaGVpZ2h0PSI0OSIvPjwvY2xpcFBhdGg+PC9kZWZzPjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMCkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMzUgLTUxKSI+PHBhdGggZD0iTTI2My41MDYgNTFDMjY0LjcxNyA1MSAyNjUuODEzIDUxLjQ4MzcgMjY2LjYwNiA1Mi4yNjU4TDI2Ny4wNTIgNTIuNzk4NyAyNjcuNTM5IDUzLjYyODMgMjkwLjE4NSA5Mi4xODMxIDI5MC41NDUgOTIuNzk1IDI5MC42NTYgOTIuOTk2QzI5MC44NzcgOTMuNTEzIDI5MSA5NC4wODE1IDI5MSA5NC42NzgyIDI5MSA5Ny4wNjUxIDI4OS4wMzggOTkgMjg2LjYxNyA5OUwyNDAuMzgzIDk5QzIzNy45NjMgOTkgMjM2IDk3LjA2NTEgMjM2IDk0LjY3ODIgMjM2IDk0LjM3OTkgMjM2LjAzMSA5NC4wODg2IDIzNi4wODkgOTMuODA3MkwyMzYuMzM4IDkzLjAxNjIgMjM2Ljg1OCA5Mi4xMzE0IDI1OS40NzMgNTMuNjI5NCAyNTkuOTYxIDUyLjc5ODUgMjYwLjQwNyA1Mi4yNjU4QzI2MS4yIDUxLjQ4MzcgMjYyLjI5NiA1MSAyNjMuNTA2IDUxWk0yNjMuNTg2IDY2LjAxODNDMjYwLjczNyA2Ni4wMTgzIDI1OS4zMTMgNjcuMTI0NSAyNTkuMzEzIDY5LjMzNyAyNTkuMzEzIDY5LjYxMDIgMjU5LjMzMiA2OS44NjA4IDI1OS4zNzEgNzAuMDg4N0wyNjEuNzk1IDg0LjAxNjEgMjY1LjM4IDg0LjAxNjEgMjY3LjgyMSA2OS43NDc1QzI2Ny44NiA2OS43MzA5IDI2Ny44NzkgNjkuNTg3NyAyNjcuODc5IDY5LjMxNzkgMjY3Ljg3OSA2Ny4xMTgyIDI2Ni40NDggNjYuMDE4MyAyNjMuNTg2IDY2LjAxODNaTTI2My41NzYgODYuMDU0N0MyNjEuMDQ5IDg2LjA1NDcgMjU5Ljc4NiA4Ny4zMDA1IDI1OS43ODYgODkuNzkyMSAyNTkuNzg2IDkyLjI4MzcgMjYxLjA0OSA5My41Mjk1IDI2My41NzYgOTMuNTI5NSAyNjYuMTE2IDkzLjUyOTUgMjY3LjM4NyA5Mi4yODM3IDI2Ny4zODcgODkuNzkyMSAyNjcuMzg3IDg3LjMwMDUgMjY2LjExNiA4Ni4wNTQ3IDI2My41NzYgODYuMDU0N1oiIGZpbGw9IiNGRkU1MDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvZz48L3N2Zz4=) no-repeat 1rem/1.8rem, #b32121; 58 | padding: 1rem 1rem 1rem 3.7rem; 59 | color: white; 60 | } 61 | 62 | .blazor-error-boundary::after { 63 | content: "An error has occurred." 64 | } 65 | -------------------------------------------------------------------------------- /GoLive.Generator.RazorPageRoute.Tests.BlazorWebAsssembly/wwwroot/css/open-iconic/FONT-LICENSE: -------------------------------------------------------------------------------- 1 | SIL OPEN FONT LICENSE Version 1.1 2 | 3 | Copyright (c) 2014 Waybury 4 | 5 | PREAMBLE 6 | The goals of the Open Font License (OFL) are to stimulate worldwide 7 | development of collaborative font projects, to support the font creation 8 | efforts of academic and linguistic communities, and to provide a free and 9 | open framework in which fonts may be shared and improved in partnership 10 | with others. 11 | 12 | The OFL allows the licensed fonts to be used, studied, modified and 13 | redistributed freely as long as they are not sold by themselves. The 14 | fonts, including any derivative works, can be bundled, embedded, 15 | redistributed and/or sold with any software provided that any reserved 16 | names are not used by derivative works. The fonts and derivatives, 17 | however, cannot be released under any other type of license. The 18 | requirement for fonts to remain under this license does not apply 19 | to any document created using the fonts or their derivatives. 20 | 21 | DEFINITIONS 22 | "Font Software" refers to the set of files released by the Copyright 23 | Holder(s) under this license and clearly marked as such. This may 24 | include source files, build scripts and documentation. 25 | 26 | "Reserved Font Name" refers to any names specified as such after the 27 | copyright statement(s). 28 | 29 | "Original Version" refers to the collection of Font Software components as 30 | distributed by the Copyright Holder(s). 31 | 32 | "Modified Version" refers to any derivative made by adding to, deleting, 33 | or substituting -- in part or in whole -- any of the components of the 34 | Original Version, by changing formats or by porting the Font Software to a 35 | new environment. 36 | 37 | "Author" refers to any designer, engineer, programmer, technical 38 | writer or other person who contributed to the Font Software. 39 | 40 | PERMISSION & CONDITIONS 41 | Permission is hereby granted, free of charge, to any person obtaining 42 | a copy of the Font Software, to use, study, copy, merge, embed, modify, 43 | redistribute, and sell modified and unmodified copies of the Font 44 | Software, subject to the following conditions: 45 | 46 | 1) Neither the Font Software nor any of its individual components, 47 | in Original or Modified Versions, may be sold by itself. 48 | 49 | 2) Original or Modified Versions of the Font Software may be bundled, 50 | redistributed and/or sold with any software, provided that each copy 51 | contains the above copyright notice and this license. These can be 52 | included either as stand-alone text files, human-readable headers or 53 | in the appropriate machine-readable metadata fields within text or 54 | binary files as long as those fields can be easily viewed by the user. 55 | 56 | 3) No Modified Version of the Font Software may use the Reserved Font 57 | Name(s) unless explicit written permission is granted by the corresponding 58 | Copyright Holder. This restriction only applies to the primary font name as 59 | presented to the users. 60 | 61 | 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font 62 | Software shall not be used to promote, endorse or advertise any 63 | Modified Version, except to acknowledge the contribution(s) of the 64 | Copyright Holder(s) and the Author(s) or with their explicit written 65 | permission. 66 | 67 | 5) The Font Software, modified or unmodified, in part or in whole, 68 | must be distributed entirely under this license, and must not be 69 | distributed under any other license. The requirement for fonts to 70 | remain under this license does not apply to any document created 71 | using the Font Software. 72 | 73 | TERMINATION 74 | This license becomes null and void if any of the above conditions are 75 | not met. 76 | 77 | DISCLAIMER 78 | THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 79 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF 80 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT 81 | OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE 82 | COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 83 | INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL 84 | DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 85 | FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM 86 | OTHER DEALINGS IN THE FONT SOFTWARE. 87 | -------------------------------------------------------------------------------- /GoLive.Generator.RazorPageRoute.Tests.BlazorWebAsssembly/wwwroot/css/open-iconic/ICON-LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Waybury 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. -------------------------------------------------------------------------------- /GoLive.Generator.RazorPageRoute.Tests.BlazorWebAsssembly/wwwroot/css/open-iconic/README.md: -------------------------------------------------------------------------------- 1 | [Open Iconic v1.1.1](http://useiconic.com/open) 2 | =========== 3 | 4 | ### Open Iconic is the open source sibling of [Iconic](http://useiconic.com). It is a hyper-legible collection of 223 icons with a tiny footprint—ready to use with Bootstrap and Foundation. [View the collection](http://useiconic.com/open#icons) 5 | 6 | 7 | 8 | ## What's in Open Iconic? 9 | 10 | * 223 icons designed to be legible down to 8 pixels 11 | * Super-light SVG files - 61.8 for the entire set 12 | * SVG sprite—the modern replacement for icon fonts 13 | * Webfont (EOT, OTF, SVG, TTF, WOFF), PNG and WebP formats 14 | * Webfont stylesheets (including versions for Bootstrap and Foundation) in CSS, LESS, SCSS and Stylus formats 15 | * PNG and WebP raster images in 8px, 16px, 24px, 32px, 48px and 64px. 16 | 17 | 18 | ## Getting Started 19 | 20 | #### For code samples and everything else you need to get started with Open Iconic, check out our [Icons](http://useiconic.com/open#icons) and [Reference](http://useiconic.com/open#reference) sections. 21 | 22 | ### General Usage 23 | 24 | #### Using Open Iconic's SVGs 25 | 26 | We like SVGs and we think they're the way to display icons on the web. Since Open Iconic are just basic SVGs, we suggest you display them like you would any other image (don't forget the `alt` attribute). 27 | 28 | ``` 29 | icon name 30 | ``` 31 | 32 | #### Using Open Iconic's SVG Sprite 33 | 34 | Open Iconic also comes in a SVG sprite which allows you to display all the icons in the set with a single request. It's like an icon font, without being a hack. 35 | 36 | Adding an icon from an SVG sprite is a little different than what you're used to, but it's still a piece of cake. *Tip: To make your icons easily style able, we suggest adding a general class to the* `` *tag and a unique class name for each different icon in the* `` *tag.* 37 | 38 | ``` 39 | 40 | 41 | 42 | ``` 43 | 44 | Sizing icons only needs basic CSS. All the icons are in a square format, so just set the `` tag with equal width and height dimensions. 45 | 46 | ``` 47 | .icon { 48 | width: 16px; 49 | height: 16px; 50 | } 51 | ``` 52 | 53 | Coloring icons is even easier. All you need to do is set the `fill` rule on the `` tag. 54 | 55 | ``` 56 | .icon-account-login { 57 | fill: #f00; 58 | } 59 | ``` 60 | 61 | To learn more about SVG Sprites, read [Chris Coyier's guide](http://css-tricks.com/svg-sprites-use-better-icon-fonts/). 62 | 63 | #### Using Open Iconic's Icon Font... 64 | 65 | 66 | ##### …with Bootstrap 67 | 68 | You can find our Bootstrap stylesheets in `font/css/open-iconic-bootstrap.{css, less, scss, styl}` 69 | 70 | 71 | ``` 72 | 73 | ``` 74 | 75 | 76 | ``` 77 | 78 | ``` 79 | 80 | ##### …with Foundation 81 | 82 | You can find our Foundation stylesheets in `font/css/open-iconic-foundation.{css, less, scss, styl}` 83 | 84 | ``` 85 | 86 | ``` 87 | 88 | 89 | ``` 90 | 91 | ``` 92 | 93 | ##### …on its own 94 | 95 | You can find our default stylesheets in `font/css/open-iconic.{css, less, scss, styl}` 96 | 97 | ``` 98 | 99 | ``` 100 | 101 | ``` 102 | 103 | ``` 104 | 105 | 106 | ## License 107 | 108 | ### Icons 109 | 110 | All code (including SVG markup) is under the [MIT License](http://opensource.org/licenses/MIT). 111 | 112 | ### Fonts 113 | 114 | All fonts are under the [SIL Licensed](http://scripts.sil.org/cms/scripts/page.php?item_id=OFL_web). 115 | -------------------------------------------------------------------------------- /GoLive.Generator.RazorPageRoute.Tests.BlazorWebAsssembly/wwwroot/css/open-iconic/font/css/open-iconic-bootstrap.min.css: -------------------------------------------------------------------------------- 1 | @font-face{font-family:Icons;src:url(../fonts/open-iconic.eot);src:url(../fonts/open-iconic.eot?#iconic-sm) format('embedded-opentype'),url(../fonts/open-iconic.woff) format('woff'),url(../fonts/open-iconic.ttf) format('truetype'),url(../fonts/open-iconic.otf) format('opentype'),url(../fonts/open-iconic.svg#iconic-sm) format('svg');font-weight:400;font-style:normal}.oi{position:relative;top:1px;display:inline-block;speak:none;font-family:Icons;font-style:normal;font-weight:400;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.oi:empty:before{width:1em;text-align:center;box-sizing:content-box}.oi.oi-align-center:before{text-align:center}.oi.oi-align-left:before{text-align:left}.oi.oi-align-right:before{text-align:right}.oi.oi-flip-horizontal:before{-webkit-transform:scale(-1,1);-ms-transform:scale(-1,1);transform:scale(-1,1)}.oi.oi-flip-vertical:before{-webkit-transform:scale(1,-1);-ms-transform:scale(-1,1);transform:scale(1,-1)}.oi.oi-flip-horizontal-vertical:before{-webkit-transform:scale(-1,-1);-ms-transform:scale(-1,1);transform:scale(-1,-1)}.oi-account-login:before{content:'\e000'}.oi-account-logout:before{content:'\e001'}.oi-action-redo:before{content:'\e002'}.oi-action-undo:before{content:'\e003'}.oi-align-center:before{content:'\e004'}.oi-align-left:before{content:'\e005'}.oi-align-right:before{content:'\e006'}.oi-aperture:before{content:'\e007'}.oi-arrow-bottom:before{content:'\e008'}.oi-arrow-circle-bottom:before{content:'\e009'}.oi-arrow-circle-left:before{content:'\e00a'}.oi-arrow-circle-right:before{content:'\e00b'}.oi-arrow-circle-top:before{content:'\e00c'}.oi-arrow-left:before{content:'\e00d'}.oi-arrow-right:before{content:'\e00e'}.oi-arrow-thick-bottom:before{content:'\e00f'}.oi-arrow-thick-left:before{content:'\e010'}.oi-arrow-thick-right:before{content:'\e011'}.oi-arrow-thick-top:before{content:'\e012'}.oi-arrow-top:before{content:'\e013'}.oi-audio-spectrum:before{content:'\e014'}.oi-audio:before{content:'\e015'}.oi-badge:before{content:'\e016'}.oi-ban:before{content:'\e017'}.oi-bar-chart:before{content:'\e018'}.oi-basket:before{content:'\e019'}.oi-battery-empty:before{content:'\e01a'}.oi-battery-full:before{content:'\e01b'}.oi-beaker:before{content:'\e01c'}.oi-bell:before{content:'\e01d'}.oi-bluetooth:before{content:'\e01e'}.oi-bold:before{content:'\e01f'}.oi-bolt:before{content:'\e020'}.oi-book:before{content:'\e021'}.oi-bookmark:before{content:'\e022'}.oi-box:before{content:'\e023'}.oi-briefcase:before{content:'\e024'}.oi-british-pound:before{content:'\e025'}.oi-browser:before{content:'\e026'}.oi-brush:before{content:'\e027'}.oi-bug:before{content:'\e028'}.oi-bullhorn:before{content:'\e029'}.oi-calculator:before{content:'\e02a'}.oi-calendar:before{content:'\e02b'}.oi-camera-slr:before{content:'\e02c'}.oi-caret-bottom:before{content:'\e02d'}.oi-caret-left:before{content:'\e02e'}.oi-caret-right:before{content:'\e02f'}.oi-caret-top:before{content:'\e030'}.oi-cart:before{content:'\e031'}.oi-chat:before{content:'\e032'}.oi-check:before{content:'\e033'}.oi-chevron-bottom:before{content:'\e034'}.oi-chevron-left:before{content:'\e035'}.oi-chevron-right:before{content:'\e036'}.oi-chevron-top:before{content:'\e037'}.oi-circle-check:before{content:'\e038'}.oi-circle-x:before{content:'\e039'}.oi-clipboard:before{content:'\e03a'}.oi-clock:before{content:'\e03b'}.oi-cloud-download:before{content:'\e03c'}.oi-cloud-upload:before{content:'\e03d'}.oi-cloud:before{content:'\e03e'}.oi-cloudy:before{content:'\e03f'}.oi-code:before{content:'\e040'}.oi-cog:before{content:'\e041'}.oi-collapse-down:before{content:'\e042'}.oi-collapse-left:before{content:'\e043'}.oi-collapse-right:before{content:'\e044'}.oi-collapse-up:before{content:'\e045'}.oi-command:before{content:'\e046'}.oi-comment-square:before{content:'\e047'}.oi-compass:before{content:'\e048'}.oi-contrast:before{content:'\e049'}.oi-copywriting:before{content:'\e04a'}.oi-credit-card:before{content:'\e04b'}.oi-crop:before{content:'\e04c'}.oi-dashboard:before{content:'\e04d'}.oi-data-transfer-download:before{content:'\e04e'}.oi-data-transfer-upload:before{content:'\e04f'}.oi-delete:before{content:'\e050'}.oi-dial:before{content:'\e051'}.oi-document:before{content:'\e052'}.oi-dollar:before{content:'\e053'}.oi-double-quote-sans-left:before{content:'\e054'}.oi-double-quote-sans-right:before{content:'\e055'}.oi-double-quote-serif-left:before{content:'\e056'}.oi-double-quote-serif-right:before{content:'\e057'}.oi-droplet:before{content:'\e058'}.oi-eject:before{content:'\e059'}.oi-elevator:before{content:'\e05a'}.oi-ellipses:before{content:'\e05b'}.oi-envelope-closed:before{content:'\e05c'}.oi-envelope-open:before{content:'\e05d'}.oi-euro:before{content:'\e05e'}.oi-excerpt:before{content:'\e05f'}.oi-expand-down:before{content:'\e060'}.oi-expand-left:before{content:'\e061'}.oi-expand-right:before{content:'\e062'}.oi-expand-up:before{content:'\e063'}.oi-external-link:before{content:'\e064'}.oi-eye:before{content:'\e065'}.oi-eyedropper:before{content:'\e066'}.oi-file:before{content:'\e067'}.oi-fire:before{content:'\e068'}.oi-flag:before{content:'\e069'}.oi-flash:before{content:'\e06a'}.oi-folder:before{content:'\e06b'}.oi-fork:before{content:'\e06c'}.oi-fullscreen-enter:before{content:'\e06d'}.oi-fullscreen-exit:before{content:'\e06e'}.oi-globe:before{content:'\e06f'}.oi-graph:before{content:'\e070'}.oi-grid-four-up:before{content:'\e071'}.oi-grid-three-up:before{content:'\e072'}.oi-grid-two-up:before{content:'\e073'}.oi-hard-drive:before{content:'\e074'}.oi-header:before{content:'\e075'}.oi-headphones:before{content:'\e076'}.oi-heart:before{content:'\e077'}.oi-home:before{content:'\e078'}.oi-image:before{content:'\e079'}.oi-inbox:before{content:'\e07a'}.oi-infinity:before{content:'\e07b'}.oi-info:before{content:'\e07c'}.oi-italic:before{content:'\e07d'}.oi-justify-center:before{content:'\e07e'}.oi-justify-left:before{content:'\e07f'}.oi-justify-right:before{content:'\e080'}.oi-key:before{content:'\e081'}.oi-laptop:before{content:'\e082'}.oi-layers:before{content:'\e083'}.oi-lightbulb:before{content:'\e084'}.oi-link-broken:before{content:'\e085'}.oi-link-intact:before{content:'\e086'}.oi-list-rich:before{content:'\e087'}.oi-list:before{content:'\e088'}.oi-location:before{content:'\e089'}.oi-lock-locked:before{content:'\e08a'}.oi-lock-unlocked:before{content:'\e08b'}.oi-loop-circular:before{content:'\e08c'}.oi-loop-square:before{content:'\e08d'}.oi-loop:before{content:'\e08e'}.oi-magnifying-glass:before{content:'\e08f'}.oi-map-marker:before{content:'\e090'}.oi-map:before{content:'\e091'}.oi-media-pause:before{content:'\e092'}.oi-media-play:before{content:'\e093'}.oi-media-record:before{content:'\e094'}.oi-media-skip-backward:before{content:'\e095'}.oi-media-skip-forward:before{content:'\e096'}.oi-media-step-backward:before{content:'\e097'}.oi-media-step-forward:before{content:'\e098'}.oi-media-stop:before{content:'\e099'}.oi-medical-cross:before{content:'\e09a'}.oi-menu:before{content:'\e09b'}.oi-microphone:before{content:'\e09c'}.oi-minus:before{content:'\e09d'}.oi-monitor:before{content:'\e09e'}.oi-moon:before{content:'\e09f'}.oi-move:before{content:'\e0a0'}.oi-musical-note:before{content:'\e0a1'}.oi-paperclip:before{content:'\e0a2'}.oi-pencil:before{content:'\e0a3'}.oi-people:before{content:'\e0a4'}.oi-person:before{content:'\e0a5'}.oi-phone:before{content:'\e0a6'}.oi-pie-chart:before{content:'\e0a7'}.oi-pin:before{content:'\e0a8'}.oi-play-circle:before{content:'\e0a9'}.oi-plus:before{content:'\e0aa'}.oi-power-standby:before{content:'\e0ab'}.oi-print:before{content:'\e0ac'}.oi-project:before{content:'\e0ad'}.oi-pulse:before{content:'\e0ae'}.oi-puzzle-piece:before{content:'\e0af'}.oi-question-mark:before{content:'\e0b0'}.oi-rain:before{content:'\e0b1'}.oi-random:before{content:'\e0b2'}.oi-reload:before{content:'\e0b3'}.oi-resize-both:before{content:'\e0b4'}.oi-resize-height:before{content:'\e0b5'}.oi-resize-width:before{content:'\e0b6'}.oi-rss-alt:before{content:'\e0b7'}.oi-rss:before{content:'\e0b8'}.oi-script:before{content:'\e0b9'}.oi-share-boxed:before{content:'\e0ba'}.oi-share:before{content:'\e0bb'}.oi-shield:before{content:'\e0bc'}.oi-signal:before{content:'\e0bd'}.oi-signpost:before{content:'\e0be'}.oi-sort-ascending:before{content:'\e0bf'}.oi-sort-descending:before{content:'\e0c0'}.oi-spreadsheet:before{content:'\e0c1'}.oi-star:before{content:'\e0c2'}.oi-sun:before{content:'\e0c3'}.oi-tablet:before{content:'\e0c4'}.oi-tag:before{content:'\e0c5'}.oi-tags:before{content:'\e0c6'}.oi-target:before{content:'\e0c7'}.oi-task:before{content:'\e0c8'}.oi-terminal:before{content:'\e0c9'}.oi-text:before{content:'\e0ca'}.oi-thumb-down:before{content:'\e0cb'}.oi-thumb-up:before{content:'\e0cc'}.oi-timer:before{content:'\e0cd'}.oi-transfer:before{content:'\e0ce'}.oi-trash:before{content:'\e0cf'}.oi-underline:before{content:'\e0d0'}.oi-vertical-align-bottom:before{content:'\e0d1'}.oi-vertical-align-center:before{content:'\e0d2'}.oi-vertical-align-top:before{content:'\e0d3'}.oi-video:before{content:'\e0d4'}.oi-volume-high:before{content:'\e0d5'}.oi-volume-low:before{content:'\e0d6'}.oi-volume-off:before{content:'\e0d7'}.oi-warning:before{content:'\e0d8'}.oi-wifi:before{content:'\e0d9'}.oi-wrench:before{content:'\e0da'}.oi-x:before{content:'\e0db'}.oi-yen:before{content:'\e0dc'}.oi-zoom-in:before{content:'\e0dd'}.oi-zoom-out:before{content:'\e0de'} -------------------------------------------------------------------------------- /GoLive.Generator.RazorPageRoute.Tests.BlazorWebAsssembly/wwwroot/css/open-iconic/font/fonts/open-iconic.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/surgicalcoder/RazorPageRouteGenerator/a3c3f2f9aaff387b26f7b32e004a614868febbf5/GoLive.Generator.RazorPageRoute.Tests.BlazorWebAsssembly/wwwroot/css/open-iconic/font/fonts/open-iconic.eot -------------------------------------------------------------------------------- /GoLive.Generator.RazorPageRoute.Tests.BlazorWebAsssembly/wwwroot/css/open-iconic/font/fonts/open-iconic.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/surgicalcoder/RazorPageRouteGenerator/a3c3f2f9aaff387b26f7b32e004a614868febbf5/GoLive.Generator.RazorPageRoute.Tests.BlazorWebAsssembly/wwwroot/css/open-iconic/font/fonts/open-iconic.otf -------------------------------------------------------------------------------- /GoLive.Generator.RazorPageRoute.Tests.BlazorWebAsssembly/wwwroot/css/open-iconic/font/fonts/open-iconic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 8 | Created by FontForge 20120731 at Tue Jul 1 20:39:22 2014 9 | By P.J. Onori 10 | Created by P.J. Onori with FontForge 2.0 (http://fontforge.sf.net) 11 | 12 | 13 | 14 | 27 | 28 | 30 | 32 | 34 | 36 | 38 | 40 | 42 | 45 | 47 | 49 | 51 | 53 | 55 | 57 | 59 | 61 | 63 | 65 | 67 | 69 | 71 | 74 | 76 | 79 | 81 | 84 | 86 | 88 | 91 | 93 | 95 | 98 | 100 | 102 | 104 | 106 | 109 | 112 | 115 | 117 | 121 | 123 | 125 | 127 | 130 | 132 | 134 | 136 | 138 | 141 | 143 | 145 | 147 | 149 | 151 | 153 | 155 | 157 | 159 | 162 | 165 | 167 | 169 | 172 | 174 | 177 | 179 | 181 | 183 | 185 | 189 | 191 | 194 | 196 | 198 | 200 | 202 | 205 | 207 | 209 | 211 | 213 | 215 | 218 | 220 | 222 | 224 | 226 | 228 | 230 | 232 | 234 | 236 | 238 | 241 | 243 | 245 | 247 | 249 | 251 | 253 | 256 | 259 | 261 | 263 | 265 | 267 | 269 | 272 | 274 | 276 | 280 | 282 | 285 | 287 | 289 | 292 | 295 | 298 | 300 | 302 | 304 | 306 | 309 | 312 | 314 | 316 | 318 | 320 | 322 | 324 | 326 | 330 | 334 | 338 | 340 | 343 | 345 | 347 | 349 | 351 | 353 | 355 | 358 | 360 | 363 | 365 | 367 | 369 | 371 | 373 | 375 | 377 | 379 | 381 | 383 | 386 | 388 | 390 | 392 | 394 | 396 | 399 | 401 | 404 | 406 | 408 | 410 | 412 | 414 | 416 | 419 | 421 | 423 | 425 | 428 | 431 | 435 | 438 | 440 | 442 | 444 | 446 | 448 | 451 | 453 | 455 | 457 | 460 | 462 | 464 | 466 | 468 | 471 | 473 | 477 | 479 | 481 | 483 | 486 | 488 | 490 | 492 | 494 | 496 | 499 | 501 | 504 | 506 | 509 | 512 | 515 | 517 | 520 | 522 | 524 | 526 | 529 | 532 | 534 | 536 | 539 | 542 | 543 | 544 | -------------------------------------------------------------------------------- /GoLive.Generator.RazorPageRoute.Tests.BlazorWebAsssembly/wwwroot/css/open-iconic/font/fonts/open-iconic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/surgicalcoder/RazorPageRouteGenerator/a3c3f2f9aaff387b26f7b32e004a614868febbf5/GoLive.Generator.RazorPageRoute.Tests.BlazorWebAsssembly/wwwroot/css/open-iconic/font/fonts/open-iconic.ttf -------------------------------------------------------------------------------- /GoLive.Generator.RazorPageRoute.Tests.BlazorWebAsssembly/wwwroot/css/open-iconic/font/fonts/open-iconic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/surgicalcoder/RazorPageRouteGenerator/a3c3f2f9aaff387b26f7b32e004a614868febbf5/GoLive.Generator.RazorPageRoute.Tests.BlazorWebAsssembly/wwwroot/css/open-iconic/font/fonts/open-iconic.woff -------------------------------------------------------------------------------- /GoLive.Generator.RazorPageRoute.Tests.BlazorWebAsssembly/wwwroot/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/surgicalcoder/RazorPageRouteGenerator/a3c3f2f9aaff387b26f7b32e004a614868febbf5/GoLive.Generator.RazorPageRoute.Tests.BlazorWebAsssembly/wwwroot/favicon.ico -------------------------------------------------------------------------------- /GoLive.Generator.RazorPageRoute.Tests.BlazorWebAsssembly/wwwroot/icon-192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/surgicalcoder/RazorPageRouteGenerator/a3c3f2f9aaff387b26f7b32e004a614868febbf5/GoLive.Generator.RazorPageRoute.Tests.BlazorWebAsssembly/wwwroot/icon-192.png -------------------------------------------------------------------------------- /GoLive.Generator.RazorPageRoute.Tests.BlazorWebAsssembly/wwwroot/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | GoLive.Generator.RazorPageRoute.Tests.BlazorWebAsssembly 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
Loading...
16 | 17 |
18 | An unhandled error has occurred. 19 | Reload 20 | 🗙 21 |
22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /GoLive.Generator.RazorPageRoute.Tests.BlazorWebAsssembly/wwwroot/jsinvokable.js: -------------------------------------------------------------------------------- 1 | const INVOKABLES = { 2 | GoLive_Generator_RazorPageRoute_Tests_BlazorWebAsssembly_Pages_Counter_Test: "GoLive.Generator.RazorPageRoute.Tests.BlazorWebAsssembly.Pages.Counter.Test", 3 | }; 4 | -------------------------------------------------------------------------------- /GoLive.Generator.RazorPageRoute.Tests.BlazorWebAsssembly/wwwroot/sample-data/weather.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "date": "2018-05-06", 4 | "temperatureC": 1, 5 | "summary": "Freezing" 6 | }, 7 | { 8 | "date": "2018-05-07", 9 | "temperatureC": 14, 10 | "summary": "Bracing" 11 | }, 12 | { 13 | "date": "2018-05-08", 14 | "temperatureC": -13, 15 | "summary": "Freezing" 16 | }, 17 | { 18 | "date": "2018-05-09", 19 | "temperatureC": -16, 20 | "summary": "Balmy" 21 | }, 22 | { 23 | "date": "2018-05-10", 24 | "temperatureC": -2, 25 | "summary": "Chilly" 26 | } 27 | ] 28 | -------------------------------------------------------------------------------- /GoLive.Generator.RazorPageRoute.Tests.BlazorWebAsssembly2/App.razor: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | Not found 8 | 9 |

Sorry, there's nothing at this address.

10 |
11 |
12 |
13 | -------------------------------------------------------------------------------- /GoLive.Generator.RazorPageRoute.Tests.BlazorWebAsssembly2/GoLive.Generator.RazorPageRoute.Tests.BlazorWebAsssembly2.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net6.0 5 | enable 6 | enable 7 | 10.0 8 | false 9 | true 10 | $(BaseIntermediateOutputPath)Generated 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /GoLive.Generator.RazorPageRoute.Tests.BlazorWebAsssembly2/Pages/Counter.razor: -------------------------------------------------------------------------------- 1 | @page "/counter" 2 | @page "/counter/view/{id}" 3 | @page "/counter/viewbyid/{id:int}" 4 | 5 | Counter 6 | 7 |

Counter

8 | 9 |

Current count: @currentCount

10 | 11 | 12 | 13 | @code { 14 | private int currentCount = 0; 15 | 16 | private void IncrementCount() 17 | { 18 | currentCount++; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /GoLive.Generator.RazorPageRoute.Tests.BlazorWebAsssembly2/Pages/FetchData.razor: -------------------------------------------------------------------------------- 1 | @page "/fetchdata" 2 | @inject HttpClient Http 3 | 4 | Weather forecast 5 | 6 |

Weather forecast

7 | 8 |

This component demonstrates fetching data from the server.

9 | 10 | @if (forecasts == null) 11 | { 12 |

Loading...

13 | } 14 | else 15 | { 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | @foreach (var forecast in forecasts) 27 | { 28 | 29 | 30 | 31 | 32 | 33 | 34 | } 35 | 36 |
DateTemp. (C)Temp. (F)Summary
@forecast.Date.ToShortDateString()@forecast.TemperatureC@forecast.TemperatureF@forecast.Summary
37 | } 38 | 39 | @code { 40 | private WeatherForecast[]? forecasts; 41 | 42 | protected override async Task OnInitializedAsync() 43 | { 44 | forecasts = await Http.GetFromJsonAsync("sample-data/weather.json"); 45 | } 46 | 47 | public class WeatherForecast 48 | { 49 | public DateTime Date { get; set; } 50 | 51 | public int TemperatureC { get; set; } 52 | 53 | public string? Summary { get; set; } 54 | 55 | public int TemperatureF => 32 + (int)(TemperatureC / 0.5556); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /GoLive.Generator.RazorPageRoute.Tests.BlazorWebAsssembly2/Pages/Index.razor: -------------------------------------------------------------------------------- 1 | @page "/" 2 | 3 | Index 4 | 5 |

Hello, world!

6 | 7 | Welcome to your new app. 8 | 9 | 10 | @code{ 11 | 12 | protected override Task OnInitializedAsync() 13 | { 14 | 15 | return base.OnInitializedAsync(); 16 | } 17 | 18 | } -------------------------------------------------------------------------------- /GoLive.Generator.RazorPageRoute.Tests.BlazorWebAsssembly2/Program.cs: -------------------------------------------------------------------------------- 1 | using GoLive.Generator.RazorPageRoute.Tests.BlazorWebAsssembly2; 2 | using Microsoft.AspNetCore.Components.Web; 3 | using Microsoft.AspNetCore.Components.WebAssembly.Hosting; 4 | 5 | var builder = WebAssemblyHostBuilder.CreateDefault(args); 6 | builder.RootComponents.Add("#app"); 7 | builder.RootComponents.Add("head::after"); 8 | 9 | builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) }); 10 | 11 | await builder.Build().RunAsync(); 12 | -------------------------------------------------------------------------------- /GoLive.Generator.RazorPageRoute.Tests.BlazorWebAsssembly2/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "iisSettings": { 3 | "windowsAuthentication": false, 4 | "anonymousAuthentication": true, 5 | "iisExpress": { 6 | "applicationUrl": "http://localhost:39406", 7 | "sslPort": 0 8 | } 9 | }, 10 | "profiles": { 11 | "GoLive.Generator.RazorPageRoute.Tests.BlazorWebAsssembly": { 12 | "commandName": "Project", 13 | "dotnetRunMessages": true, 14 | "launchBrowser": true, 15 | "inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}", 16 | "applicationUrl": "http://localhost:5178", 17 | "environmentVariables": { 18 | "ASPNETCORE_ENVIRONMENT": "Development" 19 | } 20 | }, 21 | "IIS Express": { 22 | "commandName": "IISExpress", 23 | "launchBrowser": true, 24 | "inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}", 25 | "environmentVariables": { 26 | "ASPNETCORE_ENVIRONMENT": "Development" 27 | } 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /GoLive.Generator.RazorPageRoute.Tests.BlazorWebAsssembly2/Shared/MainLayout.razor: -------------------------------------------------------------------------------- 1 | @inherits LayoutComponentBase 2 | 3 |
4 | 7 | 8 |
9 |
10 | About 11 |
12 | 13 |
14 | @Body 15 |
16 |
17 |
18 | -------------------------------------------------------------------------------- /GoLive.Generator.RazorPageRoute.Tests.BlazorWebAsssembly2/Shared/MainLayout.razor.css: -------------------------------------------------------------------------------- 1 | .page { 2 | position: relative; 3 | display: flex; 4 | flex-direction: column; 5 | } 6 | 7 | main { 8 | flex: 1; 9 | } 10 | 11 | .sidebar { 12 | background-image: linear-gradient(180deg, rgb(5, 39, 103) 0%, #3a0647 70%); 13 | } 14 | 15 | .top-row { 16 | background-color: #f7f7f7; 17 | border-bottom: 1px solid #d6d5d5; 18 | justify-content: flex-end; 19 | height: 3.5rem; 20 | display: flex; 21 | align-items: center; 22 | } 23 | 24 | .top-row ::deep a, .top-row ::deep .btn-link { 25 | white-space: nowrap; 26 | margin-left: 1.5rem; 27 | text-decoration: none; 28 | } 29 | 30 | .top-row ::deep a:hover, .top-row ::deep .btn-link:hover { 31 | text-decoration: underline; 32 | } 33 | 34 | .top-row ::deep a:first-child { 35 | overflow: hidden; 36 | text-overflow: ellipsis; 37 | } 38 | 39 | @media (max-width: 640.98px) { 40 | .top-row:not(.auth) { 41 | display: none; 42 | } 43 | 44 | .top-row.auth { 45 | justify-content: space-between; 46 | } 47 | 48 | .top-row ::deep a, .top-row ::deep .btn-link { 49 | margin-left: 0; 50 | } 51 | } 52 | 53 | @media (min-width: 641px) { 54 | .page { 55 | flex-direction: row; 56 | } 57 | 58 | .sidebar { 59 | width: 250px; 60 | height: 100vh; 61 | position: sticky; 62 | top: 0; 63 | } 64 | 65 | .top-row { 66 | position: sticky; 67 | top: 0; 68 | z-index: 1; 69 | } 70 | 71 | .top-row.auth ::deep a:first-child { 72 | flex: 1; 73 | text-align: right; 74 | width: 0; 75 | } 76 | 77 | .top-row, article { 78 | padding-left: 2rem !important; 79 | padding-right: 1.5rem !important; 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /GoLive.Generator.RazorPageRoute.Tests.BlazorWebAsssembly2/Shared/NavMenu.razor: -------------------------------------------------------------------------------- 1 |  9 | 10 |
11 | 28 |
29 | 30 | @code { 31 | private bool collapseNavMenu = true; 32 | 33 | private string? NavMenuCssClass => collapseNavMenu ? "collapse" : null; 34 | 35 | private void ToggleNavMenu() 36 | { 37 | collapseNavMenu = !collapseNavMenu; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /GoLive.Generator.RazorPageRoute.Tests.BlazorWebAsssembly2/Shared/NavMenu.razor.css: -------------------------------------------------------------------------------- 1 | .navbar-toggler { 2 | background-color: rgba(255, 255, 255, 0.1); 3 | } 4 | 5 | .top-row { 6 | height: 3.5rem; 7 | background-color: rgba(0,0,0,0.4); 8 | } 9 | 10 | .navbar-brand { 11 | font-size: 1.1rem; 12 | } 13 | 14 | .oi { 15 | width: 2rem; 16 | font-size: 1.1rem; 17 | vertical-align: text-top; 18 | top: -2px; 19 | } 20 | 21 | .nav-item { 22 | font-size: 0.9rem; 23 | padding-bottom: 0.5rem; 24 | } 25 | 26 | .nav-item:first-of-type { 27 | padding-top: 1rem; 28 | } 29 | 30 | .nav-item:last-of-type { 31 | padding-bottom: 1rem; 32 | } 33 | 34 | .nav-item ::deep a { 35 | color: #d7d7d7; 36 | border-radius: 4px; 37 | height: 3rem; 38 | display: flex; 39 | align-items: center; 40 | line-height: 3rem; 41 | } 42 | 43 | .nav-item ::deep a.active { 44 | background-color: rgba(255,255,255,0.25); 45 | color: white; 46 | } 47 | 48 | .nav-item ::deep a:hover { 49 | background-color: rgba(255,255,255,0.1); 50 | color: white; 51 | } 52 | 53 | @media (min-width: 641px) { 54 | .navbar-toggler { 55 | display: none; 56 | } 57 | 58 | .collapse { 59 | /* Never collapse the sidebar for wide screens */ 60 | display: block; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /GoLive.Generator.RazorPageRoute.Tests.BlazorWebAsssembly2/Shared/SurveyPrompt.razor: -------------------------------------------------------------------------------- 1 | 
2 | 3 | @Title 4 | 5 | 6 | Please take our 7 | brief survey 8 | 9 | and tell us what you think. 10 |
11 | 12 | @code { 13 | // Demonstrates how a parent component can supply parameters 14 | [Parameter] 15 | public string? Title { get; set; } 16 | } 17 | -------------------------------------------------------------------------------- /GoLive.Generator.RazorPageRoute.Tests.BlazorWebAsssembly2/_Imports.razor: -------------------------------------------------------------------------------- 1 | @using System.Net.Http 2 | @using System.Net.Http.Json 3 | @using Microsoft.AspNetCore.Components.Forms 4 | @using Microsoft.AspNetCore.Components.Routing 5 | @using Microsoft.AspNetCore.Components.Web 6 | @using Microsoft.AspNetCore.Components.Web.Virtualization 7 | @using Microsoft.AspNetCore.Components.WebAssembly.Http 8 | @using Microsoft.JSInterop 9 | @using GoLive.Generator.RazorPageRoute.Tests.BlazorWebAsssembly2 10 | @using GoLive.Generator.RazorPageRoute.Tests.BlazorWebAsssembly2.Shared -------------------------------------------------------------------------------- /GoLive.Generator.RazorPageRoute.Tests.BlazorWebAsssembly2/wwwroot/css/app.css: -------------------------------------------------------------------------------- 1 | @import url('open-iconic/font/css/open-iconic-bootstrap.min.css'); 2 | 3 | html, body { 4 | font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; 5 | } 6 | 7 | h1:focus { 8 | outline: none; 9 | } 10 | 11 | a, .btn-link { 12 | color: #0071c1; 13 | } 14 | 15 | .btn-primary { 16 | color: #fff; 17 | background-color: #1b6ec2; 18 | border-color: #1861ac; 19 | } 20 | 21 | .content { 22 | padding-top: 1.1rem; 23 | } 24 | 25 | .valid.modified:not([type=checkbox]) { 26 | outline: 1px solid #26b050; 27 | } 28 | 29 | .invalid { 30 | outline: 1px solid red; 31 | } 32 | 33 | .validation-message { 34 | color: red; 35 | } 36 | 37 | #blazor-error-ui { 38 | background: lightyellow; 39 | bottom: 0; 40 | box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2); 41 | display: none; 42 | left: 0; 43 | padding: 0.6rem 1.25rem 0.7rem 1.25rem; 44 | position: fixed; 45 | width: 100%; 46 | z-index: 1000; 47 | } 48 | 49 | #blazor-error-ui .dismiss { 50 | cursor: pointer; 51 | position: absolute; 52 | right: 0.75rem; 53 | top: 0.5rem; 54 | } 55 | 56 | .blazor-error-boundary { 57 | background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTYiIGhlaWdodD0iNDkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIG92ZXJmbG93PSJoaWRkZW4iPjxkZWZzPjxjbGlwUGF0aCBpZD0iY2xpcDAiPjxyZWN0IHg9IjIzNSIgeT0iNTEiIHdpZHRoPSI1NiIgaGVpZ2h0PSI0OSIvPjwvY2xpcFBhdGg+PC9kZWZzPjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMCkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMzUgLTUxKSI+PHBhdGggZD0iTTI2My41MDYgNTFDMjY0LjcxNyA1MSAyNjUuODEzIDUxLjQ4MzcgMjY2LjYwNiA1Mi4yNjU4TDI2Ny4wNTIgNTIuNzk4NyAyNjcuNTM5IDUzLjYyODMgMjkwLjE4NSA5Mi4xODMxIDI5MC41NDUgOTIuNzk1IDI5MC42NTYgOTIuOTk2QzI5MC44NzcgOTMuNTEzIDI5MSA5NC4wODE1IDI5MSA5NC42NzgyIDI5MSA5Ny4wNjUxIDI4OS4wMzggOTkgMjg2LjYxNyA5OUwyNDAuMzgzIDk5QzIzNy45NjMgOTkgMjM2IDk3LjA2NTEgMjM2IDk0LjY3ODIgMjM2IDk0LjM3OTkgMjM2LjAzMSA5NC4wODg2IDIzNi4wODkgOTMuODA3MkwyMzYuMzM4IDkzLjAxNjIgMjM2Ljg1OCA5Mi4xMzE0IDI1OS40NzMgNTMuNjI5NCAyNTkuOTYxIDUyLjc5ODUgMjYwLjQwNyA1Mi4yNjU4QzI2MS4yIDUxLjQ4MzcgMjYyLjI5NiA1MSAyNjMuNTA2IDUxWk0yNjMuNTg2IDY2LjAxODNDMjYwLjczNyA2Ni4wMTgzIDI1OS4zMTMgNjcuMTI0NSAyNTkuMzEzIDY5LjMzNyAyNTkuMzEzIDY5LjYxMDIgMjU5LjMzMiA2OS44NjA4IDI1OS4zNzEgNzAuMDg4N0wyNjEuNzk1IDg0LjAxNjEgMjY1LjM4IDg0LjAxNjEgMjY3LjgyMSA2OS43NDc1QzI2Ny44NiA2OS43MzA5IDI2Ny44NzkgNjkuNTg3NyAyNjcuODc5IDY5LjMxNzkgMjY3Ljg3OSA2Ny4xMTgyIDI2Ni40NDggNjYuMDE4MyAyNjMuNTg2IDY2LjAxODNaTTI2My41NzYgODYuMDU0N0MyNjEuMDQ5IDg2LjA1NDcgMjU5Ljc4NiA4Ny4zMDA1IDI1OS43ODYgODkuNzkyMSAyNTkuNzg2IDkyLjI4MzcgMjYxLjA0OSA5My41Mjk1IDI2My41NzYgOTMuNTI5NSAyNjYuMTE2IDkzLjUyOTUgMjY3LjM4NyA5Mi4yODM3IDI2Ny4zODcgODkuNzkyMSAyNjcuMzg3IDg3LjMwMDUgMjY2LjExNiA4Ni4wNTQ3IDI2My41NzYgODYuMDU0N1oiIGZpbGw9IiNGRkU1MDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvZz48L3N2Zz4=) no-repeat 1rem/1.8rem, #b32121; 58 | padding: 1rem 1rem 1rem 3.7rem; 59 | color: white; 60 | } 61 | 62 | .blazor-error-boundary::after { 63 | content: "An error has occurred." 64 | } 65 | -------------------------------------------------------------------------------- /GoLive.Generator.RazorPageRoute.Tests.BlazorWebAsssembly2/wwwroot/css/open-iconic/FONT-LICENSE: -------------------------------------------------------------------------------- 1 | SIL OPEN FONT LICENSE Version 1.1 2 | 3 | Copyright (c) 2014 Waybury 4 | 5 | PREAMBLE 6 | The goals of the Open Font License (OFL) are to stimulate worldwide 7 | development of collaborative font projects, to support the font creation 8 | efforts of academic and linguistic communities, and to provide a free and 9 | open framework in which fonts may be shared and improved in partnership 10 | with others. 11 | 12 | The OFL allows the licensed fonts to be used, studied, modified and 13 | redistributed freely as long as they are not sold by themselves. The 14 | fonts, including any derivative works, can be bundled, embedded, 15 | redistributed and/or sold with any software provided that any reserved 16 | names are not used by derivative works. The fonts and derivatives, 17 | however, cannot be released under any other type of license. The 18 | requirement for fonts to remain under this license does not apply 19 | to any document created using the fonts or their derivatives. 20 | 21 | DEFINITIONS 22 | "Font Software" refers to the set of files released by the Copyright 23 | Holder(s) under this license and clearly marked as such. This may 24 | include source files, build scripts and documentation. 25 | 26 | "Reserved Font Name" refers to any names specified as such after the 27 | copyright statement(s). 28 | 29 | "Original Version" refers to the collection of Font Software components as 30 | distributed by the Copyright Holder(s). 31 | 32 | "Modified Version" refers to any derivative made by adding to, deleting, 33 | or substituting -- in part or in whole -- any of the components of the 34 | Original Version, by changing formats or by porting the Font Software to a 35 | new environment. 36 | 37 | "Author" refers to any designer, engineer, programmer, technical 38 | writer or other person who contributed to the Font Software. 39 | 40 | PERMISSION & CONDITIONS 41 | Permission is hereby granted, free of charge, to any person obtaining 42 | a copy of the Font Software, to use, study, copy, merge, embed, modify, 43 | redistribute, and sell modified and unmodified copies of the Font 44 | Software, subject to the following conditions: 45 | 46 | 1) Neither the Font Software nor any of its individual components, 47 | in Original or Modified Versions, may be sold by itself. 48 | 49 | 2) Original or Modified Versions of the Font Software may be bundled, 50 | redistributed and/or sold with any software, provided that each copy 51 | contains the above copyright notice and this license. These can be 52 | included either as stand-alone text files, human-readable headers or 53 | in the appropriate machine-readable metadata fields within text or 54 | binary files as long as those fields can be easily viewed by the user. 55 | 56 | 3) No Modified Version of the Font Software may use the Reserved Font 57 | Name(s) unless explicit written permission is granted by the corresponding 58 | Copyright Holder. This restriction only applies to the primary font name as 59 | presented to the users. 60 | 61 | 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font 62 | Software shall not be used to promote, endorse or advertise any 63 | Modified Version, except to acknowledge the contribution(s) of the 64 | Copyright Holder(s) and the Author(s) or with their explicit written 65 | permission. 66 | 67 | 5) The Font Software, modified or unmodified, in part or in whole, 68 | must be distributed entirely under this license, and must not be 69 | distributed under any other license. The requirement for fonts to 70 | remain under this license does not apply to any document created 71 | using the Font Software. 72 | 73 | TERMINATION 74 | This license becomes null and void if any of the above conditions are 75 | not met. 76 | 77 | DISCLAIMER 78 | THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 79 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF 80 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT 81 | OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE 82 | COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 83 | INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL 84 | DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 85 | FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM 86 | OTHER DEALINGS IN THE FONT SOFTWARE. 87 | -------------------------------------------------------------------------------- /GoLive.Generator.RazorPageRoute.Tests.BlazorWebAsssembly2/wwwroot/css/open-iconic/ICON-LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Waybury 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. -------------------------------------------------------------------------------- /GoLive.Generator.RazorPageRoute.Tests.BlazorWebAsssembly2/wwwroot/css/open-iconic/README.md: -------------------------------------------------------------------------------- 1 | [Open Iconic v1.1.1](http://useiconic.com/open) 2 | =========== 3 | 4 | ### Open Iconic is the open source sibling of [Iconic](http://useiconic.com). It is a hyper-legible collection of 223 icons with a tiny footprint—ready to use with Bootstrap and Foundation. [View the collection](http://useiconic.com/open#icons) 5 | 6 | 7 | 8 | ## What's in Open Iconic? 9 | 10 | * 223 icons designed to be legible down to 8 pixels 11 | * Super-light SVG files - 61.8 for the entire set 12 | * SVG sprite—the modern replacement for icon fonts 13 | * Webfont (EOT, OTF, SVG, TTF, WOFF), PNG and WebP formats 14 | * Webfont stylesheets (including versions for Bootstrap and Foundation) in CSS, LESS, SCSS and Stylus formats 15 | * PNG and WebP raster images in 8px, 16px, 24px, 32px, 48px and 64px. 16 | 17 | 18 | ## Getting Started 19 | 20 | #### For code samples and everything else you need to get started with Open Iconic, check out our [Icons](http://useiconic.com/open#icons) and [Reference](http://useiconic.com/open#reference) sections. 21 | 22 | ### General Usage 23 | 24 | #### Using Open Iconic's SVGs 25 | 26 | We like SVGs and we think they're the way to display icons on the web. Since Open Iconic are just basic SVGs, we suggest you display them like you would any other image (don't forget the `alt` attribute). 27 | 28 | ``` 29 | icon name 30 | ``` 31 | 32 | #### Using Open Iconic's SVG Sprite 33 | 34 | Open Iconic also comes in a SVG sprite which allows you to display all the icons in the set with a single request. It's like an icon font, without being a hack. 35 | 36 | Adding an icon from an SVG sprite is a little different than what you're used to, but it's still a piece of cake. *Tip: To make your icons easily style able, we suggest adding a general class to the* `` *tag and a unique class name for each different icon in the* `` *tag.* 37 | 38 | ``` 39 | 40 | 41 | 42 | ``` 43 | 44 | Sizing icons only needs basic CSS. All the icons are in a square format, so just set the `` tag with equal width and height dimensions. 45 | 46 | ``` 47 | .icon { 48 | width: 16px; 49 | height: 16px; 50 | } 51 | ``` 52 | 53 | Coloring icons is even easier. All you need to do is set the `fill` rule on the `` tag. 54 | 55 | ``` 56 | .icon-account-login { 57 | fill: #f00; 58 | } 59 | ``` 60 | 61 | To learn more about SVG Sprites, read [Chris Coyier's guide](http://css-tricks.com/svg-sprites-use-better-icon-fonts/). 62 | 63 | #### Using Open Iconic's Icon Font... 64 | 65 | 66 | ##### …with Bootstrap 67 | 68 | You can find our Bootstrap stylesheets in `font/css/open-iconic-bootstrap.{css, less, scss, styl}` 69 | 70 | 71 | ``` 72 | 73 | ``` 74 | 75 | 76 | ``` 77 | 78 | ``` 79 | 80 | ##### …with Foundation 81 | 82 | You can find our Foundation stylesheets in `font/css/open-iconic-foundation.{css, less, scss, styl}` 83 | 84 | ``` 85 | 86 | ``` 87 | 88 | 89 | ``` 90 | 91 | ``` 92 | 93 | ##### …on its own 94 | 95 | You can find our default stylesheets in `font/css/open-iconic.{css, less, scss, styl}` 96 | 97 | ``` 98 | 99 | ``` 100 | 101 | ``` 102 | 103 | ``` 104 | 105 | 106 | ## License 107 | 108 | ### Icons 109 | 110 | All code (including SVG markup) is under the [MIT License](http://opensource.org/licenses/MIT). 111 | 112 | ### Fonts 113 | 114 | All fonts are under the [SIL Licensed](http://scripts.sil.org/cms/scripts/page.php?item_id=OFL_web). 115 | -------------------------------------------------------------------------------- /GoLive.Generator.RazorPageRoute.Tests.BlazorWebAsssembly2/wwwroot/css/open-iconic/font/css/open-iconic-bootstrap.min.css: -------------------------------------------------------------------------------- 1 | @font-face{font-family:Icons;src:url(../fonts/open-iconic.eot);src:url(../fonts/open-iconic.eot?#iconic-sm) format('embedded-opentype'),url(../fonts/open-iconic.woff) format('woff'),url(../fonts/open-iconic.ttf) format('truetype'),url(../fonts/open-iconic.otf) format('opentype'),url(../fonts/open-iconic.svg#iconic-sm) format('svg');font-weight:400;font-style:normal}.oi{position:relative;top:1px;display:inline-block;speak:none;font-family:Icons;font-style:normal;font-weight:400;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.oi:empty:before{width:1em;text-align:center;box-sizing:content-box}.oi.oi-align-center:before{text-align:center}.oi.oi-align-left:before{text-align:left}.oi.oi-align-right:before{text-align:right}.oi.oi-flip-horizontal:before{-webkit-transform:scale(-1,1);-ms-transform:scale(-1,1);transform:scale(-1,1)}.oi.oi-flip-vertical:before{-webkit-transform:scale(1,-1);-ms-transform:scale(-1,1);transform:scale(1,-1)}.oi.oi-flip-horizontal-vertical:before{-webkit-transform:scale(-1,-1);-ms-transform:scale(-1,1);transform:scale(-1,-1)}.oi-account-login:before{content:'\e000'}.oi-account-logout:before{content:'\e001'}.oi-action-redo:before{content:'\e002'}.oi-action-undo:before{content:'\e003'}.oi-align-center:before{content:'\e004'}.oi-align-left:before{content:'\e005'}.oi-align-right:before{content:'\e006'}.oi-aperture:before{content:'\e007'}.oi-arrow-bottom:before{content:'\e008'}.oi-arrow-circle-bottom:before{content:'\e009'}.oi-arrow-circle-left:before{content:'\e00a'}.oi-arrow-circle-right:before{content:'\e00b'}.oi-arrow-circle-top:before{content:'\e00c'}.oi-arrow-left:before{content:'\e00d'}.oi-arrow-right:before{content:'\e00e'}.oi-arrow-thick-bottom:before{content:'\e00f'}.oi-arrow-thick-left:before{content:'\e010'}.oi-arrow-thick-right:before{content:'\e011'}.oi-arrow-thick-top:before{content:'\e012'}.oi-arrow-top:before{content:'\e013'}.oi-audio-spectrum:before{content:'\e014'}.oi-audio:before{content:'\e015'}.oi-badge:before{content:'\e016'}.oi-ban:before{content:'\e017'}.oi-bar-chart:before{content:'\e018'}.oi-basket:before{content:'\e019'}.oi-battery-empty:before{content:'\e01a'}.oi-battery-full:before{content:'\e01b'}.oi-beaker:before{content:'\e01c'}.oi-bell:before{content:'\e01d'}.oi-bluetooth:before{content:'\e01e'}.oi-bold:before{content:'\e01f'}.oi-bolt:before{content:'\e020'}.oi-book:before{content:'\e021'}.oi-bookmark:before{content:'\e022'}.oi-box:before{content:'\e023'}.oi-briefcase:before{content:'\e024'}.oi-british-pound:before{content:'\e025'}.oi-browser:before{content:'\e026'}.oi-brush:before{content:'\e027'}.oi-bug:before{content:'\e028'}.oi-bullhorn:before{content:'\e029'}.oi-calculator:before{content:'\e02a'}.oi-calendar:before{content:'\e02b'}.oi-camera-slr:before{content:'\e02c'}.oi-caret-bottom:before{content:'\e02d'}.oi-caret-left:before{content:'\e02e'}.oi-caret-right:before{content:'\e02f'}.oi-caret-top:before{content:'\e030'}.oi-cart:before{content:'\e031'}.oi-chat:before{content:'\e032'}.oi-check:before{content:'\e033'}.oi-chevron-bottom:before{content:'\e034'}.oi-chevron-left:before{content:'\e035'}.oi-chevron-right:before{content:'\e036'}.oi-chevron-top:before{content:'\e037'}.oi-circle-check:before{content:'\e038'}.oi-circle-x:before{content:'\e039'}.oi-clipboard:before{content:'\e03a'}.oi-clock:before{content:'\e03b'}.oi-cloud-download:before{content:'\e03c'}.oi-cloud-upload:before{content:'\e03d'}.oi-cloud:before{content:'\e03e'}.oi-cloudy:before{content:'\e03f'}.oi-code:before{content:'\e040'}.oi-cog:before{content:'\e041'}.oi-collapse-down:before{content:'\e042'}.oi-collapse-left:before{content:'\e043'}.oi-collapse-right:before{content:'\e044'}.oi-collapse-up:before{content:'\e045'}.oi-command:before{content:'\e046'}.oi-comment-square:before{content:'\e047'}.oi-compass:before{content:'\e048'}.oi-contrast:before{content:'\e049'}.oi-copywriting:before{content:'\e04a'}.oi-credit-card:before{content:'\e04b'}.oi-crop:before{content:'\e04c'}.oi-dashboard:before{content:'\e04d'}.oi-data-transfer-download:before{content:'\e04e'}.oi-data-transfer-upload:before{content:'\e04f'}.oi-delete:before{content:'\e050'}.oi-dial:before{content:'\e051'}.oi-document:before{content:'\e052'}.oi-dollar:before{content:'\e053'}.oi-double-quote-sans-left:before{content:'\e054'}.oi-double-quote-sans-right:before{content:'\e055'}.oi-double-quote-serif-left:before{content:'\e056'}.oi-double-quote-serif-right:before{content:'\e057'}.oi-droplet:before{content:'\e058'}.oi-eject:before{content:'\e059'}.oi-elevator:before{content:'\e05a'}.oi-ellipses:before{content:'\e05b'}.oi-envelope-closed:before{content:'\e05c'}.oi-envelope-open:before{content:'\e05d'}.oi-euro:before{content:'\e05e'}.oi-excerpt:before{content:'\e05f'}.oi-expand-down:before{content:'\e060'}.oi-expand-left:before{content:'\e061'}.oi-expand-right:before{content:'\e062'}.oi-expand-up:before{content:'\e063'}.oi-external-link:before{content:'\e064'}.oi-eye:before{content:'\e065'}.oi-eyedropper:before{content:'\e066'}.oi-file:before{content:'\e067'}.oi-fire:before{content:'\e068'}.oi-flag:before{content:'\e069'}.oi-flash:before{content:'\e06a'}.oi-folder:before{content:'\e06b'}.oi-fork:before{content:'\e06c'}.oi-fullscreen-enter:before{content:'\e06d'}.oi-fullscreen-exit:before{content:'\e06e'}.oi-globe:before{content:'\e06f'}.oi-graph:before{content:'\e070'}.oi-grid-four-up:before{content:'\e071'}.oi-grid-three-up:before{content:'\e072'}.oi-grid-two-up:before{content:'\e073'}.oi-hard-drive:before{content:'\e074'}.oi-header:before{content:'\e075'}.oi-headphones:before{content:'\e076'}.oi-heart:before{content:'\e077'}.oi-home:before{content:'\e078'}.oi-image:before{content:'\e079'}.oi-inbox:before{content:'\e07a'}.oi-infinity:before{content:'\e07b'}.oi-info:before{content:'\e07c'}.oi-italic:before{content:'\e07d'}.oi-justify-center:before{content:'\e07e'}.oi-justify-left:before{content:'\e07f'}.oi-justify-right:before{content:'\e080'}.oi-key:before{content:'\e081'}.oi-laptop:before{content:'\e082'}.oi-layers:before{content:'\e083'}.oi-lightbulb:before{content:'\e084'}.oi-link-broken:before{content:'\e085'}.oi-link-intact:before{content:'\e086'}.oi-list-rich:before{content:'\e087'}.oi-list:before{content:'\e088'}.oi-location:before{content:'\e089'}.oi-lock-locked:before{content:'\e08a'}.oi-lock-unlocked:before{content:'\e08b'}.oi-loop-circular:before{content:'\e08c'}.oi-loop-square:before{content:'\e08d'}.oi-loop:before{content:'\e08e'}.oi-magnifying-glass:before{content:'\e08f'}.oi-map-marker:before{content:'\e090'}.oi-map:before{content:'\e091'}.oi-media-pause:before{content:'\e092'}.oi-media-play:before{content:'\e093'}.oi-media-record:before{content:'\e094'}.oi-media-skip-backward:before{content:'\e095'}.oi-media-skip-forward:before{content:'\e096'}.oi-media-step-backward:before{content:'\e097'}.oi-media-step-forward:before{content:'\e098'}.oi-media-stop:before{content:'\e099'}.oi-medical-cross:before{content:'\e09a'}.oi-menu:before{content:'\e09b'}.oi-microphone:before{content:'\e09c'}.oi-minus:before{content:'\e09d'}.oi-monitor:before{content:'\e09e'}.oi-moon:before{content:'\e09f'}.oi-move:before{content:'\e0a0'}.oi-musical-note:before{content:'\e0a1'}.oi-paperclip:before{content:'\e0a2'}.oi-pencil:before{content:'\e0a3'}.oi-people:before{content:'\e0a4'}.oi-person:before{content:'\e0a5'}.oi-phone:before{content:'\e0a6'}.oi-pie-chart:before{content:'\e0a7'}.oi-pin:before{content:'\e0a8'}.oi-play-circle:before{content:'\e0a9'}.oi-plus:before{content:'\e0aa'}.oi-power-standby:before{content:'\e0ab'}.oi-print:before{content:'\e0ac'}.oi-project:before{content:'\e0ad'}.oi-pulse:before{content:'\e0ae'}.oi-puzzle-piece:before{content:'\e0af'}.oi-question-mark:before{content:'\e0b0'}.oi-rain:before{content:'\e0b1'}.oi-random:before{content:'\e0b2'}.oi-reload:before{content:'\e0b3'}.oi-resize-both:before{content:'\e0b4'}.oi-resize-height:before{content:'\e0b5'}.oi-resize-width:before{content:'\e0b6'}.oi-rss-alt:before{content:'\e0b7'}.oi-rss:before{content:'\e0b8'}.oi-script:before{content:'\e0b9'}.oi-share-boxed:before{content:'\e0ba'}.oi-share:before{content:'\e0bb'}.oi-shield:before{content:'\e0bc'}.oi-signal:before{content:'\e0bd'}.oi-signpost:before{content:'\e0be'}.oi-sort-ascending:before{content:'\e0bf'}.oi-sort-descending:before{content:'\e0c0'}.oi-spreadsheet:before{content:'\e0c1'}.oi-star:before{content:'\e0c2'}.oi-sun:before{content:'\e0c3'}.oi-tablet:before{content:'\e0c4'}.oi-tag:before{content:'\e0c5'}.oi-tags:before{content:'\e0c6'}.oi-target:before{content:'\e0c7'}.oi-task:before{content:'\e0c8'}.oi-terminal:before{content:'\e0c9'}.oi-text:before{content:'\e0ca'}.oi-thumb-down:before{content:'\e0cb'}.oi-thumb-up:before{content:'\e0cc'}.oi-timer:before{content:'\e0cd'}.oi-transfer:before{content:'\e0ce'}.oi-trash:before{content:'\e0cf'}.oi-underline:before{content:'\e0d0'}.oi-vertical-align-bottom:before{content:'\e0d1'}.oi-vertical-align-center:before{content:'\e0d2'}.oi-vertical-align-top:before{content:'\e0d3'}.oi-video:before{content:'\e0d4'}.oi-volume-high:before{content:'\e0d5'}.oi-volume-low:before{content:'\e0d6'}.oi-volume-off:before{content:'\e0d7'}.oi-warning:before{content:'\e0d8'}.oi-wifi:before{content:'\e0d9'}.oi-wrench:before{content:'\e0da'}.oi-x:before{content:'\e0db'}.oi-yen:before{content:'\e0dc'}.oi-zoom-in:before{content:'\e0dd'}.oi-zoom-out:before{content:'\e0de'} -------------------------------------------------------------------------------- /GoLive.Generator.RazorPageRoute.Tests.BlazorWebAsssembly2/wwwroot/css/open-iconic/font/fonts/open-iconic.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/surgicalcoder/RazorPageRouteGenerator/a3c3f2f9aaff387b26f7b32e004a614868febbf5/GoLive.Generator.RazorPageRoute.Tests.BlazorWebAsssembly2/wwwroot/css/open-iconic/font/fonts/open-iconic.eot -------------------------------------------------------------------------------- /GoLive.Generator.RazorPageRoute.Tests.BlazorWebAsssembly2/wwwroot/css/open-iconic/font/fonts/open-iconic.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/surgicalcoder/RazorPageRouteGenerator/a3c3f2f9aaff387b26f7b32e004a614868febbf5/GoLive.Generator.RazorPageRoute.Tests.BlazorWebAsssembly2/wwwroot/css/open-iconic/font/fonts/open-iconic.otf -------------------------------------------------------------------------------- /GoLive.Generator.RazorPageRoute.Tests.BlazorWebAsssembly2/wwwroot/css/open-iconic/font/fonts/open-iconic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/surgicalcoder/RazorPageRouteGenerator/a3c3f2f9aaff387b26f7b32e004a614868febbf5/GoLive.Generator.RazorPageRoute.Tests.BlazorWebAsssembly2/wwwroot/css/open-iconic/font/fonts/open-iconic.ttf -------------------------------------------------------------------------------- /GoLive.Generator.RazorPageRoute.Tests.BlazorWebAsssembly2/wwwroot/css/open-iconic/font/fonts/open-iconic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/surgicalcoder/RazorPageRouteGenerator/a3c3f2f9aaff387b26f7b32e004a614868febbf5/GoLive.Generator.RazorPageRoute.Tests.BlazorWebAsssembly2/wwwroot/css/open-iconic/font/fonts/open-iconic.woff -------------------------------------------------------------------------------- /GoLive.Generator.RazorPageRoute.Tests.BlazorWebAsssembly2/wwwroot/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/surgicalcoder/RazorPageRouteGenerator/a3c3f2f9aaff387b26f7b32e004a614868febbf5/GoLive.Generator.RazorPageRoute.Tests.BlazorWebAsssembly2/wwwroot/favicon.ico -------------------------------------------------------------------------------- /GoLive.Generator.RazorPageRoute.Tests.BlazorWebAsssembly2/wwwroot/icon-192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/surgicalcoder/RazorPageRouteGenerator/a3c3f2f9aaff387b26f7b32e004a614868febbf5/GoLive.Generator.RazorPageRoute.Tests.BlazorWebAsssembly2/wwwroot/icon-192.png -------------------------------------------------------------------------------- /GoLive.Generator.RazorPageRoute.Tests.BlazorWebAsssembly2/wwwroot/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | GoLive.Generator.RazorPageRoute.Tests.BlazorWebAsssembly 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
Loading...
16 | 17 |
18 | An unhandled error has occurred. 19 | Reload 20 | 🗙 21 |
22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /GoLive.Generator.RazorPageRoute.Tests.BlazorWebAsssembly2/wwwroot/sample-data/weather.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "date": "2018-05-06", 4 | "temperatureC": 1, 5 | "summary": "Freezing" 6 | }, 7 | { 8 | "date": "2018-05-07", 9 | "temperatureC": 14, 10 | "summary": "Bracing" 11 | }, 12 | { 13 | "date": "2018-05-08", 14 | "temperatureC": -13, 15 | "summary": "Freezing" 16 | }, 17 | { 18 | "date": "2018-05-09", 19 | "temperatureC": -16, 20 | "summary": "Balmy" 21 | }, 22 | { 23 | "date": "2018-05-10", 24 | "temperatureC": -2, 25 | "summary": "Chilly" 26 | } 27 | ] 28 | -------------------------------------------------------------------------------- /GoLive.Generator.RazorPageRoute.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.0.31919.166 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GoLive.Generator.RazorPageRoute.Generator", "GoLive.Generator.RazorPageRoute.Generator\GoLive.Generator.RazorPageRoute.Generator.csproj", "{789354C1-9B76-4276-B6F7-83D1B8154E1D}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GoLive.Generator.RazorPageRoute.Tests.BlazorWebAsssembly", "GoLive.Generator.RazorPageRoute.Tests.BlazorWebAsssembly\GoLive.Generator.RazorPageRoute.Tests.BlazorWebAsssembly.csproj", "{8A5871C3-72B3-47B1-92BB-0EF37EBEE359}" 9 | EndProject 10 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GoLive.Generator.RazorPageRoute.Tests.BlazorWebAsssembly2", "GoLive.Generator.RazorPageRoute.Tests.BlazorWebAsssembly2\GoLive.Generator.RazorPageRoute.Tests.BlazorWebAsssembly2.csproj", "{67B54C4D-6B39-408B-AD30-90669684DD28}" 11 | EndProject 12 | Global 13 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 14 | Debug|Any CPU = Debug|Any CPU 15 | Release|Any CPU = Release|Any CPU 16 | EndGlobalSection 17 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 18 | {789354C1-9B76-4276-B6F7-83D1B8154E1D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 19 | {789354C1-9B76-4276-B6F7-83D1B8154E1D}.Debug|Any CPU.Build.0 = Debug|Any CPU 20 | {789354C1-9B76-4276-B6F7-83D1B8154E1D}.Release|Any CPU.ActiveCfg = Release|Any CPU 21 | {789354C1-9B76-4276-B6F7-83D1B8154E1D}.Release|Any CPU.Build.0 = Release|Any CPU 22 | {8A5871C3-72B3-47B1-92BB-0EF37EBEE359}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 23 | {8A5871C3-72B3-47B1-92BB-0EF37EBEE359}.Debug|Any CPU.Build.0 = Debug|Any CPU 24 | {8A5871C3-72B3-47B1-92BB-0EF37EBEE359}.Release|Any CPU.ActiveCfg = Release|Any CPU 25 | {8A5871C3-72B3-47B1-92BB-0EF37EBEE359}.Release|Any CPU.Build.0 = Release|Any CPU 26 | {67B54C4D-6B39-408B-AD30-90669684DD28}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 27 | {67B54C4D-6B39-408B-AD30-90669684DD28}.Debug|Any CPU.Build.0 = Debug|Any CPU 28 | {67B54C4D-6B39-408B-AD30-90669684DD28}.Release|Any CPU.ActiveCfg = Release|Any CPU 29 | {67B54C4D-6B39-408B-AD30-90669684DD28}.Release|Any CPU.Build.0 = Release|Any CPU 30 | EndGlobalSection 31 | GlobalSection(SolutionProperties) = preSolution 32 | HideSolutionNode = FALSE 33 | EndGlobalSection 34 | GlobalSection(ExtensibilityGlobals) = postSolution 35 | SolutionGuid = {923A5A66-A2DB-4409-9FF8-84B5B733B6A5} 36 | EndGlobalSection 37 | EndGlobal 38 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 SurgicalCoder 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | This will generate you a class, that has strongly typed methods, that will represent Razor and Blazor Page routes. You can then use this to navigate to those URLs. Also supports some forms of parameters in the URLs. 2 | 3 | # How to use 4 | 5 | Firstly, add the project from Nuget - [GoLive.Generator.RazorPageRoute](https://www.nuget.org/packages/GoLive.Generator.RazorPageRoute/), then add an AdditionalFile in your .csproj named "RazorPageRoutes.json", like so: 6 | 7 | ``` 8 | 9 | 10 | 11 | ``` 12 | 13 | If you are using .net 6, you need to disable Razor Source Code Generation, due to the way that generators are called. You can do this by inserting 14 | ``` 15 | false 16 | ``` 17 | 18 | Into an ItemGroup. 19 | 20 | Once that's done, add the settings file and change as required: 21 | 22 | 23 | ``` 24 | { 25 | "Namespace": "GoLive.Generator.RazorPageRoute.Tests.BlazorWebAsssembly", 26 | "ClassName": "PageRoutes", 27 | "OutputToFile": "PageRoutes.cs", 28 | "OutputLastCreatedTime": false, 29 | "OutputExtensionMethod" : true 30 | } 31 | ``` 32 | 33 | For `OutputFile` the path will be calculated as relative, so you can put in `..\WebAssembly\File.cs` 34 | --------------------------------------------------------------------------------