[
  {
    "path": ".devcontainer/Containerfile",
    "content": "FROM docker.io/golang:1-bookworm\n\nRUN apt-get update && apt-get install --yes \\\n    curl wget gpg \\\n    make git vim less \\\n    sudo \\\n    bash-completion man \\\n    gcc libc6-dev libx11-dev xorg-dev libxtst-dev \\\n    gcc-multilib gcc-mingw-w64\n\n# Create a non-root user so linux users can run the container as the current\n# OS user. See https://code.visualstudio.com/remote/advancedcontainers/add-nonroot-user\n# and https://github.com/devcontainers/spec/blob/main/docs/specs/devcontainer-reference.md#container-creation\n# for more information.\nARG USERNAME=dev\nARG USER_UID=1010\nARG USER_GID=1010\n\nRUN groupadd --gid $USER_GID $USERNAME \\\n    && useradd --uid $USER_UID --gid $USER_GID -m $USERNAME \\\n    && echo $USERNAME ALL=\\(root\\) NOPASSWD:ALL > /etc/sudoers.d/$USERNAME \\\n    && chmod 0440 /etc/sudoers.d/$USERNAME\n"
  },
  {
    "path": ".devcontainer/devcontainer.json",
    "content": "{\n    \"name\": \"remouseable\",\n    \"build\": {\n        \"dockerfile\": \"Containerfile\",\n        \"context\": \"..\"\n    },\n    \"remoteUser\": \"dev\",\n    \"updateRemoteUserUID\": true,\n    \"containerEnv\": {},\n    \"mounts\": [],\n    \"customizations\": {\n        \"vscode\": {\n            \"settings\": {\n                \"telemetry.telemetryLevel\": \"off\",\n                \"telemetry.enableTelemetry\": false,\n                \"files.insertFinalNewline\": true,\n                \"files.trimTrailingWhitespace\": true,\n                \"rewrap.wrappingColumn\": 80,\n                \"go.formatTool\": \"goimports\",\n                \"go.lintTool\": \"golangci-lint\",\n                \"terminal.integrated.profiles.linux\": {\n                    \"bash\": {\n                        \"path\": \"/usr/bin/bash\"\n                    }\n                },\n                \"terminal.integrated.defaultProfile.linux\": \"bash\"\n            },\n            \"extensions\": [\n                \"golang.go\",\n                \"streetsidesoftware.code-spell-checker\",\n                \"stkb.rewrap\",\n                \"ms-vscode.makefile-tools\",\n                \"redhat.vscode-yaml\",\n                \"ms-vscode.cpptools-extension-pack\"\n            ]\n        }\n    }\n}\n"
  },
  {
    "path": ".github/workflows/pr-workflow.yaml",
    "content": "name: Pull Request Checks\n\non:\n  pull_request:\n    branches:\n      - \"**\"\n  workflow_dispatch: {}\n\njobs:\n  tests:\n    name: Tests\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v4\n      - uses: actions/setup-go@v5\n        with:\n          go-version: 'stable'\n      - name: Install Linux Build Dependencies\n        run: sudo apt-get install --yes gcc libc6-dev libx11-dev xorg-dev libxtst-dev\n      - uses: actions/cache@v4\n        id: tools\n        with:\n          path: bin\n          key: ${{ runner.os }}-${{ hashFiles('tools/go.sum') }}\n      - name: Install build/test tools\n        if: steps.tools.outputs.cache-hit != 'true'\n        run: make tools\n      - name: Lint Tests\n        run: make lint\n      - name: Unit Tests\n        run: make test\n  linux_windows:\n    name: Linux And Windows builds\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v4\n      - uses: actions/setup-go@v5\n        with:\n          go-version: 'stable'\n      - name: Install Linux Build Dependencies\n        run: sudo apt-get install --yes gcc libc6-dev libx11-dev xorg-dev libxtst-dev\n      - name: Install Windows Build Dependencies\n        run: sudo apt-get install --yes gcc-multilib gcc-mingw-w64\n      - name: Build Linux\n        run: mkdir -p .build && CGO_ENABLED=1 go build -o .build/linux main.go\n      - name: Build Windows\n        run: mkdir -p .build && CC=x86_64-w64-mingw32-gcc CGO_ENABLED=1 GOOS=windows go build -o .build/windows.exe main.go\n  osx:\n    name: OSX Builds\n    runs-on: macos-latest\n    steps:\n      - uses: actions/checkout@v4\n      - uses: actions/setup-go@v5\n        with:\n          go-version: 'stable'\n      - uses: maxim-lobanov/setup-xcode@v1\n        with:\n          xcode-version: latest-stable\n      - name: Build OSX AMD64\n        run: mkdir -p .build && CGO_ENABLED=1 GOOS=darwin GOARCH=amd64 go build -o .build/osx-amd main.go\n      - name: Build OSX ARM64\n        run: mkdir -p .build && CGO_ENABLED=1 GOOS=darwin GOARCH=arm64 go build -o .build/osx-arm main.go\n"
  },
  {
    "path": ".github/workflows/tag-workflow.yaml",
    "content": "name: Build Linux/Windows\n\non:\n  release:\n    types:\n      - published\n  workflow_dispatch: {}\n\npermissions:\n  contents: write\n\njobs:\n  windows_linux:\n    name: Windows And Linux releases\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v4\n      - uses: actions/setup-go@v5\n        with:\n          go-version: 'stable'\n      - name: Install Linux Build Dependencies\n        run: sudo apt-get install --yes gcc libc6-dev libx11-dev xorg-dev libxtst-dev\n      - name: Install Windows Build Dependencies\n        run: sudo apt-get install --yes gcc-multilib gcc-mingw-w64\n      - name: Build Linux\n        run: mkdir -p .build && CGO_ENABLED=1 go build -o .build/linux main.go\n      - name: Build Windows\n        run: mkdir -p .build && CC=x86_64-w64-mingw32-gcc CGO_ENABLED=1 GOOS=windows go build -o .build/windows.exe main.go\n      - name: Add Linux Artifact To Release\n        run: gh release upload ${{github.event.release.tag_name}} .build/linux --clobber\n        env:\n          GH_TOKEN: ${{ github.token }}\n      - name: Add Windows Artifact To Release\n        run: gh release upload ${{github.event.release.tag_name}} .build/windows.exe --clobber\n        env:\n          GH_TOKEN: ${{ github.token }}\n  osx:\n    name: OSX Releases\n    runs-on: macos-latest\n    steps:\n      - uses: actions/checkout@v4\n      - uses: actions/setup-go@v5\n        with:\n          go-version: 'stable'\n      - uses: maxim-lobanov/setup-xcode@v1\n        with:\n          xcode-version: latest-stable\n      - name: Build OSX AMD64\n        run: mkdir -p .build && CGO_ENABLED=1 GOOS=darwin GOARCH=amd64 go build -o .build/osx-amd main.go\n      - name: Build OSX ARM64\n        run: mkdir -p .build && CGO_ENABLED=1 GOOS=darwin GOARCH=arm64 go build -o .build/osx-arm main.go\n      - name: Add OSX AMD64 Artifact To Release\n        run: gh release upload ${{github.event.release.tag_name}} .build/osx-amd --clobber\n        env:\n          GH_TOKEN: ${{ github.token }}\n      - name: Add OSX ARM64 Artifact To Release\n        run: gh release upload ${{github.event.release.tag_name}} .build/osx-arm --clobber\n        env:\n          GH_TOKEN: ${{ github.token }}\n"
  },
  {
    "path": ".gitignore",
    "content": "\n# Created by https://www.gitignore.io/api/go,vim,osx,node,linux,emacs,python,windows,intellij,jetbrains,sublimetext,visualstudio,visualstudiocode\n# Edit at https://www.gitignore.io/?templates=go,vim,osx,node,linux,emacs,python,windows,intellij,jetbrains,sublimetext,visualstudio,visualstudiocode\n\n### Emacs ###\n# -*- mode: gitignore; -*-\n*~\n\\#*\\#\n/.emacs.desktop\n/.emacs.desktop.lock\n*.elc\nauto-save-list\ntramp\n.\\#*\n\n# Org-mode\n.org-id-locations\n*_archive\n\n# flymake-mode\n*_flymake.*\n\n# eshell files\n/eshell/history\n/eshell/lastdir\n\n# elpa packages\n/elpa/\n\n# reftex files\n*.rel\n\n# AUCTeX auto folder\n/auto/\n\n# cask packages\n.cask/\ndist/\n\n# Flycheck\nflycheck_*.el\n\n# server auth directory\n/server/\n\n# projectiles files\n.projectile\n\n# directory configuration\n.dir-locals.el\n\n# network security\n/network-security.data\n\n\n### Go ###\n# Binaries for programs and plugins\n*.exe\n*.exe~\n*.dll\n*.so\n*.dylib\n\n# Test binary, built with `go test -c`\n*.test\n\n# Output of the go coverage tool, specifically when used with LiteIDE\n*.out\n\n# Dependency directories (remove the comment below to include it)\n# vendor/\n\n### Go Patch ###\n/vendor/\n/Godeps/\n\n### Intellij ###\n# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm\n# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839\n\n# User-specific stuff\n.idea/**/workspace.xml\n.idea/**/tasks.xml\n.idea/**/usage.statistics.xml\n.idea/**/dictionaries\n.idea/**/shelf\n\n# Generated files\n.idea/**/contentModel.xml\n\n# Sensitive or high-churn files\n.idea/**/dataSources/\n.idea/**/dataSources.ids\n.idea/**/dataSources.local.xml\n.idea/**/sqlDataSources.xml\n.idea/**/dynamic.xml\n.idea/**/uiDesigner.xml\n.idea/**/dbnavigator.xml\n\n# Gradle\n.idea/**/gradle.xml\n.idea/**/libraries\n\n# Gradle and Maven with auto-import\n# When using Gradle or Maven with auto-import, you should exclude module files,\n# since they will be recreated, and may cause churn.  Uncomment if using\n# auto-import.\n# .idea/modules.xml\n# .idea/*.iml\n# .idea/modules\n# *.iml\n# *.ipr\n\n# CMake\ncmake-build-*/\n\n# Mongo Explorer plugin\n.idea/**/mongoSettings.xml\n\n# File-based project format\n*.iws\n\n# IntelliJ\nout/\n\n# mpeltonen/sbt-idea plugin\n.idea_modules/\n\n# JIRA plugin\natlassian-ide-plugin.xml\n\n# Cursive Clojure plugin\n.idea/replstate.xml\n\n# Crashlytics plugin (for Android Studio and IntelliJ)\ncom_crashlytics_export_strings.xml\ncrashlytics.properties\ncrashlytics-build.properties\nfabric.properties\n\n# Editor-based Rest Client\n.idea/httpRequests\n\n# Android studio 3.1+ serialized cache file\n.idea/caches/build_file_checksums.ser\n\n### Intellij Patch ###\n# Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721\n\n# *.iml\n# modules.xml\n# .idea/misc.xml\n# *.ipr\n\n# Sonarlint plugin\n.idea/sonarlint\n\n### JetBrains ###\n# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm\n# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839\n\n# User-specific stuff\n\n# Generated files\n\n# Sensitive or high-churn files\n\n# Gradle\n\n# Gradle and Maven with auto-import\n# When using Gradle or Maven with auto-import, you should exclude module files,\n# since they will be recreated, and may cause churn.  Uncomment if using\n# auto-import.\n# .idea/modules.xml\n# .idea/*.iml\n# .idea/modules\n# *.iml\n# *.ipr\n\n# CMake\n\n# Mongo Explorer plugin\n\n# File-based project format\n\n# IntelliJ\n\n# mpeltonen/sbt-idea plugin\n\n# JIRA plugin\n\n# Cursive Clojure plugin\n\n# Crashlytics plugin (for Android Studio and IntelliJ)\n\n# Editor-based Rest Client\n\n# Android studio 3.1+ serialized cache file\n\n### JetBrains Patch ###\n# Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721\n\n# *.iml\n# modules.xml\n# .idea/misc.xml\n# *.ipr\n\n# Sonarlint plugin\n\n### Linux ###\n\n# temporary files which can be created if a process still has a handle open of a deleted file\n.fuse_hidden*\n\n# KDE directory preferences\n.directory\n\n# Linux trash folder which might appear on any partition or disk\n.Trash-*\n\n# .nfs files are created when an open file is removed but is still being accessed\n.nfs*\n\n### Node ###\n# Logs\nlogs\n*.log\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\nlerna-debug.log*\n\n# Diagnostic reports (https://nodejs.org/api/report.html)\nreport.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json\n\n# Runtime data\npids\n*.pid\n*.seed\n*.pid.lock\n\n# Directory for instrumented libs generated by jscoverage/JSCover\nlib-cov\n\n# Coverage directory used by tools like istanbul\ncoverage\n*.lcov\n\n# nyc test coverage\n.nyc_output\n\n# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)\n.grunt\n\n# Bower dependency directory (https://bower.io/)\nbower_components\n\n# node-waf configuration\n.lock-wscript\n\n# Compiled binary addons (https://nodejs.org/api/addons.html)\nbuild/Release\n\n# Dependency directories\nnode_modules/\njspm_packages/\n\n# TypeScript v1 declaration files\ntypings/\n\n# TypeScript cache\n*.tsbuildinfo\n\n# Optional npm cache directory\n.npm\n\n# Optional eslint cache\n.eslintcache\n\n# Optional REPL history\n.node_repl_history\n\n# Output of 'npm pack'\n*.tgz\n\n# Yarn Integrity file\n.yarn-integrity\n\n# dotenv environment variables file\n.env\n.env.test\n\n# parcel-bundler cache (https://parceljs.org/)\n.cache\n\n# next.js build output\n.next\n\n# nuxt.js build output\n.nuxt\n\n# vuepress build output\n.vuepress/dist\n\n# Serverless directories\n.serverless/\n\n# FuseBox cache\n.fusebox/\n\n# DynamoDB Local files\n.dynamodb/\n\n### OSX ###\n# General\n.DS_Store\n.AppleDouble\n.LSOverride\n\n# Icon must end with two \\r\nIcon\n\n# Thumbnails\n._*\n\n# Files that might appear in the root of a volume\n.DocumentRevisions-V100\n.fseventsd\n.Spotlight-V100\n.TemporaryItems\n.Trashes\n.VolumeIcon.icns\n.com.apple.timemachine.donotpresent\n\n# Directories potentially created on remote AFP share\n.AppleDB\n.AppleDesktop\nNetwork Trash Folder\nTemporary Items\n.apdisk\n\n### Python ###\n# Byte-compiled / optimized / DLL files\n__pycache__/\n*.py[cod]\n*$py.class\n\n# C extensions\n\n# Distribution / packaging\n.Python\nbuild/\ndevelop-eggs/\ndownloads/\neggs/\n.eggs/\nlib/\nlib64/\nparts/\nsdist/\nvar/\nwheels/\npip-wheel-metadata/\nshare/python-wheels/\n*.egg-info/\n.installed.cfg\n*.egg\nMANIFEST\n\n# PyInstaller\n#  Usually these files are written by a python script from a template\n#  before PyInstaller builds the exe, so as to inject date/other infos into it.\n*.manifest\n*.spec\n\n# Installer logs\npip-log.txt\npip-delete-this-directory.txt\n\n# Unit test / coverage reports\nhtmlcov/\n.tox/\n.nox/\n.coverage\n.coverage.*\nnosetests.xml\ncoverage.xml\n*.cover\n.hypothesis/\n.pytest_cache/\n\n# Translations\n*.mo\n*.pot\n\n# Django stuff:\nlocal_settings.py\ndb.sqlite3\ndb.sqlite3-journal\n\n# Flask stuff:\ninstance/\n.webassets-cache\n\n# Scrapy stuff:\n.scrapy\n\n# Sphinx documentation\ndocs/_build/\n\n# PyBuilder\ntarget/\n\n# Jupyter Notebook\n.ipynb_checkpoints\n\n# IPython\nprofile_default/\nipython_config.py\n\n# pyenv\n.python-version\n\n# pipenv\n#   According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.\n#   However, in case of collaboration, if having platform-specific dependencies or dependencies\n#   having no cross-platform support, pipenv may install dependencies that don't work, or not\n#   install all needed dependencies.\n#Pipfile.lock\n\n# celery beat schedule file\ncelerybeat-schedule\n\n# SageMath parsed files\n*.sage.py\n\n# Environments\n.venv\nenv/\nvenv/\nENV/\nenv.bak/\nvenv.bak/\n\n# Spyder project settings\n.spyderproject\n.spyproject\n\n# Rope project settings\n.ropeproject\n\n# mkdocs documentation\n/site\n\n# mypy\n.mypy_cache/\n.dmypy.json\ndmypy.json\n\n# Pyre type checker\n.pyre/\n\n### SublimeText ###\n# Cache files for Sublime Text\n*.tmlanguage.cache\n*.tmPreferences.cache\n*.stTheme.cache\n\n# Workspace files are user-specific\n*.sublime-workspace\n\n# Project files should be checked into the repository, unless a significant\n# proportion of contributors will probably not be using Sublime Text\n# *.sublime-project\n\n# SFTP configuration file\nsftp-config.json\n\n# Package control specific files\nPackage Control.last-run\nPackage Control.ca-list\nPackage Control.ca-bundle\nPackage Control.system-ca-bundle\nPackage Control.cache/\nPackage Control.ca-certs/\nPackage Control.merged-ca-bundle\nPackage Control.user-ca-bundle\noscrypto-ca-bundle.crt\nbh_unicode_properties.cache\n\n# Sublime-github package stores a github token in this file\n# https://packagecontrol.io/packages/sublime-github\nGitHub.sublime-settings\n\n### Vim ###\n# Swap\n[._]*.s[a-v][a-z]\n[._]*.sw[a-p]\n[._]s[a-rt-v][a-z]\n[._]ss[a-gi-z]\n[._]sw[a-p]\n\n# Session\nSession.vim\nSessionx.vim\n\n# Temporary\n.netrwhist\n# Auto-generated tag files\ntags\n# Persistent undo\n[._]*.un~\n\n### VisualStudioCode ###\n.vscode/*\n!.vscode/settings.json\n!.vscode/tasks.json\n!.vscode/launch.json\n!.vscode/extensions.json\n\n### VisualStudioCode Patch ###\n# Ignore all local history of files\n.history\n\n### Windows ###\n# Windows thumbnail cache files\nThumbs.db\nThumbs.db:encryptable\nehthumbs.db\nehthumbs_vista.db\n\n# Dump file\n*.stackdump\n\n# Folder config file\n[Dd]esktop.ini\n\n# Recycle Bin used on file shares\n$RECYCLE.BIN/\n\n# Windows Installer files\n*.cab\n*.msi\n*.msix\n*.msm\n*.msp\n\n# Windows shortcuts\n*.lnk\n\n### VisualStudio ###\n## Ignore Visual Studio temporary files, build results, and\n## files generated by popular Visual Studio add-ons.\n##\n## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore\n\n# User-specific files\n*.rsuser\n*.suo\n*.user\n*.userosscache\n*.sln.docstates\n\n# User-specific files (MonoDevelop/Xamarin Studio)\n*.userprefs\n\n# Mono auto generated files\nmono_crash.*\n\n# Build results\n[Dd]ebug/\n[Dd]ebugPublic/\n[Rr]elease/\n[Rr]eleases/\nx64/\nx86/\n[Aa][Rr][Mm]/\n[Aa][Rr][Mm]64/\nbld/\n[Bb]in/\n[Oo]bj/\n[Ll]og/\n\n# Visual Studio 2015/2017 cache/options directory\n.vs/\n# Uncomment if you have tasks that create the project's static files in wwwroot\n#wwwroot/\n\n# Visual Studio 2017 auto generated files\nGenerated\\ Files/\n\n# MSTest test Results\n[Tt]est[Rr]esult*/\n[Bb]uild[Ll]og.*\n\n# NUnit\n*.VisualState.xml\nTestResult.xml\nnunit-*.xml\n\n# Build Results of an ATL Project\n[Dd]ebugPS/\n[Rr]eleasePS/\ndlldata.c\n\n# Benchmark Results\nBenchmarkDotNet.Artifacts/\n\n# .NET Core\nproject.lock.json\nproject.fragment.lock.json\nartifacts/\n\n# StyleCop\nStyleCopReport.xml\n\n# Files built by Visual Studio\n*_i.c\n*_p.c\n*_h.h\n*.ilk\n*.meta\n*.obj\n*.iobj\n*.pch\n*.pdb\n*.ipdb\n*.pgc\n*.pgd\n*.rsp\n*.sbr\n*.tlb\n*.tli\n*.tlh\n*.tmp\n*.tmp_proj\n*_wpftmp.csproj\n*.vspscc\n*.vssscc\n.builds\n*.pidb\n*.svclog\n*.scc\n\n# Chutzpah Test files\n_Chutzpah*\n\n# Visual C++ cache files\nipch/\n*.aps\n*.ncb\n*.opendb\n*.opensdf\n*.sdf\n*.cachefile\n*.VC.db\n*.VC.VC.opendb\n\n# Visual Studio profiler\n*.psess\n*.vsp\n*.vspx\n*.sap\n\n# Visual Studio Trace Files\n*.e2e\n\n# TFS 2012 Local Workspace\n$tf/\n\n# Guidance Automation Toolkit\n*.gpState\n\n# ReSharper is a .NET coding add-in\n_ReSharper*/\n*.[Rr]e[Ss]harper\n*.DotSettings.user\n\n# JustCode is a .NET coding add-in\n.JustCode\n\n# TeamCity is a build add-in\n_TeamCity*\n\n# DotCover is a Code Coverage Tool\n*.dotCover\n\n# AxoCover is a Code Coverage Tool\n.axoCover/*\n!.axoCover/settings.json\n\n# Visual Studio code coverage results\n*.coverage\n*.coveragexml\n\n# NCrunch\n_NCrunch_*\n.*crunch*.local.xml\nnCrunchTemp_*\n\n# MightyMoose\n*.mm.*\nAutoTest.Net/\n\n# Web workbench (sass)\n.sass-cache/\n\n# Installshield output folder\n[Ee]xpress/\n\n# DocProject is a documentation generator add-in\nDocProject/buildhelp/\nDocProject/Help/*.HxT\nDocProject/Help/*.HxC\nDocProject/Help/*.hhc\nDocProject/Help/*.hhk\nDocProject/Help/*.hhp\nDocProject/Help/Html2\nDocProject/Help/html\n\n# Click-Once directory\npublish/\n\n# Publish Web Output\n*.[Pp]ublish.xml\n*.azurePubxml\n# Note: Comment the next line if you want to checkin your web deploy settings,\n# but database connection strings (with potential passwords) will be unencrypted\n*.pubxml\n*.publishproj\n\n# Microsoft Azure Web App publish settings. Comment the next line if you want to\n# checkin your Azure Web App publish settings, but sensitive information contained\n# in these scripts will be unencrypted\nPublishScripts/\n\n# NuGet Packages\n*.nupkg\n# NuGet Symbol Packages\n*.snupkg\n# The packages folder can be ignored because of Package Restore\n**/[Pp]ackages/*\n# except build/, which is used as an MSBuild target.\n!**/[Pp]ackages/build/\n# Uncomment if necessary however generally it will be regenerated when needed\n#!**/[Pp]ackages/repositories.config\n# NuGet v3's project.json files produces more ignorable files\n*.nuget.props\n*.nuget.targets\n\n# Microsoft Azure Build Output\ncsx/\n*.build.csdef\n\n# Microsoft Azure Emulator\necf/\nrcf/\n\n# Windows Store app package directories and files\nAppPackages/\nBundleArtifacts/\nPackage.StoreAssociation.xml\n_pkginfo.txt\n*.appx\n*.appxbundle\n*.appxupload\n\n# Visual Studio cache files\n# files ending in .cache can be ignored\n*.[Cc]ache\n# but keep track of directories ending in .cache\n!?*.[Cc]ache/\n\n# Others\nClientBin/\n~$*\n*.dbmdl\n*.dbproj.schemaview\n*.jfm\n*.pfx\n*.publishsettings\norleans.codegen.cs\n\n# Including strong name files can present a security risk\n# (https://github.com/github/gitignore/pull/2483#issue-259490424)\n#*.snk\n\n# Since there are multiple workflows, uncomment next line to ignore bower_components\n# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)\n#bower_components/\n\n# RIA/Silverlight projects\nGenerated_Code/\n\n# Backup & report files from converting an old project file\n# to a newer Visual Studio version. Backup files are not needed,\n# because we have git ;-)\n_UpgradeReport_Files/\nBackup*/\nUpgradeLog*.XML\nUpgradeLog*.htm\nServiceFabricBackup/\n*.rptproj.bak\n\n# SQL Server files\n*.mdf\n*.ldf\n*.ndf\n\n# Business Intelligence projects\n*.rdl.data\n*.bim.layout\n*.bim_*.settings\n*.rptproj.rsuser\n*- [Bb]ackup.rdl\n*- [Bb]ackup ([0-9]).rdl\n*- [Bb]ackup ([0-9][0-9]).rdl\n\n# Microsoft Fakes\nFakesAssemblies/\n\n# GhostDoc plugin setting file\n*.GhostDoc.xml\n\n# Node.js Tools for Visual Studio\n.ntvs_analysis.dat\n\n# Visual Studio 6 build log\n*.plg\n\n# Visual Studio 6 workspace options file\n*.opt\n\n# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)\n*.vbw\n\n# Visual Studio LightSwitch build output\n**/*.HTMLClient/GeneratedArtifacts\n**/*.DesktopClient/GeneratedArtifacts\n**/*.DesktopClient/ModelManifest.xml\n**/*.Server/GeneratedArtifacts\n**/*.Server/ModelManifest.xml\n_Pvt_Extensions\n\n# Paket dependency manager\n.paket/paket.exe\npaket-files/\n\n# FAKE - F# Make\n.fake/\n\n# CodeRush personal settings\n.cr/personal\n\n# Python Tools for Visual Studio (PTVS)\n*.pyc\n\n# Cake - Uncomment if you are using it\n# tools/**\n# !tools/packages.config\n\n# Tabs Studio\n*.tss\n\n# Telerik's JustMock configuration file\n*.jmconfig\n\n# BizTalk build output\n*.btp.cs\n*.btm.cs\n*.odx.cs\n*.xsd.cs\n\n# OpenCover UI analysis results\nOpenCover/\n\n# Azure Stream Analytics local run output\nASALocalRun/\n\n# MSBuild Binary and Structured Log\n*.binlog\n\n# NVidia Nsight GPU debugger configuration file\n*.nvuser\n\n# MFractors (Xamarin productivity tool) working folder\n.mfractor/\n\n# Local History for Visual Studio\n.localhistory/\n\n# BeatPulse healthcheck temp database\nhealthchecksdb\n\n# Backup folder for Package Reference Convert tool in Visual Studio 2017\nMigrationBackup/\n\n# End of https://www.gitignore.io/api/go,vim,osx,node,linux,emacs,python,windows,intellij,jetbrains,sublimetext,visualstudio,visualstudiocode\n\n# Begin custom overrides\n\n# Project local bin directory\nbin/\n# Test coverage collection directory\n.coverage/\n# Antlr files\n.antlr/\n# Static file bundles that can be created at build time.\nstatik/statik.go\n# Project local build output directory\n.build/\n\n# End custom overrides\n"
  },
  {
    "path": ".golangci.errcheck.ignore",
    "content": ""
  },
  {
    "path": ".golangci.yaml",
    "content": "# options for analysis running\nrun:\n  # timeout for analysis, e.g. 30s, 5m, default is 1m\n  deadline: 1m\n\n  # exit code when at least one issue was found, default is 1\n  issues-exit-code: 1\n\n  # include test files or not, default is true\n  tests: true\n\n  # list of build tags, all linters use it. Default is empty list.\n  build-tags:\n    - integration\n\n  # which dirs to skip: they won't be analyzed; can use regexp here:\n  # generated.*, regexp is applied on full path; default value is empty list,\n  # but next dirs are always skipped independently from this option's value:\n  # vendor$, third_party$, testdata$, examples$, Godeps$, builtin$\n  skip-dirs:\n    - internal/proto\n\n  # by default isn't set. If set we pass it to \"go list -mod={option}\". From \"go\n  # help modules\": If invoked with -mod=readonly, the go command is disallowed\n  # from the implicit automatic updating of go.mod described above. Instead, it\n  # fails when any changes to go.mod are needed. This setting is most useful to\n  # check that go.mod does not need updates, such as in a continuous integration\n  # and testing system. If invoked with -mod=vendor, the go command assumes that\n  # the vendor directory holds the correct copies of dependencies and ignores\n  # the dependency descriptions in go.mod.\n  modules-download-mode: readonly\n\n\n# output configuration options\noutput:\n  # colored-line-number|line-number|json|tab|checkstyle|code-climate, default is\n  # \"colored-line-number\"\n  format: colored-line-number\n\n  # print lines of code with issue, default is true\n  print-issued-lines: true\n\n  # print linter name in the end of issue text, default is true\n  print-linter-name: true\n\n\n# all available settings of specific linters\nlinters-settings:\n  errcheck:\n    # report about not checking of errors in type assetions: `a :=\n    # b.(MyStruct)`; default is false: such cases aren't reported by default.\n    check-type-assertions: false\n\n    # report about assignment of errors to blank identifier: `num, _ :=\n    # strconv.Atoi(numStr)`; default is false: such cases aren't reported by\n    # default.\n    check-blank: false\n\n    # [deprecated] comma-separated list of pairs of the form pkg:regex the regex\n    # is used to ignore names within pkg. (default \"fmt:.*\"). see\n    # https://github.com/kisielk/errcheck#the-deprecated-method for details\n    ignore: fmt:.*\n\n    # path to a file containing a list of functions to exclude from checking see\n    # https://github.com/kisielk/errcheck#excluding-functions for details\n    exclude: .golangci.errcheck.ignore\n  govet:\n    # report about shadowed variables\n    check-shadowing: true\n  golint:\n    # minimal confidence for issues, default is 0.8\n    min-confidence: 0.8\n  gofmt:\n    # simplify code: gofmt with `-s` option, true by default.\n    # NOTE: Setting to false in order to cooperate with goimports which does\n    # _not_ apply the simplification.\n    simplify: false\n  goimports:\n    # put imports beginning with prefix after 3rd-party packages; it's a\n    # comma-separated list of prefixes\n    local-prefixes: github.com/kevinconway/\n  gocyclo:\n    # minimal code complexity to report, 30 by default (but we recommend 10-20)\n    min-complexity: 60 # Setting high value to account for complex reflection.\n  maligned:\n    # print struct with more effective memory layout or not, false by default\n    suggest-new: true\n  dupl:\n    # tokens count to trigger issue, 150 by default\n    threshold: 300\n  goconst:\n    # minimal length of string constant, 3 by default\n    min-len: 3\n    # minimal occurrences count to trigger, 3 by default\n    min-occurrences: 3\n  misspell:\n    # Correct spellings using locale preferences for US or UK. Default is to use\n    # a neutral variety of English. Setting locale to US will correct the\n    # British spelling of 'colour' to 'color'.\n    locale: US\n    ignore-words:\n      - ignore\n  lll:\n    # max line length, lines longer will be reported. Default is 120. '\\t' is\n    # counted as 1 character by default, and can be changed with the tab-width\n    # option\n    line-length: 120\n    # tab width in spaces. Default to 1.\n    tab-width: 1\n  unused:\n    # treat code as a program (not a library) and report unused exported\n    # identifiers; default is false. XXX: if you enable this setting, unused\n    # will report a lot of false-positives in text editors: if it's called for\n    # subdir of a project it can't find funcs usages. All text editor\n    # integrations with golangci-lint call it on a directory with the changed\n    # file.\n    check-exported: false\n  unparam:\n    # Inspect exported functions, default is false. Set to true if no external\n    # program/library imports your code. XXX: if you enable this setting,\n    # unparam will report a lot of false-positives in text editors: if it's\n    # called for subdir of a project it can't find external interfaces. All text\n    # editor integrations with golangci-lint call it on a directory with the\n    # changed file.\n    check-exported: false\n  nakedret:\n    # make an issue if func has more lines of code than this setting and it has\n    # naked returns; default is 30\n    max-func-lines: 1\n  prealloc:\n    # XXX: we don't recommend using this linter before doing performance\n    # profiling. For most programs usage of prealloc will be a premature\n    # optimization.\n\n    # Report preallocation suggestions only on simple loops that have no\n    # returns/breaks/continues/gotos in them. True by default.\n    simple: true\n    range-loops: true # Report preallocation suggestions on range loops, true by default\n    for-loops: true # Report preallocation suggestions on for loops, false by default\nlinters:\n  presets:\n    - bugs\n    - test\n  disable:\n    - depguard\n    - gocritic\n    - lll\n    - funlen\n    - wsl\n    - gocognit\n    - unused # Disabled because it seems to break if there is no vendor.\n    - typecheck # Disabled because it seems to break if there is no vendor.\n    - testifylint # Added to lint suite after project started\n    - testpackage # Added to lint suite after project started\n    - paralleltest # Added to lint suite after project started\n    - exhaustivestruct # Added to lint suite after project started\n    - exhaustruct # Added to lint suite after project started\n\nissues:\n  # List of regexps of issue texts to exclude, empty list by default. But\n  # independently from this option we use default exclude patterns, it can be\n  # disabled by `exclude-use-default: false`. To list all excluded by default\n  # patterns execute `golangci-lint run --help`\n  exclude: []\n\n  # Excluding configuration per-path, per-linter, per-text and per-source\n  exclude-rules:\n    # Exclude some linters from running on tests files.\n    - path: _test\\.go\n      linters:\n        - gocyclo\n        - errcheck\n        - dupl\n        - gosec\n\n    # Exclude known linters from partially hard-vendored code, which is\n    # impossible to exclude via \"nolint\" comments.\n    - path: internal/hmac/\n      text: \"weak cryptographic primitive\"\n      linters:\n        - gosec\n\n    # Exclude some staticcheck messages\n    - linters:\n        - staticcheck\n      text: \"SA9003:\"\n\n    # Exclude lll issues for long lines with go:generate\n    - linters:\n        - lll\n      source: \"^//go:generate \"\n\n  # Independently from option `exclude` we use default exclude patterns, it can\n  # be disabled by this option. To list all excluded by default patterns execute\n  # `golangci-lint run --help`. Default value for this option is true.\n  exclude-use-default: true\n\n  # Maximum issues count per one linter. Set to 0 to disable. Default is 50.\n  max-issues-per-linter: 50\n\n  # Maximum count of issues with the same text. Set to 0 to disable. Default is\n  # 3.\n  max-same-issues: 3\n\n  # Show only new issues: if there are unstaged changes or untracked files, only\n  # those changes are analyzed, else only changes in HEAD~ are analyzed. It's a\n  # super-useful option for integration of golangci-lint into existing large\n  # codebase. It's not practical to fix all existing issues at the moment of\n  # integration: much better don't allow issues in new code. Default is false.\n  new: false\n\n"
  },
  {
    "path": ".travis.yml",
    "content": "language: go\ngo:\n  - 1.14.x\nservices:\n  - xvfb\naddons:\n  homebrew:\n    update: true\n    packages:\n      - go@1.14\n      - make\n      - coreutils\n      - findutils\n      - gnu-tar\n      - gnu-sed\n      - gawk\n      - gnutls\n      - gnu-indent\n      - gnu-getopt\n      - grep\n  apt:\n    packages:\n      - gcc\n      - libc6-dev\n      - libx11-dev\n      - xorg-dev\n      - libxtst-dev\n      - gcc-multilib\n      - gcc-mingw-w64\nos:\n  - linux\n  - osx\ninstall:\n  - GO111MODULE=on go get\nscript:\n  - if [[ \"${TRAVIS_OS_NAME}\" == \"osx\" ]]; then export PATH=\"$(brew --prefix)/opt/make/libexec/gnubin:${PATH}\" ; fi\n  - make tools\n  - make lint\n  - make test\n  - make coverage\n  - make BUILDNAME=${TRAVIS_OS_NAME} build\n  - if [[ \"${TRAVIS_OS_NAME}\" == \"linux\" ]]; then CC=x86_64-w64-mingw32-gcc GOOS=windows CGO_ENABLED=1 go build -o .build/windows.exe main.go ; fi\ndeploy:\n  provider: releases\n  api_key:\n    secure: n2pSGM0ygiIptoWD/D9W0VokURsI8p44+qFsBbMuWz1kG3agzsHfJR8ufvYVYnl3CelupOHoU11+uM/R3am5djnqVkpYZhdvJznEaLzdPZeLDuMaMF0GLm6o5UFpcA0nf/68RAaLaBg4iXCBrSfN5nnrscxdmKOfQ1V8PwhkIZNkKXaXBK2myx9o6uhSfuRYHvXlTtZ01R8Yy7l/3TB6I841OuGMsxI/klDPFF/6DYe0bbgmh6Q6FRAsGAZGfrWGUGa4g5gi9cBpYGyR0vZfMxy4nlSaF2Owi9Pguj/8gWabmHLDSyWZqDOcrp2VlVALMNTMeP+0s2MNkp9CbFjlngMoykh1cV/wC/OGKyWasqKLAgX+HTDhGjDIsbhEyaK9RydKUSW4CNAoOJU3jzONOrCocFsmuGRP7H9XoS2XDK7X4cbCJEIbkgqQqSPRKz+i4fdPE5eUiSlxvy4QDE24YUrcIdpyND0naF1OMqyqkMqXVHf2cmqqMWYSoz3FRy4uLs81Mq2hFcQBjYKoSSrJ5UfKrtU5PZy7UpGDPRvCzVaiXpRrCZgRVhuDAAZPa3CvJmN5xDYUTjRc42fziIAwwbtAB0uq40O3xdIYGxt1GaUnagaucbU1aBbc3T/X/o/yDdUA/os6hXSh6FtKdIm/qGD+jssvHi44ILDYdaeTmuw=\n  file_glob: true\n  file: ${TRAVIS_BUILD_DIR}/.build/*\n  on:\n    repo: kevinconway/remouseable\n    tags: true\n  skip_cleanup: true\n  cleanup: false\n"
  },
  {
    "path": "LICENSE",
    "content": "                    GNU GENERAL PUBLIC LICENSE\n                       Version 3, 29 June 2007\n\n Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>\n Everyone is permitted to copy and distribute verbatim copies\n of this license document, but changing it is not allowed.\n\n                            Preamble\n\n  The GNU General Public License is a free, copyleft license for\nsoftware and other kinds of works.\n\n  The licenses for most software and other practical works are designed\nto take away your freedom to share and change the works.  By contrast,\nthe GNU General Public License is intended to guarantee your freedom to\nshare and change all versions of a program--to make sure it remains free\nsoftware for all its users.  We, the Free Software Foundation, use the\nGNU General Public License for most of our software; it applies also to\nany other work released this way by its authors.  You can apply it to\nyour programs, too.\n\n  When we speak of free software, we are referring to freedom, not\nprice.  Our General Public Licenses are designed to make sure that you\nhave the freedom to distribute copies of free software (and charge for\nthem if you wish), that you receive source code or can get it if you\nwant it, that you can change the software or use pieces of it in new\nfree programs, and that you know you can do these things.\n\n  To protect your rights, we need to prevent others from denying you\nthese rights or asking you to surrender the rights.  Therefore, you have\ncertain responsibilities if you distribute copies of the software, or if\nyou modify it: responsibilities to respect the freedom of others.\n\n  For example, if you distribute copies of such a program, whether\ngratis or for a fee, you must pass on to the recipients the same\nfreedoms that you received.  You must make sure that they, too, receive\nor can get the source code.  And you must show them these terms so they\nknow their rights.\n\n  Developers that use the GNU GPL protect your rights with two steps:\n(1) assert copyright on the software, and (2) offer you this License\ngiving you legal permission to copy, distribute and/or modify it.\n\n  For the developers' and authors' protection, the GPL clearly explains\nthat there is no warranty for this free software.  For both users' and\nauthors' sake, the GPL requires that modified versions be marked as\nchanged, so that their problems will not be attributed erroneously to\nauthors of previous versions.\n\n  Some devices are designed to deny users access to install or run\nmodified versions of the software inside them, although the manufacturer\ncan do so.  This is fundamentally incompatible with the aim of\nprotecting users' freedom to change the software.  The systematic\npattern of such abuse occurs in the area of products for individuals to\nuse, which is precisely where it is most unacceptable.  Therefore, we\nhave designed this version of the GPL to prohibit the practice for those\nproducts.  If such problems arise substantially in other domains, we\nstand ready to extend this provision to those domains in future versions\nof the GPL, as needed to protect the freedom of users.\n\n  Finally, every program is threatened constantly by software patents.\nStates should not allow patents to restrict development and use of\nsoftware on general-purpose computers, but in those that do, we wish to\navoid the special danger that patents applied to a free program could\nmake it effectively proprietary.  To prevent this, the GPL assures that\npatents cannot be used to render the program non-free.\n\n  The precise terms and conditions for copying, distribution and\nmodification follow.\n\n                       TERMS AND CONDITIONS\n\n  0. Definitions.\n\n  \"This License\" refers to version 3 of the GNU General Public License.\n\n  \"Copyright\" also means copyright-like laws that apply to other kinds of\nworks, such as semiconductor masks.\n\n  \"The Program\" refers to any copyrightable work licensed under this\nLicense.  Each licensee is addressed as \"you\".  \"Licensees\" and\n\"recipients\" may be individuals or organizations.\n\n  To \"modify\" a work means to copy from or adapt all or part of the work\nin a fashion requiring copyright permission, other than the making of an\nexact copy.  The resulting work is called a \"modified version\" of the\nearlier work or a work \"based on\" the earlier work.\n\n  A \"covered work\" means either the unmodified Program or a work based\non the Program.\n\n  To \"propagate\" a work means to do anything with it that, without\npermission, would make you directly or secondarily liable for\ninfringement under applicable copyright law, except executing it on a\ncomputer or modifying a private copy.  Propagation includes copying,\ndistribution (with or without modification), making available to the\npublic, and in some countries other activities as well.\n\n  To \"convey\" a work means any kind of propagation that enables other\nparties to make or receive copies.  Mere interaction with a user through\na computer network, with no transfer of a copy, is not conveying.\n\n  An interactive user interface displays \"Appropriate Legal Notices\"\nto the extent that it includes a convenient and prominently visible\nfeature that (1) displays an appropriate copyright notice, and (2)\ntells the user that there is no warranty for the work (except to the\nextent that warranties are provided), that licensees may convey the\nwork under this License, and how to view a copy of this License.  If\nthe interface presents a list of user commands or options, such as a\nmenu, a prominent item in the list meets this criterion.\n\n  1. Source Code.\n\n  The \"source code\" for a work means the preferred form of the work\nfor making modifications to it.  \"Object code\" means any non-source\nform of a work.\n\n  A \"Standard Interface\" means an interface that either is an official\nstandard defined by a recognized standards body, or, in the case of\ninterfaces specified for a particular programming language, one that\nis widely used among developers working in that language.\n\n  The \"System Libraries\" of an executable work include anything, other\nthan the work as a whole, that (a) is included in the normal form of\npackaging a Major Component, but which is not part of that Major\nComponent, and (b) serves only to enable use of the work with that\nMajor Component, or to implement a Standard Interface for which an\nimplementation is available to the public in source code form.  A\n\"Major Component\", in this context, means a major essential component\n(kernel, window system, and so on) of the specific operating system\n(if any) on which the executable work runs, or a compiler used to\nproduce the work, or an object code interpreter used to run it.\n\n  The \"Corresponding Source\" for a work in object code form means all\nthe source code needed to generate, install, and (for an executable\nwork) run the object code and to modify the work, including scripts to\ncontrol those activities.  However, it does not include the work's\nSystem Libraries, or general-purpose tools or generally available free\nprograms which are used unmodified in performing those activities but\nwhich are not part of the work.  For example, Corresponding Source\nincludes interface definition files associated with source files for\nthe work, and the source code for shared libraries and dynamically\nlinked subprograms that the work is specifically designed to require,\nsuch as by intimate data communication or control flow between those\nsubprograms and other parts of the work.\n\n  The Corresponding Source need not include anything that users\ncan regenerate automatically from other parts of the Corresponding\nSource.\n\n  The Corresponding Source for a work in source code form is that\nsame work.\n\n  2. Basic Permissions.\n\n  All rights granted under this License are granted for the term of\ncopyright on the Program, and are irrevocable provided the stated\nconditions are met.  This License explicitly affirms your unlimited\npermission to run the unmodified Program.  The output from running a\ncovered work is covered by this License only if the output, given its\ncontent, constitutes a covered work.  This License acknowledges your\nrights of fair use or other equivalent, as provided by copyright law.\n\n  You may make, run and propagate covered works that you do not\nconvey, without conditions so long as your license otherwise remains\nin force.  You may convey covered works to others for the sole purpose\nof having them make modifications exclusively for you, or provide you\nwith facilities for running those works, provided that you comply with\nthe terms of this License in conveying all material for which you do\nnot control copyright.  Those thus making or running the covered works\nfor you must do so exclusively on your behalf, under your direction\nand control, on terms that prohibit them from making any copies of\nyour copyrighted material outside their relationship with you.\n\n  Conveying under any other circumstances is permitted solely under\nthe conditions stated below.  Sublicensing is not allowed; section 10\nmakes it unnecessary.\n\n  3. Protecting Users' Legal Rights From Anti-Circumvention Law.\n\n  No covered work shall be deemed part of an effective technological\nmeasure under any applicable law fulfilling obligations under article\n11 of the WIPO copyright treaty adopted on 20 December 1996, or\nsimilar laws prohibiting or restricting circumvention of such\nmeasures.\n\n  When you convey a covered work, you waive any legal power to forbid\ncircumvention of technological measures to the extent such circumvention\nis effected by exercising rights under this License with respect to\nthe covered work, and you disclaim any intention to limit operation or\nmodification of the work as a means of enforcing, against the work's\nusers, your or third parties' legal rights to forbid circumvention of\ntechnological measures.\n\n  4. Conveying Verbatim Copies.\n\n  You may convey verbatim copies of the Program's source code as you\nreceive it, in any medium, provided that you conspicuously and\nappropriately publish on each copy an appropriate copyright notice;\nkeep intact all notices stating that this License and any\nnon-permissive terms added in accord with section 7 apply to the code;\nkeep intact all notices of the absence of any warranty; and give all\nrecipients a copy of this License along with the Program.\n\n  You may charge any price or no price for each copy that you convey,\nand you may offer support or warranty protection for a fee.\n\n  5. Conveying Modified Source Versions.\n\n  You may convey a work based on the Program, or the modifications to\nproduce it from the Program, in the form of source code under the\nterms of section 4, provided that you also meet all of these conditions:\n\n    a) The work must carry prominent notices stating that you modified\n    it, and giving a relevant date.\n\n    b) The work must carry prominent notices stating that it is\n    released under this License and any conditions added under section\n    7.  This requirement modifies the requirement in section 4 to\n    \"keep intact all notices\".\n\n    c) You must license the entire work, as a whole, under this\n    License to anyone who comes into possession of a copy.  This\n    License will therefore apply, along with any applicable section 7\n    additional terms, to the whole of the work, and all its parts,\n    regardless of how they are packaged.  This License gives no\n    permission to license the work in any other way, but it does not\n    invalidate such permission if you have separately received it.\n\n    d) If the work has interactive user interfaces, each must display\n    Appropriate Legal Notices; however, if the Program has interactive\n    interfaces that do not display Appropriate Legal Notices, your\n    work need not make them do so.\n\n  A compilation of a covered work with other separate and independent\nworks, which are not by their nature extensions of the covered work,\nand which are not combined with it such as to form a larger program,\nin or on a volume of a storage or distribution medium, is called an\n\"aggregate\" if the compilation and its resulting copyright are not\nused to limit the access or legal rights of the compilation's users\nbeyond what the individual works permit.  Inclusion of a covered work\nin an aggregate does not cause this License to apply to the other\nparts of the aggregate.\n\n  6. Conveying Non-Source Forms.\n\n  You may convey a covered work in object code form under the terms\nof sections 4 and 5, provided that you also convey the\nmachine-readable Corresponding Source under the terms of this License,\nin one of these ways:\n\n    a) Convey the object code in, or embodied in, a physical product\n    (including a physical distribution medium), accompanied by the\n    Corresponding Source fixed on a durable physical medium\n    customarily used for software interchange.\n\n    b) Convey the object code in, or embodied in, a physical product\n    (including a physical distribution medium), accompanied by a\n    written offer, valid for at least three years and valid for as\n    long as you offer spare parts or customer support for that product\n    model, to give anyone who possesses the object code either (1) a\n    copy of the Corresponding Source for all the software in the\n    product that is covered by this License, on a durable physical\n    medium customarily used for software interchange, for a price no\n    more than your reasonable cost of physically performing this\n    conveying of source, or (2) access to copy the\n    Corresponding Source from a network server at no charge.\n\n    c) Convey individual copies of the object code with a copy of the\n    written offer to provide the Corresponding Source.  This\n    alternative is allowed only occasionally and noncommercially, and\n    only if you received the object code with such an offer, in accord\n    with subsection 6b.\n\n    d) Convey the object code by offering access from a designated\n    place (gratis or for a charge), and offer equivalent access to the\n    Corresponding Source in the same way through the same place at no\n    further charge.  You need not require recipients to copy the\n    Corresponding Source along with the object code.  If the place to\n    copy the object code is a network server, the Corresponding Source\n    may be on a different server (operated by you or a third party)\n    that supports equivalent copying facilities, provided you maintain\n    clear directions next to the object code saying where to find the\n    Corresponding Source.  Regardless of what server hosts the\n    Corresponding Source, you remain obligated to ensure that it is\n    available for as long as needed to satisfy these requirements.\n\n    e) Convey the object code using peer-to-peer transmission, provided\n    you inform other peers where the object code and Corresponding\n    Source of the work are being offered to the general public at no\n    charge under subsection 6d.\n\n  A separable portion of the object code, whose source code is excluded\nfrom the Corresponding Source as a System Library, need not be\nincluded in conveying the object code work.\n\n  A \"User Product\" is either (1) a \"consumer product\", which means any\ntangible personal property which is normally used for personal, family,\nor household purposes, or (2) anything designed or sold for incorporation\ninto a dwelling.  In determining whether a product is a consumer product,\ndoubtful cases shall be resolved in favor of coverage.  For a particular\nproduct received by a particular user, \"normally used\" refers to a\ntypical or common use of that class of product, regardless of the status\nof the particular user or of the way in which the particular user\nactually uses, or expects or is expected to use, the product.  A product\nis a consumer product regardless of whether the product has substantial\ncommercial, industrial or non-consumer uses, unless such uses represent\nthe only significant mode of use of the product.\n\n  \"Installation Information\" for a User Product means any methods,\nprocedures, authorization keys, or other information required to install\nand execute modified versions of a covered work in that User Product from\na modified version of its Corresponding Source.  The information must\nsuffice to ensure that the continued functioning of the modified object\ncode is in no case prevented or interfered with solely because\nmodification has been made.\n\n  If you convey an object code work under this section in, or with, or\nspecifically for use in, a User Product, and the conveying occurs as\npart of a transaction in which the right of possession and use of the\nUser Product is transferred to the recipient in perpetuity or for a\nfixed term (regardless of how the transaction is characterized), the\nCorresponding Source conveyed under this section must be accompanied\nby the Installation Information.  But this requirement does not apply\nif neither you nor any third party retains the ability to install\nmodified object code on the User Product (for example, the work has\nbeen installed in ROM).\n\n  The requirement to provide Installation Information does not include a\nrequirement to continue to provide support service, warranty, or updates\nfor a work that has been modified or installed by the recipient, or for\nthe User Product in which it has been modified or installed.  Access to a\nnetwork may be denied when the modification itself materially and\nadversely affects the operation of the network or violates the rules and\nprotocols for communication across the network.\n\n  Corresponding Source conveyed, and Installation Information provided,\nin accord with this section must be in a format that is publicly\ndocumented (and with an implementation available to the public in\nsource code form), and must require no special password or key for\nunpacking, reading or copying.\n\n  7. Additional Terms.\n\n  \"Additional permissions\" are terms that supplement the terms of this\nLicense by making exceptions from one or more of its conditions.\nAdditional permissions that are applicable to the entire Program shall\nbe treated as though they were included in this License, to the extent\nthat they are valid under applicable law.  If additional permissions\napply only to part of the Program, that part may be used separately\nunder those permissions, but the entire Program remains governed by\nthis License without regard to the additional permissions.\n\n  When you convey a copy of a covered work, you may at your option\nremove any additional permissions from that copy, or from any part of\nit.  (Additional permissions may be written to require their own\nremoval in certain cases when you modify the work.)  You may place\nadditional permissions on material, added by you to a covered work,\nfor which you have or can give appropriate copyright permission.\n\n  Notwithstanding any other provision of this License, for material you\nadd to a covered work, you may (if authorized by the copyright holders of\nthat material) supplement the terms of this License with terms:\n\n    a) Disclaiming warranty or limiting liability differently from the\n    terms of sections 15 and 16 of this License; or\n\n    b) Requiring preservation of specified reasonable legal notices or\n    author attributions in that material or in the Appropriate Legal\n    Notices displayed by works containing it; or\n\n    c) Prohibiting misrepresentation of the origin of that material, or\n    requiring that modified versions of such material be marked in\n    reasonable ways as different from the original version; or\n\n    d) Limiting the use for publicity purposes of names of licensors or\n    authors of the material; or\n\n    e) Declining to grant rights under trademark law for use of some\n    trade names, trademarks, or service marks; or\n\n    f) Requiring indemnification of licensors and authors of that\n    material by anyone who conveys the material (or modified versions of\n    it) with contractual assumptions of liability to the recipient, for\n    any liability that these contractual assumptions directly impose on\n    those licensors and authors.\n\n  All other non-permissive additional terms are considered \"further\nrestrictions\" within the meaning of section 10.  If the Program as you\nreceived it, or any part of it, contains a notice stating that it is\ngoverned by this License along with a term that is a further\nrestriction, you may remove that term.  If a license document contains\na further restriction but permits relicensing or conveying under this\nLicense, you may add to a covered work material governed by the terms\nof that license document, provided that the further restriction does\nnot survive such relicensing or conveying.\n\n  If you add terms to a covered work in accord with this section, you\nmust place, in the relevant source files, a statement of the\nadditional terms that apply to those files, or a notice indicating\nwhere to find the applicable terms.\n\n  Additional terms, permissive or non-permissive, may be stated in the\nform of a separately written license, or stated as exceptions;\nthe above requirements apply either way.\n\n  8. Termination.\n\n  You may not propagate or modify a covered work except as expressly\nprovided under this License.  Any attempt otherwise to propagate or\nmodify it is void, and will automatically terminate your rights under\nthis License (including any patent licenses granted under the third\nparagraph of section 11).\n\n  However, if you cease all violation of this License, then your\nlicense from a particular copyright holder is reinstated (a)\nprovisionally, unless and until the copyright holder explicitly and\nfinally terminates your license, and (b) permanently, if the copyright\nholder fails to notify you of the violation by some reasonable means\nprior to 60 days after the cessation.\n\n  Moreover, your license from a particular copyright holder is\nreinstated permanently if the copyright holder notifies you of the\nviolation by some reasonable means, this is the first time you have\nreceived notice of violation of this License (for any work) from that\ncopyright holder, and you cure the violation prior to 30 days after\nyour receipt of the notice.\n\n  Termination of your rights under this section does not terminate the\nlicenses of parties who have received copies or rights from you under\nthis License.  If your rights have been terminated and not permanently\nreinstated, you do not qualify to receive new licenses for the same\nmaterial under section 10.\n\n  9. Acceptance Not Required for Having Copies.\n\n  You are not required to accept this License in order to receive or\nrun a copy of the Program.  Ancillary propagation of a covered work\noccurring solely as a consequence of using peer-to-peer transmission\nto receive a copy likewise does not require acceptance.  However,\nnothing other than this License grants you permission to propagate or\nmodify any covered work.  These actions infringe copyright if you do\nnot accept this License.  Therefore, by modifying or propagating a\ncovered work, you indicate your acceptance of this License to do so.\n\n  10. Automatic Licensing of Downstream Recipients.\n\n  Each time you convey a covered work, the recipient automatically\nreceives a license from the original licensors, to run, modify and\npropagate that work, subject to this License.  You are not responsible\nfor enforcing compliance by third parties with this License.\n\n  An \"entity transaction\" is a transaction transferring control of an\norganization, or substantially all assets of one, or subdividing an\norganization, or merging organizations.  If propagation of a covered\nwork results from an entity transaction, each party to that\ntransaction who receives a copy of the work also receives whatever\nlicenses to the work the party's predecessor in interest had or could\ngive under the previous paragraph, plus a right to possession of the\nCorresponding Source of the work from the predecessor in interest, if\nthe predecessor has it or can get it with reasonable efforts.\n\n  You may not impose any further restrictions on the exercise of the\nrights granted or affirmed under this License.  For example, you may\nnot impose a license fee, royalty, or other charge for exercise of\nrights granted under this License, and you may not initiate litigation\n(including a cross-claim or counterclaim in a lawsuit) alleging that\nany patent claim is infringed by making, using, selling, offering for\nsale, or importing the Program or any portion of it.\n\n  11. Patents.\n\n  A \"contributor\" is a copyright holder who authorizes use under this\nLicense of the Program or a work on which the Program is based.  The\nwork thus licensed is called the contributor's \"contributor version\".\n\n  A contributor's \"essential patent claims\" are all patent claims\nowned or controlled by the contributor, whether already acquired or\nhereafter acquired, that would be infringed by some manner, permitted\nby this License, of making, using, or selling its contributor version,\nbut do not include claims that would be infringed only as a\nconsequence of further modification of the contributor version.  For\npurposes of this definition, \"control\" includes the right to grant\npatent sublicenses in a manner consistent with the requirements of\nthis License.\n\n  Each contributor grants you a non-exclusive, worldwide, royalty-free\npatent license under the contributor's essential patent claims, to\nmake, use, sell, offer for sale, import and otherwise run, modify and\npropagate the contents of its contributor version.\n\n  In the following three paragraphs, a \"patent license\" is any express\nagreement or commitment, however denominated, not to enforce a patent\n(such as an express permission to practice a patent or covenant not to\nsue for patent infringement).  To \"grant\" such a patent license to a\nparty means to make such an agreement or commitment not to enforce a\npatent against the party.\n\n  If you convey a covered work, knowingly relying on a patent license,\nand the Corresponding Source of the work is not available for anyone\nto copy, free of charge and under the terms of this License, through a\npublicly available network server or other readily accessible means,\nthen you must either (1) cause the Corresponding Source to be so\navailable, or (2) arrange to deprive yourself of the benefit of the\npatent license for this particular work, or (3) arrange, in a manner\nconsistent with the requirements of this License, to extend the patent\nlicense to downstream recipients.  \"Knowingly relying\" means you have\nactual knowledge that, but for the patent license, your conveying the\ncovered work in a country, or your recipient's use of the covered work\nin a country, would infringe one or more identifiable patents in that\ncountry that you have reason to believe are valid.\n\n  If, pursuant to or in connection with a single transaction or\narrangement, you convey, or propagate by procuring conveyance of, a\ncovered work, and grant a patent license to some of the parties\nreceiving the covered work authorizing them to use, propagate, modify\nor convey a specific copy of the covered work, then the patent license\nyou grant is automatically extended to all recipients of the covered\nwork and works based on it.\n\n  A patent license is \"discriminatory\" if it does not include within\nthe scope of its coverage, prohibits the exercise of, or is\nconditioned on the non-exercise of one or more of the rights that are\nspecifically granted under this License.  You may not convey a covered\nwork if you are a party to an arrangement with a third party that is\nin the business of distributing software, under which you make payment\nto the third party based on the extent of your activity of conveying\nthe work, and under which the third party grants, to any of the\nparties who would receive the covered work from you, a discriminatory\npatent license (a) in connection with copies of the covered work\nconveyed by you (or copies made from those copies), or (b) primarily\nfor and in connection with specific products or compilations that\ncontain the covered work, unless you entered into that arrangement,\nor that patent license was granted, prior to 28 March 2007.\n\n  Nothing in this License shall be construed as excluding or limiting\nany implied license or other defenses to infringement that may\notherwise be available to you under applicable patent law.\n\n  12. No Surrender of Others' Freedom.\n\n  If conditions are imposed on you (whether by court order, agreement or\notherwise) that contradict the conditions of this License, they do not\nexcuse you from the conditions of this License.  If you cannot convey a\ncovered work so as to satisfy simultaneously your obligations under this\nLicense and any other pertinent obligations, then as a consequence you may\nnot convey it at all.  For example, if you agree to terms that obligate you\nto collect a royalty for further conveying from those to whom you convey\nthe Program, the only way you could satisfy both those terms and this\nLicense would be to refrain entirely from conveying the Program.\n\n  13. Use with the GNU Affero General Public License.\n\n  Notwithstanding any other provision of this License, you have\npermission to link or combine any covered work with a work licensed\nunder version 3 of the GNU Affero General Public License into a single\ncombined work, and to convey the resulting work.  The terms of this\nLicense will continue to apply to the part which is the covered work,\nbut the special requirements of the GNU Affero General Public License,\nsection 13, concerning interaction through a network will apply to the\ncombination as such.\n\n  14. Revised Versions of this License.\n\n  The Free Software Foundation may publish revised and/or new versions of\nthe GNU General Public License from time to time.  Such new versions will\nbe similar in spirit to the present version, but may differ in detail to\naddress new problems or concerns.\n\n  Each version is given a distinguishing version number.  If the\nProgram specifies that a certain numbered version of the GNU General\nPublic License \"or any later version\" applies to it, you have the\noption of following the terms and conditions either of that numbered\nversion or of any later version published by the Free Software\nFoundation.  If the Program does not specify a version number of the\nGNU General Public License, you may choose any version ever published\nby the Free Software Foundation.\n\n  If the Program specifies that a proxy can decide which future\nversions of the GNU General Public License can be used, that proxy's\npublic statement of acceptance of a version permanently authorizes you\nto choose that version for the Program.\n\n  Later license versions may give you additional or different\npermissions.  However, no additional obligations are imposed on any\nauthor or copyright holder as a result of your choosing to follow a\nlater version.\n\n  15. Disclaimer of Warranty.\n\n  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY\nAPPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT\nHOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY\nOF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,\nTHE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\nPURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM\nIS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF\nALL NECESSARY SERVICING, REPAIR OR CORRECTION.\n\n  16. Limitation of Liability.\n\n  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING\nWILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS\nTHE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY\nGENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE\nUSE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF\nDATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD\nPARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),\nEVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF\nSUCH DAMAGES.\n\n  17. Interpretation of Sections 15 and 16.\n\n  If the disclaimer of warranty and limitation of liability provided\nabove cannot be given local legal effect according to their terms,\nreviewing courts shall apply local law that most closely approximates\nan absolute waiver of all civil liability in connection with the\nProgram, unless a warranty or assumption of liability accompanies a\ncopy of the Program in return for a fee.\n\n                     END OF TERMS AND CONDITIONS\n\n            How to Apply These Terms to Your New Programs\n\n  If you develop a new program, and you want it to be of the greatest\npossible use to the public, the best way to achieve this is to make it\nfree software which everyone can redistribute and change under these terms.\n\n  To do so, attach the following notices to the program.  It is safest\nto attach them to the start of each source file to most effectively\nstate the exclusion of warranty; and each file should have at least\nthe \"copyright\" line and a pointer to where the full notice is found.\n\n    <one line to give the program's name and a brief idea of what it does.>\n    Copyright (C) <year>  <name of author>\n\n    This program is free software: you can redistribute it and/or modify\n    it under the terms of the GNU General Public License as published by\n    the Free Software Foundation, either version 3 of the License, or\n    (at your option) any later version.\n\n    This program is distributed in the hope that it will be useful,\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n    GNU General Public License for more details.\n\n    You should have received a copy of the GNU General Public License\n    along with this program.  If not, see <https://www.gnu.org/licenses/>.\n\nAlso add information on how to contact you by electronic and paper mail.\n\n  If the program does terminal interaction, make it output a short\nnotice like this when it starts in an interactive mode:\n\n    <program>  Copyright (C) <year>  <name of author>\n    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.\n    This is free software, and you are welcome to redistribute it\n    under certain conditions; type `show c' for details.\n\nThe hypothetical commands `show w' and `show c' should show the appropriate\nparts of the General Public License.  Of course, your program's commands\nmight be different; for a GUI interface, you would use an \"about box\".\n\n  You should also get your employer (if you work as a programmer) or school,\nif any, to sign a \"copyright disclaimer\" for the program, if necessary.\nFor more information on this, and how to apply and follow the GNU GPL, see\n<https://www.gnu.org/licenses/>.\n\n  The GNU General Public License does not permit incorporating your program\ninto proprietary programs.  If your program is a subroutine library, you\nmay consider it more useful to permit linking proprietary applications with\nthe library.  If this is what you want to do, use the GNU Lesser General\nPublic License instead of this License.  But first, please read\n<https://www.gnu.org/licenses/why-not-lgpl.html>.\n"
  },
  {
    "path": "Makefile",
    "content": ".PHONY : update updatetools tools\n.PHONY : lint test integration coverage\n.PHONY : build\n.PHONY : clean cleancoverage cleantools\n\nPROJECT_PATH = $(shell pwd -L)\nTOOLSDIR = $(PROJECT_PATH)/tools\nBINDIR = $(PROJECT_PATH)/bin\nBUILDDIR = $(PROJECT_PATH)/.build\nGOFLAGS ::= ${GOFLAGS}\nCOVERDIR = $(PROJECT_PATH)/.coverage\nCOVEROUT = $(wildcard $(COVERDIR)/*.out)\nCOVERINTERCHANGE = $(COVEROUT:.out=.interchange)\nCOVERHTML = $(COVEROUT:.out=.html)\nCOVERXML = $(COVEROUT:.out=.xml)\nCOVERCOMBINED ::= $(COVERDIR)/combined.out\nBUILDNAME = remouse\n\n# Tools need to be enumerated here in order to support updating them.\n# They will only be used in the context of the /tools directory which\n# is a special sub-module that is only engaged when handling the tools.\n# We do this to prevent having tools included in the actual project\n# dependencies.\nTOOLS ::= github.com/golang/mock/mockgen\nTOOLS ::= $(TOOLS) golang.org/x/tools/cmd/goimports\nTOOLS ::= $(TOOLS) github.com/golangci/golangci-lint/cmd/golangci-lint\nTOOLS ::= $(TOOLS) github.com/axw/gocov/gocov\nTOOLS ::= $(TOOLS) github.com/matm/gocov-html\nTOOLS ::= $(TOOLS) github.com/AlekSi/gocov-xml\nTOOLS ::= $(TOOLS) github.com/wadey/gocovmerge\n\nUNIT_PKGS = $(shell go list ./... | sed 1d | paste -sd \",\" -)\n\nupdate:\n\tGO111MODULE=on go get -u\n\nupdatetools: cleantools\n\t# Regenerate the module files for the tools and then\n\t# reinstall them. This should be done periodically but\n\t# infrequently.\n\tcd $(TOOLSDIR) && GO111MODULE=on go get -u $(TOOLS)\n\t$(MAKE) $(BINDIR)\n\n$(BINDIR):\n\tcd $(TOOLSDIR) && GOBIN=$(BINDIR) go install $(TOOLS)\n\ntools: $(BINDIR)\n\t# This is an alias for generating the tools. Unless\n\t# $(BINDIR) is set elsewhere it will generate a local\n\t# /bin directory in the repo.\n\nfmt: $(BINDIR)\n\t# Apply goimports to all code files. Here we intentionally\n\t# ignore everything in /vendor if it is present.\n\tGO111MODULE=on \\\n\tGOFLAGS=\"$(GOFLAGS)\" \\\n\t$(BINDIR)/goimports -w -v \\\n\t-local github.com/kevinconway/ \\\n\t$(shell find . -type f -name '*.go' -not -path \"./vendor/*\")\n\nlint: $(BINDIR)\n\tGO111MODULE=on \\\n\tGOFLAGS=\"$(GOFLAGS)\" \\\n\t$(BINDIR)/golangci-lint run \\\n\t\t--config .golangci.yaml \\\n\t\t--print-resources-usage \\\n\t\t--verbose\n\ntest: $(BINDIR) $(COVERDIR)\n\tGO111MODULE=on \\\n\tGOFLAGS=\"$(GOFLAGS)\" \\\n\tgo test \\\n\t\t-v \\\n\t\t-cover \\\n\t\t-race \\\n\t\t-coverpkg=\"$(UNIT_PKGS)\" \\\n\t\t-coverprofile=\"$(COVERDIR)/unit.out\" \\\n\t\t./...\n\nbuild: $(BUILDDIR)\n\t# Optionally build the service if it has an executable\n\t# present in the project root.\n\tGO111MODULE=on \\\n\tGOFLAGS=\"$(GOFLAGS)\" \\\n\tgo build -o $(BUILDDIR)/$(BUILDNAME) main.go\n\n$(BUILDDIR):\n\tmkdir -p $(BUILDDIR)\n\ngenerate: $(BINDIR)\n\t# Run any code generation steps.\n\tGO111MODULE=on \\\n\tGOFLAGS=\"$(GOFLAGS)\" \\\n\tPATH=\"${PATH}:$(BINDIR)\" \\\n\tgo generate github.com/kevinconway/remouseable/pkg github.com/kevinconway/remouseable/pkg/internal\n\t$(MAKE) fmt\n\ncoverage: $(BINDIR) $(COVERDIR) $(COVERCOMBINED) $(COVERINTERCHANGE) $(COVERHTML) $(COVERXML)\n\t# The cover rule is an alias for a number of other rules that each\n\t# generate part of the full coverage report. First, any coverage reports\n\t# are combined so that there is a report both for an individual test run\n\t# and a report that covers all test runs together. Then all coverage\n\t# files are converted to an interchange format. From there we generate\n\t# an HTML and XML report. XML reports may be used with jUnit style parsers,\n\t# the HTML report is for human consumption in order to help identify\n\t# the location of coverage gaps, and the original reports are available\n\t# for any purpose.\n\tGO111MODULE=on \\\n\tGOFLAGS=\"$(GOFLAGS)\" \\\n\tgo tool cover -func $(COVERCOMBINED)\n\n$(COVERCOMBINED):\n\tGO111MODULE=on \\\n\tGOFLAGS=\"$(GOFLAGS)\" \\\n \t$(BINDIR)/gocovmerge $(COVERDIR)/*.out > $(COVERCOMBINED)\n\n\t# NOTE: I couldn't figure out how to automatically include\n\t# the combined files with the list of other .out files that\n\t# are processed in bulk. For now, this needs to have specific\n\t# calls to make for combined coverage.\n\t$(MAKE) $(COVERCOMBINED:.out=.interchange)\n\t$(MAKE) $(COVERCOMBINED:.out=.xml)\n\t$(MAKE) $(COVERCOMBINED:.out=.html)\n\n$(COVERDIR)/%.interchange: $(COVERDIR)/%.out\n\tGO111MODULE=on \\\n\tGOFLAGS=\"$(GOFLAGS)\" \\\n\t$(BINDIR)/gocov convert $< > $@\n\n$(COVERDIR)/%.xml: $(COVERDIR)/%.interchange\n\tcat $< | \\\n\tGO111MODULE=on \\\n\tGOFLAGS=\"$(GOFLAGS)\" \\\n\t$(BINDIR)/gocov-xml > $@\n\n$(COVERDIR)/%.html: $(COVERDIR)/%.interchange\n\tcat $< | \\\n\tGO111MODULE=on \\\n\tGOFLAGS=\"$(GOFLAGS)\" \\\n\t$(BINDIR)/gocov-html > $@\n\n$(COVERDIR):\n\tmkdir -p $(COVERDIR)\n\nclean: cleancoverage cleantools ;\n\ncleantools:\n\trm -rf $(BINDIR)\n\ncleancoverage:\n\trm -rf $(COVERDIR)\n"
  },
  {
    "path": "README.md",
    "content": "# reMouseable\n\n> Use your reMarkable tablet as a mouse.\n\n- [reMouseable](#remouseable)\n  - [Update From September 19, 2024](#update-from-september-19-2024)\n  - [Overview](#overview)\n  - [Code And Developer Documentation](#code-and-developer-documentation)\n  - [Installation](#installation)\n    - [Windows](#windows)\n    - [OSX](#osx)\n    - [Linux](#linux)\n  - [Usage](#usage)\n    - [reMarkable 2 Tablets](#remarkable-2-tablets)\n    - [Wireless Tablet](#wireless-tablet)\n    - [Advanced SSH Setup](#advanced-ssh-setup)\n    - [All Options](#all-options)\n  - [Common Issues And Solutions](#common-issues-and-solutions)\n    - [OSX Privacy Settings](#osx-privacy-settings)\n    - [Getting \"panic: dial unix: missing address\" On Windows](#getting-panic-dial-unix-missing-address-on-windows)\n  - [Building](#building)\n    - [Linux](#linux-1)\n    - [OSX](#osx-1)\n    - [Windows](#windows-1)\n      - [Windows On Linux](#windows-on-linux)\n  - [How It Works](#how-it-works)\n  - [License](#license)\n  - [Developing](#developing)\n  - [Thanks](#thanks)\n\n## Update From September 19, 2024\n\nI somewhat recently had a one-off need to connect my tablet and run remouseable\nagain. Once my tablet installed the last few years of updates then I hit the\nsame issue as anyone else trying to use this project over the past year and a\nhalf to two years. I'm sharing the fix with folks in case someone finds it\nuseful but **remouseable is still discontinued**.\n\nRemousable was broken for long enough that I expect nearly everyone who once\nused it has moved on. If you start using it again or are considering using it\nfor the first time then I wish you the best. Please understand, though, that I\ndo not have time to support you if you need help or encounter an issue. I've\nleft the GitHub issues enabled so anyone using this can request or offer help to\nothers but I do not monitor the issues and will not respond to them myself.\n\nYou can download the fixed executables from\nhttps://github.com/kevinconway/remouseable/releases and follow this README's\ninstructions on how to install them. However, consider\nhttps://github.com/Evidlo/remarkable_mouse as a replacement that continued\nworking while remouseable was broken and continues to have people contributing\nto it. It also supports more features than this project such as multi-monitor\nsupport.\n\nIf you are a developer and want to add new features then please fork the\nproject. I've added GitHub actions workflows to automate building new\nexecutables and a [devcontainer](https://containers.dev/) to make running a fork\neven easier. If you maintain a fork with newer or better features than mine then\nI'm happy to add a link to your project here.\n\n## Overview\n\nI'm a user of the [reMarkable](https://remarkable.com/) tablet. After using it\nfor a while I started wondering if it could be used as an input for my\ncomputer so I could write and draw on digital whiteboards. It turns out, it can!\n\nThere's a great implementation of this feature written in Python at\n<https://github.com/Evidlo/remarkable_mouse>. I'm working on this\nimplementation so that I can offer pre-built binaries that don't require a\nspecific language to be installed on the host machine.\n\n## Code And Developer Documentation\n\nThis README contains how-to information for installing, configuration, and using\nthe project. To view the code API documentation check out the\n[godocs](https://godoc.org/github.com/kevinconway/remouseable).\n\nIf you would like to modify the project or add a feature then see the technical\ndocumentation in the `technical-documentation` directory.\n\n## Installation\n\n### Windows\n\nGo to <https://github.com/kevinconway/remouseable/releases/latest> and download\nthe file named `windows.exe`. Then rename the file to `remouseable.exe`. You\ncan now open the Windows command prompt and start the program with:\n\n```shell\ncd Downloads\nremouseable.exe\n```\n\nIf a new version of the program comes out then you can overwrite your\n`remouseable.exe` with a new version using exactly the same steps.\n\n### OSX\n\nGo to <https://github.com/kevinconway/remouseable/releases/latest> and download\nthe file named `osx-arm` if using an M series model or `osx-amd` if using a\nmodel older than M1. Then rename the file to `remouseable`. Next, make the\nprogram runnable with by opening a command line prompt and:\n\n```shell\ncd ~/Downloads\nchmod +x remouseable\n```\n\nYou can now run the program by opening a command line prompt and:\n\n```shell\ncd ~/Downloads\n./remouseable\n```\n\nNote that the first time you run the application your system will prompt you\nwith a security notice. The remouseable application works by controlling your\nmouse and OSX does not allow this by default. To enable the application you\nmust grant your command line prompt accessibility settings which allow it to\nmove the mouse. To do this, navigate to\n`System Preferences -> Security & Privacy -> Privacy -> Accessibility`. You will\nsee your terminal or shell in the list of applications that have requested\naccessibility permissions.\n\nIf you'd like to be able to launch the application through spotlight instead of\nonly the terminal then check out <https://github.com/isaacwisdom/reMouseableApp>\nwhere another developer has created an Applscript wrapper that makes remouseable\nact more like a typical OSX application.\n\n### Linux\n\nGo to <https://github.com/kevinconway/remouseable/releases/latest> and download\nthe file named `linux`. Then rename the file to `remouseable`. Next, make the\nprogram runnable with by opening a command line prompt and:\n\n```shell\ncd ~/Downloads\nchmod +x remouseable\n```\n\nYou can now run the program by opening a command line prompt and:\n\n```shell\ncd ~/Downloads\n./remouseable\n```\n\nNote that project only works in an X11 environment. If your system uses Wayland\nthen touching the tablet with the mouse will result in a remote desktop prompt\ndue to something related to Wayland's X11 backwards compatibility choices. Even\nif you allow the connection the application will not work correctly. Some forum\nthreads such as [this](https://discussion.fedoraproject.org/t/fedora-39-keeps-spaming-confirmation-remote-desktop-window/98323)\nor [this](https://discussion.fedoraproject.org/t/getting-spammed-with-remote-desktop-connection-window/115561)\nmay provide some help but Wayland is technically not supported.\n\n## Usage\n\nMost settings default to the correct values. The only value you should need to\nset in the common case is the SSH password for the tablet. This password value\nis found in the settings menu under `Help` and then `Copyrights and licenses`.\nYour password will be near the bottom of the page. If you have an older tablet\nthat has not been updated to the latest software then your password may be\nfound in the `About` tab of the tablet menu at the bottom of the `General\nInformation` section. You may either give the password as text with\n\n```bash\nremouseable --ssh-password=\"XYZ123\"\n```\n\nor you may choose to have a password prompt with:\n\n```bash\nremouseable --ssh-password=\"-\"\n```\n\nRun one of these commands with your device connected over USB and your stylus\nwill become a mouse. The stylus is actually active _before_ it touches the\nscreen. This means you can see your mouse move by hovering the stylus just above\nthe writing surface but without directly touching the tablet. Once you touch the\ntablet surface with the stylus the computer mouse will click and hold down the\nleft mouse button while you write or draw and then release the button when you\nlift the stylus.\n\n### reMarkable 2 Tablets\n\nThe application should work with both reMarkable and reMarkable 2 tablets.\nHowever, the reMarkable 2 requires that you add\n`--event-file /dev/input/event1` when executing because of a slight change in\nwhere the stylus events are written in the new tablets. The full command should\nlook like\n`remousable --ssh-password=\"MYPASSWORD\" --event-file=\"/dev/input/event1\"`.\n\n### Wireless Tablet\n\nThe default expectation is that you will have your tablet connected over USB\nwhich makes the default `10.11.99.1` address available. However, it is also\npossible to access your device over wifi. If you attempt this method then you\nwill need to arrange for a static, or at least consistent, IP address for the\ntablet. This is something you can usually do through configuring your router to\nassign a fixed IP address to the device based on the hardware MAC address.\n\nIf you cannot assign the same `10.11.99.1` address in your setup then you may\noverride the default IP address when running the application:\n\n### Advanced SSH Setup\n\nBy default, the tablet only accepts the root password for authentication. It is\npossible, though, to install a custom public key on the device so that you can\nuse either password-less authentication or use a key pair that is encrypted with\nthe password of your choice rather than the device's default password.\n\nIf you'd like to create a key pair especially for accessing the reMarkable\ntablet then start with a guide like\n<https://help.github.com/en/articles/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent>\nthat walks through creating a new key pair and registering it with your SSH\nagent. For even more advanced SSH users, such as those using the gpg-agent as\nthe SSH agent, the remouseable application will talk to any valid SSH agent\nimplementation so long as the `SSH_AUTH_SOCK` value is set correctly.\n\nOnce you have a key pair ready, copy the public key value from `ssh-add -L` for\nthe key you want to use. Then copy the key over to your tablet with:\n\n```bash\nssh root@10.11.99.1 # This will prompt for password.\nmkdir -p ~/.ssh # This directory does not exist by default.\necho 'INSERT YOUR PUBLIC KEY HERE' >> ~/.ssh/authorized_keys\n```\n\nNow future connections over SSH will leverage your key pair and you can omit\nthe usual password flag when running the application.\n\nNote that windows builds cannot use this option due to incompatibilities with\nthe current version of the windows ssh-agent.\n\nNote that if you encounter the `Invalid MIT-MAGIC-COOKIE-1 key` error it means\nthat most likely the ssh fingerprint of the device might have changed to an\nupdate of the tablet OS. Follow the ssh suggestion of removing the outdated\nfingerprint then if you are satisfied that your device is indeed the right one\ntry connecting again.\n\n```bash\nremouseable --ssh-ip=\"192.168.1.110:22\" # or other IP\n```\n\n### All Options\n\n```\n$ remouseable -h\nUsage of remouseable:\n      --debug-events             Stream hardware events from the tablet instead of acting as a mouse. This is for debugging.\n      --disable-drag-event       Disable use of the custom OSX drag event. Only use this drawing on an Apple device is not working as expected.\n      --event-file string        The path on the tablet from which to read evdev events. Probably don't change this. (default \"/dev/input/event0\")\n      --orientation string       Orientation of the tablet. Choices are vertical, right, and left (default \"right\")\n      --pressure-threshold int   Change the click detection sensitivity. 1000 is when the pen makes contact with the tablet. Set higher to require more pen pressure for a click. (default 1000)\n      --screen-height int        The max units per millimeter of the host screen height. Probably don't change this. (default 1080)\n      --screen-width int         The max units per millimeter of the host screen width. Probably don't change this. (default 1920)\n      --ssh-ip string            The host and port of a tablet. (default \"10.11.99.1:22\")\n      --ssh-password string      An optional password to use when ssh-ing into the tablet. Use - for a prompt rather than entering a value. If not given then public/private keypair authentication is used.\n      --ssh-socket string        Path to the SSH auth socket. This must not be empty if using public/private keypair authentication.\n      --ssh-user string          The ssh username to use when logging into the tablet. (default \"root\")\n      --tablet-height int        The max units per millimeter for the hight of the tablet. Probably don't change this. (default 15725)\n      --tablet-width int         The max units per millimeter for the width of the tablet. Probably don't change this. (default 20967)\npflag: help requested\nexit status 2\n```\n\n## Common Issues And Solutions\n\n### OSX Privacy Settings\n\nIf you are using this on an Apple or OSX device then you will need to give the\nterminal or shell you are using permissions to control your mouse. Mouse\npermissions are treated as an accessibility feature. If you are not prompted by\nthe operating system to update your permissions the first time you run the\napplication then you can navigate to\n`System Preferences -> Security & Privacy -> Privacy -> Accessibility`. You will\nsee your terminal or shell in the list of applications that have requested\naccessibility permissions.\n\n### Getting \"panic: dial unix: missing address\" On Windows\n\nThis error message happens most often when the `--ssh-password` flag is missing\nwhen running the application. On Windows, you must run the application with\neither `remouseable.exe --ssh-password=\"MYPASSWORD\"` or\n`remouseable.exe --ssh-password=\"-\"`.\n\n## Building\n\nThere are pre-built binaries attached to each release that should work for all\n64bit versions of linux, osx, and windows. However, if you prefer to generate\nyour own build then the following sections detail building a binary on\ndifferent platforms.\n\n### Linux\n\nLinux builds are dependent on:\n\n- gcc\n- x11 dev headers\n- xtst dev headers\n- xorg dev headers\n\nThese package will vary by name depending on your chosen linux distro. Debian\nand Ubuntu users can install these with:\n\n```shell\napt-get install -y gcc libc6-dev libx11-dev xorg-dev libxtst-dev\n```\n\nFrom there you run `make build`.\n\n### OSX\n\nOSX builds will require xcode and the xcode command line tools. These must be\ninstalled through the Apple store.\n\nBeyond xcode the build also requires installing support for gnu make if you want\nto use the Makefile for generating a build. Homebrew users can install this\nwith:\n\n```shell\nbrew install make coreutils findutils gnu-tar gnu-sed gawk gnutls gnu-indent gnu-getopt grep\nexport PATH=\"$(brew --prefix)/opt/make/libexec/gnubin:${PATH}\"\n```\n\nFrom there you run `make build`.\n\n### Windows\n\nWindows builds require a GCC implementation. I recommend\n<https://jmeubank.github.io/tdm-gcc/>. During installation you will be given the\noption to add the GCC install to your path. If you choose not to then you will\nneed to temporarily add it to your path in PowerShell with:\n\n```shell\n$env:Path += \";C:\\TDM-GCC-64\\bin\\\"\n```\n\nThe included Makefile contains too many bash specific commands to work in\nPowerShell but you can still generate a binary by running:\n\n```shell\ngo build main.go\n```\n\n#### Windows On Linux\n\nIf you want to generate a windows build from a linux machine then you will need\nto install a MinGW implementation. Debian and Ubuntu users can do this with:\n\n```shell\napt-get install -y gcc-multilib gcc-mingw-w64\n```\n\nThe included Makefile does not have a build option for this but you can generate\nthe binary with:\n\n```shell\nCC=x86_64-w64-mingw32-gcc GOOS=windows go build main.go\n```\n\n## How It Works\n\nThe project is implemented as a set of successive layers that turn the tablet\ninto a mouse. It follows as:\n\n-   SSH into the device and start streaming `evdev` data back to the host.\n-   Convert the raw byte stream into structured `evdev` data containers.\n-   Feed all events into a state machine that emits higher level state change\n    events like \"CLICK\" and \"MOVE\".\n-   Use state change events as a trigger for moving or clicking the mouse\n    on the host machine.\n\nEach of these layers has an interface defined in the `pkg/domain.go` file.\n\nThe mouse interactions on the host are performed by using a modified version of\n<https://github.com/go-vgo/robotgo>. The `pkg/internal/robotgo` directory\ncontains a stripped down version of `robotgo` that contains only the portions\nrequired to detect the screen dimensions and send mouse events. The actual\n`robotgo` project contains support for a much larger set of features such as\ntaking screen shots and controlling windows on the screen. However, each of\nthose additional features comes with additional system dependencies that make\ncreating a portable binary build difficult.\n\n## License\n\n    remouseable is free software: you can redistribute it and/or modify\n    it under the terms of the GNU General Public License version 3 as published\n    by the Free Software Foundation.\n\n    remouseable is distributed in the hope that it will be useful,\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n    GNU General Public License for more details.\n\n    You should have received a copy of the GNU General Public License\n    along with remouseable.  If not, see <https://www.gnu.org/licenses/>\n\n## Developing\n\nThis project is go1.16+ compatible. A Makefile is included to make some things\neasier. Some make targets of note:\n\n-   make generate\n\n    Re-generate any automatically generated code. Note that there is a gomock\n    bug making it necessary to manually modify the files after generation\n    because it adds a cyclical import.\n\n-   make test\n\n    Run all the unit tests and generate a coverage report in `.coverage/`.\n\n-   make lint\n\n    Run the golangci-lint suite using the included configuration.\n\n-   make fmt\n\n    Apply `goimports` formatting.\n\n-   make build\n\n    Generate a binary from the current project state.\n\n-   make tools\n\n    Generate a `.bin/` directory that contains a built version of each of the\n    tools used to build and test the project.\n\n-   make update / make updatetools\n\n    Run `go get -u` for the project or for the project tooling.\n\n-   make clean / make cleantools / make cleancoverage\n\n    Remove files generated by the Makefile. The top-level `clean` should remove\n    all artifacts such as `./bin` and `./coverage`. The other are scoped to\n    specific artifacts for cases where, for example, you want to remove old\n    coverage reports and regenerate them.\n\n## Thanks\n\nI used the <https://github.com/gvalkov/golang-evdev> project as a reference when\nimplementing the `evdev` parser. I didn't use it directly because it is very\nmuch oriented towards directly opening and managing a file descriptor for a\ndevice. This project needs to read data from a remote device.\n\nI used the <https://github.com/go-vgo/robotgo> project as the basis for\ninteracting with the operating system. I embedded portions of it here instead\nof importing the Go package in order to limit the number of dependencies\nrequired to build the project.\n"
  },
  {
    "path": "go.mod",
    "content": "module github.com/kevinconway/remouseable\n\ngo 1.23\n\nrequire (\n\tgithub.com/dave/jennifer v1.7.1\n\tgithub.com/golang/mock v1.6.0\n\tgithub.com/spf13/pflag v1.0.5\n\tgithub.com/stretchr/testify v1.9.0\n\tgolang.org/x/crypto v0.27.0\n\tgolang.org/x/sys v0.25.0\n\tgolang.org/x/term v0.24.0\n)\n\nrequire (\n\tgithub.com/davecgh/go-spew v1.1.1 // indirect\n\tgithub.com/pmezard/go-difflib v1.0.0 // indirect\n\tgopkg.in/yaml.v3 v3.0.1 // indirect\n)\n"
  },
  {
    "path": "go.sum",
    "content": "github.com/dave/jennifer v1.7.1 h1:B4jJJDHelWcDhlRQxWeo0Npa/pYKBLrirAQoTN45txo=\ngithub.com/dave/jennifer v1.7.1/go.mod h1:nXbxhEmQfOZhWml3D1cDK5M1FLnMSozpbFN/m3RmGZc=\ngithub.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=\ngithub.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=\ngithub.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc=\ngithub.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=\ngithub.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=\ngithub.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=\ngithub.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=\ngithub.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=\ngithub.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=\ngithub.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=\ngithub.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=\ngolang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=\ngolang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=\ngolang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A=\ngolang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70=\ngolang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=\ngolang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=\ngolang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=\ngolang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34=\ngolang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=\ngolang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=\ngolang.org/x/term v0.24.0 h1:Mh5cbb+Zk2hqqXNO7S1iTjEphVL+jb8ZWaqh/g+JWkM=\ngolang.org/x/term v0.24.0/go.mod h1:lOBK/LVxemqiMij05LGJ0tzNr8xlmwBRJ81PX6wVLH8=\ngolang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=\ngolang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=\ngolang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=\ngolang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=\ngolang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngolang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngolang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=\ngopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=\ngopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=\ngopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=\n"
  },
  {
    "path": "main.go",
    "content": "// This file is part of remouseable.\n//\n// remouseable is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License version 3 as published\n// by the Free Software Foundation.\n//\n// remouseable is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with remouseable.  If not, see <https://www.gnu.org/licenses/>.\n\npackage main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net\"\n\t\"os\"\n\t\"syscall\"\n\n\tflag \"github.com/spf13/pflag\"\n\t\"golang.org/x/crypto/ssh\"\n\t\"golang.org/x/crypto/ssh/agent\"\n\t\"golang.org/x/term\"\n\n\tremouseable \"github.com/kevinconway/remouseable/pkg\"\n)\n\nfunc main() {\n\n\tdriver := &remouseable.RobotgoDriver{}\n\n\tfs := flag.NewFlagSet(\"remouseable\", flag.ExitOnError)\n\torientation := fs.String(\"orientation\", \"right\", \"Orientation of the tablet. Choices are vertical, right, and left\")\n\ttabletHeight := fs.Int(\"tablet-height\", remouseable.DefaultTabletHeight, \"The max units per millimeter for the hight of the tablet. Probably don't change this.\")\n\ttabletWidth := fs.Int(\"tablet-width\", remouseable.DefaultTabletWidth, \"The max units per millimeter for the width of the tablet. Probably don't change this.\")\n\ttmpScreenWidth, tmpScreenHeight, _ := driver.GetSize()\n\tscreenHeight := fs.Int(\"screen-height\", tmpScreenHeight, \"The max units per millimeter of the host screen height. Probably don't change this.\")\n\tscreenWidth := fs.Int(\"screen-width\", tmpScreenWidth, \"The max units per millimeter of the host screen width. Probably don't change this.\")\n\tsshIP := fs.String(\"ssh-ip\", \"10.11.99.1:22\", \"The host and port of a tablet.\")\n\tsshUser := fs.String(\"ssh-user\", \"root\", \"The ssh username to use when logging into the tablet.\")\n\tsshPassword := fs.String(\"ssh-password\", \"\", \"An optional password to use when ssh-ing into the tablet. Use - for a prompt rather than entering a value. If not given then public/private keypair authentication is used.\")\n\tsshSocket := fs.String(\"ssh-socket\", os.Getenv(\"SSH_AUTH_SOCK\"), \"Path to the SSH auth socket. This must not be empty if using public/private keypair authentication.\")\n\tevtFile := fs.String(\"event-file\", \"/dev/input/event0\", \"The path on the tablet from which to read evdev events. Probably don't change this.\")\n\tdebugEvents := fs.Bool(\"debug-events\", false, \"Stream hardware events from the tablet instead of acting as a mouse. This is for debugging.\")\n\tdisableDrag := fs.Bool(\"disable-drag-event\", false, \"Disable use of the custom OSX drag event. Only use this drawing on an Apple device is not working as expected.\")\n\tpressureThreshold := fs.Int(\"pressure-threshold\", 1000, \"Change the click detection sensitivity. 1000 is when the pen makes contact with the tablet. Set higher to require more pen pressure for a click.\")\n\t_ = fs.Parse(os.Args[1:])\n\n\tif *sshPassword == \"-\" {\n\t\tfmt.Print(\"Enter Password: \")\n\t\tpwd, err := term.ReadPassword(int(syscall.Stdin))\n\t\tif err != nil {\n\t\t\tpanic(err)\n\t\t}\n\t\t*sshPassword = string(pwd)\n\t}\n\tsshConfig := &ssh.ClientConfig{\n\t\tUser: *sshUser,\n\t\tAuth: []ssh.AuthMethod{\n\t\t\tssh.Password(*sshPassword),\n\t\t},\n\t\tHostKeyAlgorithms: []string{\n\t\t\t\"ecdsa-sha2-nistp256\",\n\t\t\t\"ecdsa-sha2-nistp384\",\n\t\t\t\"ecdsa-sha2-nistp521\",\n\t\t\t\"ssh-ed25519\",\n\t\t\t\"rsa-sha2-256\",\n\t\t\t\"rsa-sha2-512\",\n\t\t\t\"ssh-rsa\",\n\t\t},\n\t\tHostKeyCallback: ssh.InsecureIgnoreHostKey(), //nolint:gosec\n\t}\n\tif *sshPassword == \"\" {\n\t\tagentFd, err := net.Dial(\"unix\", *sshSocket)\n\t\tif err != nil {\n\t\t\tpanic(err)\n\t\t}\n\t\tdefer agentFd.Close()\n\n\t\tagentSigner := agent.NewClient(agentFd)\n\n\t\tsshConfig.Auth = []ssh.AuthMethod{\n\t\t\tssh.PublicKeysCallback(agentSigner.Signers),\n\t\t}\n\t}\n\n\tclient, err := ssh.Dial(\"tcp\", *sshIP, sshConfig)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\tsesh, err := client.NewSession()\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer sesh.Close()\n\n\tpipe, err := sesh.StdoutPipe()\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tif err = sesh.Start(fmt.Sprintf(\"cat %s\", *evtFile)); err != nil {\n\t\tpanic(err)\n\t}\n\tif *debugEvents {\n\t\tit := &remouseable.SelectingEvdevIterator{\n\t\t\tWrapped: &remouseable.FileEvdevIterator{\n\t\t\t\tSource: io.NopCloser(pipe),\n\t\t\t},\n\t\t\tSelection: []uint16{remouseable.EV_ABS},\n\t\t}\n\t\tdefer it.Close()\n\t\tfmt.Println(\"remouseable connected and running.\")\n\t\tfor it.Next() {\n\t\t\tevt := it.Current()\n\t\t\tevtype := remouseable.EVMap[evt.Type]\n\t\t\tevcode := remouseable.CodeString(evt.Type, evt.Code)\n\t\t\tfmt.Printf(\n\t\t\t\t`{\"eventType\": %d, \"eventTypeName\": \"%s\", \"eventCode\": %d, \"eventCodeName\": \"%s\", \"eventValue\": %d}`,\n\t\t\t\tevt.Type, evtype, evt.Code, evcode, evt.Value,\n\t\t\t)\n\t\t\tfmt.Print(\"\\n\")\n\t\t}\n\t\tif err = it.Close(); err != nil {\n\t\t\tpanic(err.Error())\n\t\t}\n\t\treturn\n\t}\n\n\tit := &remouseable.SelectingEvdevIterator{\n\t\tWrapped: &remouseable.FileEvdevIterator{\n\t\t\tSource: io.NopCloser(pipe),\n\t\t},\n\t\tSelection: []uint16{remouseable.EV_ABS},\n\t}\n\tdefer it.Close()\n\n\tvar sm remouseable.StateMachine = &remouseable.DraggingEvdevStateMachine{\n\t\tEvdevStateMachine: &remouseable.EvdevStateMachine{\n\t\t\tIterator:          it,\n\t\t\tPressureThreshold: *pressureThreshold,\n\t\t},\n\t}\n\tif *disableDrag {\n\t\tsm = &remouseable.EvdevStateMachine{\n\t\t\tIterator:          it,\n\t\t\tPressureThreshold: *pressureThreshold,\n\t\t}\n\t}\n\tdefer sm.Close()\n\n\tvar sc remouseable.PositionScaler\n\tswitch *orientation {\n\tcase \"right\":\n\t\tsc = &remouseable.RightPositionScaler{\n\t\t\tTabletWidth:  *tabletWidth,\n\t\t\tTabletHeight: *tabletHeight,\n\t\t\tScreenWidth:  *screenWidth,\n\t\t\tScreenHeight: *screenHeight,\n\t\t}\n\tcase \"left\":\n\t\tsc = &remouseable.LeftPositionScaler{\n\t\t\tTabletWidth:  *tabletWidth,\n\t\t\tTabletHeight: *tabletHeight,\n\t\t\tScreenWidth:  *screenWidth,\n\t\t\tScreenHeight: *screenHeight,\n\t\t}\n\tcase \"vertical\":\n\t\tsc = &remouseable.VerticalPositionScaler{\n\t\t\tTabletWidth:  *tabletWidth,\n\t\t\tTabletHeight: *tabletHeight,\n\t\t\tScreenWidth:  *screenWidth,\n\t\t\tScreenHeight: *screenHeight,\n\t\t}\n\tdefault:\n\t\tpanic(fmt.Sprintf(\"unknown orienation selection %s\", *orientation))\n\t}\n\n\trt := &remouseable.Runtime{\n\t\tPositionScaler: sc,\n\t\tStateMachine:   sm,\n\t\tDriver:         driver,\n\t}\n\n\tfmt.Println(\"remouseable connected and running.\")\n\tfor rt.Next() {\n\t}\n\tif err = rt.Close(); err != nil {\n\t\tpanic(err)\n\t}\n}\n"
  },
  {
    "path": "pkg/domain.go",
    "content": "// This file is part of remouseable.\n//\n// remouseable is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License version 3 as published\n// by the Free Software Foundation.\n//\n// remouseable is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with remouseable.  If not, see <https://www.gnu.org/licenses/>.\n\npackage remouseable\n\nimport \"time\"\n\n// EvdevEvent is a container type for raw evdev events. It is structured\n// such that it can be used with the encoding/binary package to unmarshal\n// raw events from the binary format.\ntype EvdevEvent struct {\n\t// Time of the event\n\tTime time.Time\n\t// Type is one of the EV_* named constants in evdevcodes.go\n\tType uint16\n\t// Code is the relevant event constant from evdevcodes.go\n\tCode uint16\n\t// Numeric value of the event. Dependent on the event type.\n\tValue int32\n}\n\n// EvdevIterator represents a source of EvdevEvent instances. This is generally\n// sourced from a /dev/input/event* file but may have alternative\n// implementations for special use cases. For example, alternatives may be\n// streaming events from a network source or replaying of static data for\n// testing.\ntype EvdevIterator interface {\n\t// Next progresses the iterator. It returns false when there are no more\n\t// elements to iterate or when the iterator encountered an error.\n\tNext() bool\n\t// Current returns the active element of the iterator. This should only be\n\t// called if Next() returned a true.\n\tCurrent() EvdevEvent\n\t// Close must be called before discarding the iterator. If the iterator\n\t// exited cleanly then the error is nil. The error is non-nil if either the\n\t// iterator encountered an internal error and stopped early or if it failed\n\t// to close.\n\tClose() error\n}\n\nconst (\n\t// StateChangeMove represents a move of the x and y for the mouse.\n\tChangeTypeMove = \"MOVE\"\n\t// StateChangeDrag represents a move of the x and y for the mouse when clicked.\n\tChangeTypeDrag = \"DRAG\"\n\t// ChangeTypeClick indicates that the stylus is touching the tablet.\n\tChangeTypeClick = \"CLICK\"\n\t// ChangeTypeUnclick indicates the stylus is no longer touching the tablet.\n\tChangeTypeUnclick = \"UNCLICK\"\n)\n\n// StateChangeMove contains mouse movement data.\ntype StateChangeMove struct {\n\tX int\n\tY int\n}\n\n// Type returns the specific change type.\nfunc (*StateChangeMove) Type() string {\n\treturn ChangeTypeMove\n}\n\n// StateChangeDrag contains mouse movement data when clicked.\ntype StateChangeDrag struct {\n\tX int\n\tY int\n}\n\n// Type returns the specific change type.\nfunc (*StateChangeDrag) Type() string {\n\treturn ChangeTypeDrag\n}\n\n// StateChangeClick contains mouse click data.\ntype StateChangeClick struct{}\n\n// Type returns the specific change type.\nfunc (*StateChangeClick) Type() string {\n\treturn ChangeTypeClick\n}\n\n// StateChangeUnclick contains mouse click data.\ntype StateChangeUnclick struct{}\n\n// Type returns the specific change type.\nfunc (*StateChangeUnclick) Type() string {\n\treturn ChangeTypeUnclick\n}\n\n// StateChange is a type for switching on the kind of change in order to convert\n// the generic change type into a specific change type.\ntype StateChange interface {\n\tType() string\n}\n\n// StateMachine is a specialized version of the EvdevIterator that only emits\n// events on significant changes of the machine.\ntype StateMachine interface {\n\t// Next progresses the iterator. It returns false when there are no more\n\t// elements to iterate or when the iterator encountered an error.\n\tNext() bool\n\t// Current returns the active element of the iterator. This should only be\n\t// called if Next() returned a true.\n\tCurrent() StateChange\n\t// Close must be called before discarding the iterator. If the iterator\n\t// exited cleanly then the error is nil. The error is non-nil if either the\n\t// iterator encountered an internal error and stopped early or if it failed\n\t// to close.\n\tClose() error\n}\n\n// PositionScaler implements scaling rules for converting x/y coordinates\n// between differently sized screens.\ntype PositionScaler interface {\n\tScalePosition(x int, y int) (int, int)\n}\n\n// Driver is used to control a host system.\ntype Driver interface {\n\tMoveMouse(x int, y int) error\n\tDragMouse(x int, y int) error\n\tClick() error\n\tUnclick() error\n\tGetSize() (width int, height int, err error)\n}\n"
  },
  {
    "path": "pkg/driver.go",
    "content": "// This file is part of remouseable.\n//\n// remouseable is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License version 3 as published\n// by the Free Software Foundation.\n//\n// remouseable is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with remouseable.  If not, see <https://www.gnu.org/licenses/>.\n\npackage remouseable\n\nimport \"github.com/kevinconway/remouseable/pkg/internal/robotgo\"\n\n// RobotgoDriver implements Driver using the robotgo cgo library.\ntype RobotgoDriver struct{}\n\n// GetSize returns the width and height of the host screen.\nfunc (*RobotgoDriver) GetSize() (int, int, error) {\n\twidth, height := robotgo.GetScreenSize()\n\treturn width, height, nil\n}\n\n// Click and hold the mouse button down.\nfunc (*RobotgoDriver) Click() error {\n\trobotgo.MouseToggle(\"down\", \"left\")\n\treturn nil\n}\n\n// Unclick and release the mouse button.\nfunc (*RobotgoDriver) Unclick() error {\n\trobotgo.MouseToggle(\"up\", \"left\")\n\treturn nil\n}\n\n// MoveMouse sets the mouse to a specified location.\nfunc (*RobotgoDriver) MoveMouse(x int, y int) error {\n\t// Reversing the x/y due to robotgo seemingly having an opposite\n\t// x/y concept as the typical event source of evdev, etc.\n\trobotgo.MoveMouse(x, y)\n\treturn nil\n}\n\n// DragMouse sets the mouse to a specified location while dragging a screen element.\nfunc (*RobotgoDriver) DragMouse(x int, y int) error {\n\t// Reversing the x/y due to robotgo seemingly having an opposite\n\t// x/y concept as the typical event source of evdev, etc.\n\trobotgo.DragMouse(x, y)\n\treturn nil\n}\n"
  },
  {
    "path": "pkg/evdevcodes.go",
    "content": "package remouseable\n\n// Code generated DO NOT EDIT\n\n// Generated using Linux 5.0.0-31-generic x86_64.\n// Generated at 2019-10-17T00:10:35-05:00.\n// Generated from /usr/include/linux/input.h, /usr/include/linux/input-event-codes.h.\nconst (\n\tEV_VERSION                   = 0x010001\n\tID_BUS                       = 0\n\tID_VENDOR                    = 1\n\tID_PRODUCT                   = 2\n\tID_VERSION                   = 3\n\tBUS_PCI                      = 0x01\n\tBUS_ISAPNP                   = 0x02\n\tBUS_USB                      = 0x03\n\tBUS_HIL                      = 0x04\n\tBUS_BLUETOOTH                = 0x05\n\tBUS_VIRTUAL                  = 0x06\n\tBUS_ISA                      = 0x10\n\tBUS_I8042                    = 0x11\n\tBUS_XTKBD                    = 0x12\n\tBUS_RS232                    = 0x13\n\tBUS_GAMEPORT                 = 0x14\n\tBUS_PARPORT                  = 0x15\n\tBUS_AMIGA                    = 0x16\n\tBUS_ADB                      = 0x17\n\tBUS_I2C                      = 0x18\n\tBUS_HOST                     = 0x19\n\tBUS_GSC                      = 0x1A\n\tBUS_ATARI                    = 0x1B\n\tBUS_SPI                      = 0x1C\n\tBUS_RMI                      = 0x1D\n\tBUS_CEC                      = 0x1E\n\tBUS_INTEL_ISHTP              = 0x1F\n\tFF_STATUS_STOPPED            = 0x00\n\tFF_STATUS_PLAYING            = 0x01\n\tFF_STATUS_MAX                = 0x01\n\tFF_RUMBLE                    = 0x50\n\tFF_PERIODIC                  = 0x51\n\tFF_CONSTANT                  = 0x52\n\tFF_SPRING                    = 0x53\n\tFF_FRICTION                  = 0x54\n\tFF_DAMPER                    = 0x55\n\tFF_INERTIA                   = 0x56\n\tFF_RAMP                      = 0x57\n\tFF_EFFECT_MIN                = FF_RUMBLE\n\tFF_EFFECT_MAX                = FF_RAMP\n\tFF_SQUARE                    = 0x58\n\tFF_TRIANGLE                  = 0x59\n\tFF_SINE                      = 0x5a\n\tFF_SAW_UP                    = 0x5b\n\tFF_SAW_DOWN                  = 0x5c\n\tFF_CUSTOM                    = 0x5d\n\tFF_WAVEFORM_MIN              = FF_SQUARE\n\tFF_WAVEFORM_MAX              = FF_CUSTOM\n\tFF_GAIN                      = 0x60\n\tFF_AUTOCENTER                = 0x61\n\tFF_MAX_EFFECTS               = FF_GAIN\n\tFF_MAX                       = 0x7f\n\tEV_SYN                       = 0x00\n\tEV_KEY                       = 0x01\n\tEV_REL                       = 0x02\n\tEV_ABS                       = 0x03\n\tEV_MSC                       = 0x04\n\tEV_SW                        = 0x05\n\tEV_LED                       = 0x11\n\tEV_SND                       = 0x12\n\tEV_REP                       = 0x14\n\tEV_FF                        = 0x15\n\tEV_PWR                       = 0x16\n\tEV_FF_STATUS                 = 0x17\n\tEV_MAX                       = 0x1f\n\tSYN_REPORT                   = 0\n\tSYN_CONFIG                   = 1\n\tSYN_MT_REPORT                = 2\n\tSYN_DROPPED                  = 3\n\tSYN_MAX                      = 0xf\n\tKEY_RESERVED                 = 0\n\tKEY_ESC                      = 1\n\tKEY_1                        = 2\n\tKEY_2                        = 3\n\tKEY_3                        = 4\n\tKEY_4                        = 5\n\tKEY_5                        = 6\n\tKEY_6                        = 7\n\tKEY_7                        = 8\n\tKEY_8                        = 9\n\tKEY_9                        = 10\n\tKEY_0                        = 11\n\tKEY_MINUS                    = 12\n\tKEY_EQUAL                    = 13\n\tKEY_BACKSPACE                = 14\n\tKEY_TAB                      = 15\n\tKEY_Q                        = 16\n\tKEY_W                        = 17\n\tKEY_E                        = 18\n\tKEY_R                        = 19\n\tKEY_T                        = 20\n\tKEY_Y                        = 21\n\tKEY_U                        = 22\n\tKEY_I                        = 23\n\tKEY_O                        = 24\n\tKEY_P                        = 25\n\tKEY_LEFTBRACE                = 26\n\tKEY_RIGHTBRACE               = 27\n\tKEY_ENTER                    = 28\n\tKEY_LEFTCTRL                 = 29\n\tKEY_A                        = 30\n\tKEY_S                        = 31\n\tKEY_D                        = 32\n\tKEY_F                        = 33\n\tKEY_G                        = 34\n\tKEY_H                        = 35\n\tKEY_J                        = 36\n\tKEY_K                        = 37\n\tKEY_L                        = 38\n\tKEY_SEMICOLON                = 39\n\tKEY_APOSTROPHE               = 40\n\tKEY_GRAVE                    = 41\n\tKEY_LEFTSHIFT                = 42\n\tKEY_BACKSLASH                = 43\n\tKEY_Z                        = 44\n\tKEY_X                        = 45\n\tKEY_C                        = 46\n\tKEY_V                        = 47\n\tKEY_B                        = 48\n\tKEY_N                        = 49\n\tKEY_M                        = 50\n\tKEY_COMMA                    = 51\n\tKEY_DOT                      = 52\n\tKEY_SLASH                    = 53\n\tKEY_RIGHTSHIFT               = 54\n\tKEY_KPASTERISK               = 55\n\tKEY_LEFTALT                  = 56\n\tKEY_SPACE                    = 57\n\tKEY_CAPSLOCK                 = 58\n\tKEY_F1                       = 59\n\tKEY_F2                       = 60\n\tKEY_F3                       = 61\n\tKEY_F4                       = 62\n\tKEY_F5                       = 63\n\tKEY_F6                       = 64\n\tKEY_F7                       = 65\n\tKEY_F8                       = 66\n\tKEY_F9                       = 67\n\tKEY_F10                      = 68\n\tKEY_NUMLOCK                  = 69\n\tKEY_SCROLLLOCK               = 70\n\tKEY_KP7                      = 71\n\tKEY_KP8                      = 72\n\tKEY_KP9                      = 73\n\tKEY_KPMINUS                  = 74\n\tKEY_KP4                      = 75\n\tKEY_KP5                      = 76\n\tKEY_KP6                      = 77\n\tKEY_KPPLUS                   = 78\n\tKEY_KP1                      = 79\n\tKEY_KP2                      = 80\n\tKEY_KP3                      = 81\n\tKEY_KP0                      = 82\n\tKEY_KPDOT                    = 83\n\tKEY_ZENKAKUHANKAKU           = 85\n\tKEY_102ND                    = 86\n\tKEY_F11                      = 87\n\tKEY_F12                      = 88\n\tKEY_RO                       = 89\n\tKEY_KATAKANA                 = 90\n\tKEY_HIRAGANA                 = 91\n\tKEY_HENKAN                   = 92\n\tKEY_KATAKANAHIRAGANA         = 93\n\tKEY_MUHENKAN                 = 94\n\tKEY_KPJPCOMMA                = 95\n\tKEY_KPENTER                  = 96\n\tKEY_RIGHTCTRL                = 97\n\tKEY_KPSLASH                  = 98\n\tKEY_SYSRQ                    = 99\n\tKEY_RIGHTALT                 = 100\n\tKEY_LINEFEED                 = 101\n\tKEY_HOME                     = 102\n\tKEY_UP                       = 103\n\tKEY_PAGEUP                   = 104\n\tKEY_LEFT                     = 105\n\tKEY_RIGHT                    = 106\n\tKEY_END                      = 107\n\tKEY_DOWN                     = 108\n\tKEY_PAGEDOWN                 = 109\n\tKEY_INSERT                   = 110\n\tKEY_DELETE                   = 111\n\tKEY_MACRO                    = 112\n\tKEY_MUTE                     = 113\n\tKEY_VOLUMEDOWN               = 114\n\tKEY_VOLUMEUP                 = 115\n\tKEY_POWER                    = 116\n\tKEY_KPEQUAL                  = 117\n\tKEY_KPPLUSMINUS              = 118\n\tKEY_PAUSE                    = 119\n\tKEY_SCALE                    = 120\n\tKEY_KPCOMMA                  = 121\n\tKEY_HANGEUL                  = 122\n\tKEY_HANGUEL                  = KEY_HANGEUL\n\tKEY_HANJA                    = 123\n\tKEY_YEN                      = 124\n\tKEY_LEFTMETA                 = 125\n\tKEY_RIGHTMETA                = 126\n\tKEY_COMPOSE                  = 127\n\tKEY_STOP                     = 128\n\tKEY_AGAIN                    = 129\n\tKEY_PROPS                    = 130\n\tKEY_UNDO                     = 131\n\tKEY_FRONT                    = 132\n\tKEY_COPY                     = 133\n\tKEY_OPEN                     = 134\n\tKEY_PASTE                    = 135\n\tKEY_FIND                     = 136\n\tKEY_CUT                      = 137\n\tKEY_HELP                     = 138\n\tKEY_MENU                     = 139\n\tKEY_CALC                     = 140\n\tKEY_SETUP                    = 141\n\tKEY_SLEEP                    = 142\n\tKEY_WAKEUP                   = 143\n\tKEY_FILE                     = 144\n\tKEY_SENDFILE                 = 145\n\tKEY_DELETEFILE               = 146\n\tKEY_XFER                     = 147\n\tKEY_PROG1                    = 148\n\tKEY_PROG2                    = 149\n\tKEY_WWW                      = 150\n\tKEY_MSDOS                    = 151\n\tKEY_COFFEE                   = 152\n\tKEY_SCREENLOCK               = KEY_COFFEE\n\tKEY_ROTATE_DISPLAY           = 153\n\tKEY_DIRECTION                = KEY_ROTATE_DISPLAY\n\tKEY_CYCLEWINDOWS             = 154\n\tKEY_MAIL                     = 155\n\tKEY_BOOKMARKS                = 156\n\tKEY_COMPUTER                 = 157\n\tKEY_BACK                     = 158\n\tKEY_FORWARD                  = 159\n\tKEY_CLOSECD                  = 160\n\tKEY_EJECTCD                  = 161\n\tKEY_EJECTCLOSECD             = 162\n\tKEY_NEXTSONG                 = 163\n\tKEY_PLAYPAUSE                = 164\n\tKEY_PREVIOUSSONG             = 165\n\tKEY_STOPCD                   = 166\n\tKEY_RECORD                   = 167\n\tKEY_REWIND                   = 168\n\tKEY_PHONE                    = 169\n\tKEY_ISO                      = 170\n\tKEY_CONFIG                   = 171\n\tKEY_HOMEPAGE                 = 172\n\tKEY_REFRESH                  = 173\n\tKEY_EXIT                     = 174\n\tKEY_MOVE                     = 175\n\tKEY_EDIT                     = 176\n\tKEY_SCROLLUP                 = 177\n\tKEY_SCROLLDOWN               = 178\n\tKEY_KPLEFTPAREN              = 179\n\tKEY_KPRIGHTPAREN             = 180\n\tKEY_NEW                      = 181\n\tKEY_REDO                     = 182\n\tKEY_F13                      = 183\n\tKEY_F14                      = 184\n\tKEY_F15                      = 185\n\tKEY_F16                      = 186\n\tKEY_F17                      = 187\n\tKEY_F18                      = 188\n\tKEY_F19                      = 189\n\tKEY_F20                      = 190\n\tKEY_F21                      = 191\n\tKEY_F22                      = 192\n\tKEY_F23                      = 193\n\tKEY_F24                      = 194\n\tKEY_PLAYCD                   = 200\n\tKEY_PAUSECD                  = 201\n\tKEY_PROG3                    = 202\n\tKEY_PROG4                    = 203\n\tKEY_DASHBOARD                = 204\n\tKEY_SUSPEND                  = 205\n\tKEY_CLOSE                    = 206\n\tKEY_PLAY                     = 207\n\tKEY_FASTFORWARD              = 208\n\tKEY_BASSBOOST                = 209\n\tKEY_PRINT                    = 210\n\tKEY_HP                       = 211\n\tKEY_CAMERA                   = 212\n\tKEY_SOUND                    = 213\n\tKEY_QUESTION                 = 214\n\tKEY_EMAIL                    = 215\n\tKEY_CHAT                     = 216\n\tKEY_SEARCH                   = 217\n\tKEY_CONNECT                  = 218\n\tKEY_FINANCE                  = 219\n\tKEY_SPORT                    = 220\n\tKEY_SHOP                     = 221\n\tKEY_ALTERASE                 = 222\n\tKEY_CANCEL                   = 223\n\tKEY_BRIGHTNESSDOWN           = 224\n\tKEY_BRIGHTNESSUP             = 225\n\tKEY_MEDIA                    = 226\n\tKEY_SWITCHVIDEOMODE          = 227\n\tKEY_KBDILLUMTOGGLE           = 228\n\tKEY_KBDILLUMDOWN             = 229\n\tKEY_KBDILLUMUP               = 230\n\tKEY_SEND                     = 231\n\tKEY_REPLY                    = 232\n\tKEY_FORWARDMAIL              = 233\n\tKEY_SAVE                     = 234\n\tKEY_DOCUMENTS                = 235\n\tKEY_BATTERY                  = 236\n\tKEY_BLUETOOTH                = 237\n\tKEY_WLAN                     = 238\n\tKEY_UWB                      = 239\n\tKEY_UNKNOWN                  = 240\n\tKEY_VIDEO_NEXT               = 241\n\tKEY_VIDEO_PREV               = 242\n\tKEY_BRIGHTNESS_CYCLE         = 243\n\tKEY_BRIGHTNESS_AUTO          = 244\n\tKEY_BRIGHTNESS_ZERO          = KEY_BRIGHTNESS_AUTO\n\tKEY_DISPLAY_OFF              = 245\n\tKEY_WWAN                     = 246\n\tKEY_WIMAX                    = KEY_WWAN\n\tKEY_RFKILL                   = 247\n\tKEY_MICMUTE                  = 248\n\tBTN_MISC                     = 0x100\n\tBTN_0                        = 0x100\n\tBTN_1                        = 0x101\n\tBTN_2                        = 0x102\n\tBTN_3                        = 0x103\n\tBTN_4                        = 0x104\n\tBTN_5                        = 0x105\n\tBTN_6                        = 0x106\n\tBTN_7                        = 0x107\n\tBTN_8                        = 0x108\n\tBTN_9                        = 0x109\n\tBTN_MOUSE                    = 0x110\n\tBTN_LEFT                     = 0x110\n\tBTN_RIGHT                    = 0x111\n\tBTN_MIDDLE                   = 0x112\n\tBTN_SIDE                     = 0x113\n\tBTN_EXTRA                    = 0x114\n\tBTN_FORWARD                  = 0x115\n\tBTN_BACK                     = 0x116\n\tBTN_TASK                     = 0x117\n\tBTN_JOYSTICK                 = 0x120\n\tBTN_TRIGGER                  = 0x120\n\tBTN_THUMB                    = 0x121\n\tBTN_THUMB2                   = 0x122\n\tBTN_TOP                      = 0x123\n\tBTN_TOP2                     = 0x124\n\tBTN_PINKIE                   = 0x125\n\tBTN_BASE                     = 0x126\n\tBTN_BASE2                    = 0x127\n\tBTN_BASE3                    = 0x128\n\tBTN_BASE4                    = 0x129\n\tBTN_BASE5                    = 0x12a\n\tBTN_BASE6                    = 0x12b\n\tBTN_DEAD                     = 0x12f\n\tBTN_GAMEPAD                  = 0x130\n\tBTN_SOUTH                    = 0x130\n\tBTN_A                        = BTN_SOUTH\n\tBTN_EAST                     = 0x131\n\tBTN_B                        = BTN_EAST\n\tBTN_C                        = 0x132\n\tBTN_NORTH                    = 0x133\n\tBTN_X                        = BTN_NORTH\n\tBTN_WEST                     = 0x134\n\tBTN_Y                        = BTN_WEST\n\tBTN_Z                        = 0x135\n\tBTN_TL                       = 0x136\n\tBTN_TR                       = 0x137\n\tBTN_TL2                      = 0x138\n\tBTN_TR2                      = 0x139\n\tBTN_SELECT                   = 0x13a\n\tBTN_START                    = 0x13b\n\tBTN_MODE                     = 0x13c\n\tBTN_THUMBL                   = 0x13d\n\tBTN_THUMBR                   = 0x13e\n\tBTN_DIGI                     = 0x140\n\tBTN_TOOL_PEN                 = 0x140\n\tBTN_TOOL_RUBBER              = 0x141\n\tBTN_TOOL_BRUSH               = 0x142\n\tBTN_TOOL_PENCIL              = 0x143\n\tBTN_TOOL_AIRBRUSH            = 0x144\n\tBTN_TOOL_FINGER              = 0x145\n\tBTN_TOOL_MOUSE               = 0x146\n\tBTN_TOOL_LENS                = 0x147\n\tBTN_TOOL_QUINTTAP            = 0x148\n\tBTN_STYLUS3                  = 0x149\n\tBTN_TOUCH                    = 0x14a\n\tBTN_STYLUS                   = 0x14b\n\tBTN_STYLUS2                  = 0x14c\n\tBTN_TOOL_DOUBLETAP           = 0x14d\n\tBTN_TOOL_TRIPLETAP           = 0x14e\n\tBTN_TOOL_QUADTAP             = 0x14f\n\tBTN_WHEEL                    = 0x150\n\tBTN_GEAR_DOWN                = 0x150\n\tBTN_GEAR_UP                  = 0x151\n\tKEY_OK                       = 0x160\n\tKEY_SELECT                   = 0x161\n\tKEY_GOTO                     = 0x162\n\tKEY_CLEAR                    = 0x163\n\tKEY_POWER2                   = 0x164\n\tKEY_OPTION                   = 0x165\n\tKEY_INFO                     = 0x166\n\tKEY_TIME                     = 0x167\n\tKEY_VENDOR                   = 0x168\n\tKEY_ARCHIVE                  = 0x169\n\tKEY_PROGRAM                  = 0x16a\n\tKEY_CHANNEL                  = 0x16b\n\tKEY_FAVORITES                = 0x16c\n\tKEY_EPG                      = 0x16d\n\tKEY_PVR                      = 0x16e\n\tKEY_MHP                      = 0x16f\n\tKEY_LANGUAGE                 = 0x170\n\tKEY_TITLE                    = 0x171\n\tKEY_SUBTITLE                 = 0x172\n\tKEY_ANGLE                    = 0x173\n\tKEY_ZOOM                     = 0x174\n\tKEY_MODE                     = 0x175\n\tKEY_KEYBOARD                 = 0x176\n\tKEY_SCREEN                   = 0x177\n\tKEY_PC                       = 0x178\n\tKEY_TV                       = 0x179\n\tKEY_TV2                      = 0x17a\n\tKEY_VCR                      = 0x17b\n\tKEY_VCR2                     = 0x17c\n\tKEY_SAT                      = 0x17d\n\tKEY_SAT2                     = 0x17e\n\tKEY_CD                       = 0x17f\n\tKEY_TAPE                     = 0x180\n\tKEY_RADIO                    = 0x181\n\tKEY_TUNER                    = 0x182\n\tKEY_PLAYER                   = 0x183\n\tKEY_TEXT                     = 0x184\n\tKEY_DVD                      = 0x185\n\tKEY_AUX                      = 0x186\n\tKEY_MP3                      = 0x187\n\tKEY_AUDIO                    = 0x188\n\tKEY_VIDEO                    = 0x189\n\tKEY_DIRECTORY                = 0x18a\n\tKEY_LIST                     = 0x18b\n\tKEY_MEMO                     = 0x18c\n\tKEY_CALENDAR                 = 0x18d\n\tKEY_RED                      = 0x18e\n\tKEY_GREEN                    = 0x18f\n\tKEY_YELLOW                   = 0x190\n\tKEY_BLUE                     = 0x191\n\tKEY_CHANNELUP                = 0x192\n\tKEY_CHANNELDOWN              = 0x193\n\tKEY_FIRST                    = 0x194\n\tKEY_LAST                     = 0x195\n\tKEY_AB                       = 0x196\n\tKEY_NEXT                     = 0x197\n\tKEY_RESTART                  = 0x198\n\tKEY_SLOW                     = 0x199\n\tKEY_SHUFFLE                  = 0x19a\n\tKEY_BREAK                    = 0x19b\n\tKEY_PREVIOUS                 = 0x19c\n\tKEY_DIGITS                   = 0x19d\n\tKEY_TEEN                     = 0x19e\n\tKEY_TWEN                     = 0x19f\n\tKEY_VIDEOPHONE               = 0x1a0\n\tKEY_GAMES                    = 0x1a1\n\tKEY_ZOOMIN                   = 0x1a2\n\tKEY_ZOOMOUT                  = 0x1a3\n\tKEY_ZOOMRESET                = 0x1a4\n\tKEY_WORDPROCESSOR            = 0x1a5\n\tKEY_EDITOR                   = 0x1a6\n\tKEY_SPREADSHEET              = 0x1a7\n\tKEY_GRAPHICSEDITOR           = 0x1a8\n\tKEY_PRESENTATION             = 0x1a9\n\tKEY_DATABASE                 = 0x1aa\n\tKEY_NEWS                     = 0x1ab\n\tKEY_VOICEMAIL                = 0x1ac\n\tKEY_ADDRESSBOOK              = 0x1ad\n\tKEY_MESSENGER                = 0x1ae\n\tKEY_DISPLAYTOGGLE            = 0x1af\n\tKEY_BRIGHTNESS_TOGGLE        = KEY_DISPLAYTOGGLE\n\tKEY_SPELLCHECK               = 0x1b0\n\tKEY_LOGOFF                   = 0x1b1\n\tKEY_DOLLAR                   = 0x1b2\n\tKEY_EURO                     = 0x1b3\n\tKEY_FRAMEBACK                = 0x1b4\n\tKEY_FRAMEFORWARD             = 0x1b5\n\tKEY_CONTEXT_MENU             = 0x1b6\n\tKEY_MEDIA_REPEAT             = 0x1b7\n\tKEY_10CHANNELSUP             = 0x1b8\n\tKEY_10CHANNELSDOWN           = 0x1b9\n\tKEY_IMAGES                   = 0x1ba\n\tKEY_DEL_EOL                  = 0x1c0\n\tKEY_DEL_EOS                  = 0x1c1\n\tKEY_INS_LINE                 = 0x1c2\n\tKEY_DEL_LINE                 = 0x1c3\n\tKEY_FN                       = 0x1d0\n\tKEY_FN_ESC                   = 0x1d1\n\tKEY_FN_F1                    = 0x1d2\n\tKEY_FN_F2                    = 0x1d3\n\tKEY_FN_F3                    = 0x1d4\n\tKEY_FN_F4                    = 0x1d5\n\tKEY_FN_F5                    = 0x1d6\n\tKEY_FN_F6                    = 0x1d7\n\tKEY_FN_F7                    = 0x1d8\n\tKEY_FN_F8                    = 0x1d9\n\tKEY_FN_F9                    = 0x1da\n\tKEY_FN_F10                   = 0x1db\n\tKEY_FN_F11                   = 0x1dc\n\tKEY_FN_F12                   = 0x1dd\n\tKEY_FN_1                     = 0x1de\n\tKEY_FN_2                     = 0x1df\n\tKEY_FN_D                     = 0x1e0\n\tKEY_FN_E                     = 0x1e1\n\tKEY_FN_F                     = 0x1e2\n\tKEY_FN_S                     = 0x1e3\n\tKEY_FN_B                     = 0x1e4\n\tKEY_BRL_DOT1                 = 0x1f1\n\tKEY_BRL_DOT2                 = 0x1f2\n\tKEY_BRL_DOT3                 = 0x1f3\n\tKEY_BRL_DOT4                 = 0x1f4\n\tKEY_BRL_DOT5                 = 0x1f5\n\tKEY_BRL_DOT6                 = 0x1f6\n\tKEY_BRL_DOT7                 = 0x1f7\n\tKEY_BRL_DOT8                 = 0x1f8\n\tKEY_BRL_DOT9                 = 0x1f9\n\tKEY_BRL_DOT10                = 0x1fa\n\tKEY_NUMERIC_0                = 0x200\n\tKEY_NUMERIC_1                = 0x201\n\tKEY_NUMERIC_2                = 0x202\n\tKEY_NUMERIC_3                = 0x203\n\tKEY_NUMERIC_4                = 0x204\n\tKEY_NUMERIC_5                = 0x205\n\tKEY_NUMERIC_6                = 0x206\n\tKEY_NUMERIC_7                = 0x207\n\tKEY_NUMERIC_8                = 0x208\n\tKEY_NUMERIC_9                = 0x209\n\tKEY_NUMERIC_STAR             = 0x20a\n\tKEY_NUMERIC_POUND            = 0x20b\n\tKEY_NUMERIC_A                = 0x20c\n\tKEY_NUMERIC_B                = 0x20d\n\tKEY_NUMERIC_C                = 0x20e\n\tKEY_NUMERIC_D                = 0x20f\n\tKEY_CAMERA_FOCUS             = 0x210\n\tKEY_WPS_BUTTON               = 0x211\n\tKEY_TOUCHPAD_TOGGLE          = 0x212\n\tKEY_TOUCHPAD_ON              = 0x213\n\tKEY_TOUCHPAD_OFF             = 0x214\n\tKEY_CAMERA_ZOOMIN            = 0x215\n\tKEY_CAMERA_ZOOMOUT           = 0x216\n\tKEY_CAMERA_UP                = 0x217\n\tKEY_CAMERA_DOWN              = 0x218\n\tKEY_CAMERA_LEFT              = 0x219\n\tKEY_CAMERA_RIGHT             = 0x21a\n\tKEY_ATTENDANT_ON             = 0x21b\n\tKEY_ATTENDANT_OFF            = 0x21c\n\tKEY_ATTENDANT_TOGGLE         = 0x21d\n\tKEY_LIGHTS_TOGGLE            = 0x21e\n\tBTN_DPAD_UP                  = 0x220\n\tBTN_DPAD_DOWN                = 0x221\n\tBTN_DPAD_LEFT                = 0x222\n\tBTN_DPAD_RIGHT               = 0x223\n\tKEY_ALS_TOGGLE               = 0x230\n\tKEY_BUTTONCONFIG             = 0x240\n\tKEY_TASKMANAGER              = 0x241\n\tKEY_JOURNAL                  = 0x242\n\tKEY_CONTROLPANEL             = 0x243\n\tKEY_APPSELECT                = 0x244\n\tKEY_SCREENSAVER              = 0x245\n\tKEY_VOICECOMMAND             = 0x246\n\tKEY_ASSISTANT                = 0x247\n\tKEY_BRIGHTNESS_MIN           = 0x250\n\tKEY_BRIGHTNESS_MAX           = 0x251\n\tKEY_KBDINPUTASSIST_PREV      = 0x260\n\tKEY_KBDINPUTASSIST_NEXT      = 0x261\n\tKEY_KBDINPUTASSIST_PREVGROUP = 0x262\n\tKEY_KBDINPUTASSIST_NEXTGROUP = 0x263\n\tKEY_KBDINPUTASSIST_ACCEPT    = 0x264\n\tKEY_KBDINPUTASSIST_CANCEL    = 0x265\n\tKEY_RIGHT_UP                 = 0x266\n\tKEY_RIGHT_DOWN               = 0x267\n\tKEY_LEFT_UP                  = 0x268\n\tKEY_LEFT_DOWN                = 0x269\n\tKEY_ROOT_MENU                = 0x26a\n\tKEY_MEDIA_TOP_MENU           = 0x26b\n\tKEY_NUMERIC_11               = 0x26c\n\tKEY_NUMERIC_12               = 0x26d\n\tKEY_AUDIO_DESC               = 0x26e\n\tKEY_3D_MODE                  = 0x26f\n\tKEY_NEXT_FAVORITE            = 0x270\n\tKEY_STOP_RECORD              = 0x271\n\tKEY_PAUSE_RECORD             = 0x272\n\tKEY_VOD                      = 0x273\n\tKEY_UNMUTE                   = 0x274\n\tKEY_FASTREVERSE              = 0x275\n\tKEY_SLOWREVERSE              = 0x276\n\tKEY_DATA                     = 0x277\n\tKEY_ONSCREEN_KEYBOARD        = 0x278\n\tBTN_TRIGGER_HAPPY            = 0x2c0\n\tBTN_TRIGGER_HAPPY1           = 0x2c0\n\tBTN_TRIGGER_HAPPY2           = 0x2c1\n\tBTN_TRIGGER_HAPPY3           = 0x2c2\n\tBTN_TRIGGER_HAPPY4           = 0x2c3\n\tBTN_TRIGGER_HAPPY5           = 0x2c4\n\tBTN_TRIGGER_HAPPY6           = 0x2c5\n\tBTN_TRIGGER_HAPPY7           = 0x2c6\n\tBTN_TRIGGER_HAPPY8           = 0x2c7\n\tBTN_TRIGGER_HAPPY9           = 0x2c8\n\tBTN_TRIGGER_HAPPY10          = 0x2c9\n\tBTN_TRIGGER_HAPPY11          = 0x2ca\n\tBTN_TRIGGER_HAPPY12          = 0x2cb\n\tBTN_TRIGGER_HAPPY13          = 0x2cc\n\tBTN_TRIGGER_HAPPY14          = 0x2cd\n\tBTN_TRIGGER_HAPPY15          = 0x2ce\n\tBTN_TRIGGER_HAPPY16          = 0x2cf\n\tBTN_TRIGGER_HAPPY17          = 0x2d0\n\tBTN_TRIGGER_HAPPY18          = 0x2d1\n\tBTN_TRIGGER_HAPPY19          = 0x2d2\n\tBTN_TRIGGER_HAPPY20          = 0x2d3\n\tBTN_TRIGGER_HAPPY21          = 0x2d4\n\tBTN_TRIGGER_HAPPY22          = 0x2d5\n\tBTN_TRIGGER_HAPPY23          = 0x2d6\n\tBTN_TRIGGER_HAPPY24          = 0x2d7\n\tBTN_TRIGGER_HAPPY25          = 0x2d8\n\tBTN_TRIGGER_HAPPY26          = 0x2d9\n\tBTN_TRIGGER_HAPPY27          = 0x2da\n\tBTN_TRIGGER_HAPPY28          = 0x2db\n\tBTN_TRIGGER_HAPPY29          = 0x2dc\n\tBTN_TRIGGER_HAPPY30          = 0x2dd\n\tBTN_TRIGGER_HAPPY31          = 0x2de\n\tBTN_TRIGGER_HAPPY32          = 0x2df\n\tBTN_TRIGGER_HAPPY33          = 0x2e0\n\tBTN_TRIGGER_HAPPY34          = 0x2e1\n\tBTN_TRIGGER_HAPPY35          = 0x2e2\n\tBTN_TRIGGER_HAPPY36          = 0x2e3\n\tBTN_TRIGGER_HAPPY37          = 0x2e4\n\tBTN_TRIGGER_HAPPY38          = 0x2e5\n\tBTN_TRIGGER_HAPPY39          = 0x2e6\n\tBTN_TRIGGER_HAPPY40          = 0x2e7\n\tKEY_MIN_INTERESTING          = KEY_MUTE\n\tKEY_MAX                      = 0x2ff\n\tREL_X                        = 0x00\n\tREL_Y                        = 0x01\n\tREL_Z                        = 0x02\n\tREL_RX                       = 0x03\n\tREL_RY                       = 0x04\n\tREL_RZ                       = 0x05\n\tREL_HWHEEL                   = 0x06\n\tREL_DIAL                     = 0x07\n\tREL_WHEEL                    = 0x08\n\tREL_MISC                     = 0x09\n\tREL_MAX                      = 0x0f\n\tABS_X                        = 0x00\n\tABS_Y                        = 0x01\n\tABS_Z                        = 0x02\n\tABS_RX                       = 0x03\n\tABS_RY                       = 0x04\n\tABS_RZ                       = 0x05\n\tABS_THROTTLE                 = 0x06\n\tABS_RUDDER                   = 0x07\n\tABS_WHEEL                    = 0x08\n\tABS_GAS                      = 0x09\n\tABS_BRAKE                    = 0x0a\n\tABS_HAT0X                    = 0x10\n\tABS_HAT0Y                    = 0x11\n\tABS_HAT1X                    = 0x12\n\tABS_HAT1Y                    = 0x13\n\tABS_HAT2X                    = 0x14\n\tABS_HAT2Y                    = 0x15\n\tABS_HAT3X                    = 0x16\n\tABS_HAT3Y                    = 0x17\n\tABS_PRESSURE                 = 0x18\n\tABS_DISTANCE                 = 0x19\n\tABS_TILT_X                   = 0x1a\n\tABS_TILT_Y                   = 0x1b\n\tABS_TOOL_WIDTH               = 0x1c\n\tABS_VOLUME                   = 0x20\n\tABS_MISC                     = 0x28\n\tABS_RESERVED                 = 0x2e\n\tABS_MT_SLOT                  = 0x2f\n\tABS_MT_TOUCH_MAJOR           = 0x30\n\tABS_MT_TOUCH_MINOR           = 0x31\n\tABS_MT_WIDTH_MAJOR           = 0x32\n\tABS_MT_WIDTH_MINOR           = 0x33\n\tABS_MT_ORIENTATION           = 0x34\n\tABS_MT_POSITION_X            = 0x35\n\tABS_MT_POSITION_Y            = 0x36\n\tABS_MT_TOOL_TYPE             = 0x37\n\tABS_MT_BLOB_ID               = 0x38\n\tABS_MT_TRACKING_ID           = 0x39\n\tABS_MT_PRESSURE              = 0x3a\n\tABS_MT_DISTANCE              = 0x3b\n\tABS_MT_TOOL_X                = 0x3c\n\tABS_MT_TOOL_Y                = 0x3d\n\tABS_MAX                      = 0x3f\n\tSW_LID                       = 0x00\n\tSW_TABLET_MODE               = 0x01\n\tSW_HEADPHONE_INSERT          = 0x02\n\tSW_RFKILL_ALL                = 0x03\n\tSW_RADIO                     = SW_RFKILL_ALL\n\tSW_MICROPHONE_INSERT         = 0x04\n\tSW_DOCK                      = 0x05\n\tSW_LINEOUT_INSERT            = 0x06\n\tSW_JACK_PHYSICAL_INSERT      = 0x07\n\tSW_VIDEOOUT_INSERT           = 0x08\n\tSW_CAMERA_LENS_COVER         = 0x09\n\tSW_KEYPAD_SLIDE              = 0x0a\n\tSW_FRONT_PROXIMITY           = 0x0b\n\tSW_ROTATE_LOCK               = 0x0c\n\tSW_LINEIN_INSERT             = 0x0d\n\tSW_MUTE_DEVICE               = 0x0e\n\tSW_PEN_INSERTED              = 0x0f\n\tSW_MAX                       = 0x0f\n\tMSC_SERIAL                   = 0x00\n\tMSC_PULSELED                 = 0x01\n\tMSC_GESTURE                  = 0x02\n\tMSC_RAW                      = 0x03\n\tMSC_SCAN                     = 0x04\n\tMSC_TIMESTAMP                = 0x05\n\tMSC_MAX                      = 0x07\n\tLED_NUML                     = 0x00\n\tLED_CAPSL                    = 0x01\n\tLED_SCROLLL                  = 0x02\n\tLED_COMPOSE                  = 0x03\n\tLED_KANA                     = 0x04\n\tLED_SLEEP                    = 0x05\n\tLED_SUSPEND                  = 0x06\n\tLED_MUTE                     = 0x07\n\tLED_MISC                     = 0x08\n\tLED_MAIL                     = 0x09\n\tLED_CHARGING                 = 0x0a\n\tLED_MAX                      = 0x0f\n\tREP_DELAY                    = 0x00\n\tREP_PERIOD                   = 0x01\n\tREP_MAX                      = 0x01\n\tSND_CLICK                    = 0x00\n\tSND_BELL                     = 0x01\n\tSND_TONE                     = 0x02\n\tSND_MAX                      = 0x07\n)\n\nvar KEYMap = map[uint16]string{0: \"KEY_RESERVED\", 1: \"KEY_ESC\", 2: \"KEY_1\", 3: \"KEY_2\", 4: \"KEY_3\", 5: \"KEY_4\", 6: \"KEY_5\", 7: \"KEY_6\", 8: \"KEY_7\", 9: \"KEY_8\", 10: \"KEY_9\", 11: \"KEY_0\", 12: \"KEY_MINUS\", 13: \"KEY_EQUAL\", 14: \"KEY_BACKSPACE\", 15: \"KEY_TAB\", 16: \"KEY_Q\", 17: \"KEY_W\", 18: \"KEY_E\", 19: \"KEY_R\", 20: \"KEY_T\", 21: \"KEY_Y\", 22: \"KEY_U\", 23: \"KEY_I\", 24: \"KEY_O\", 25: \"KEY_P\", 26: \"KEY_LEFTBRACE\", 27: \"KEY_RIGHTBRACE\", 28: \"KEY_ENTER\", 29: \"KEY_LEFTCTRL\", 30: \"KEY_A\", 31: \"KEY_S\", 32: \"KEY_D\", 33: \"KEY_F\", 34: \"KEY_G\", 35: \"KEY_H\", 36: \"KEY_J\", 37: \"KEY_K\", 38: \"KEY_L\", 39: \"KEY_SEMICOLON\", 40: \"KEY_APOSTROPHE\", 41: \"KEY_GRAVE\", 42: \"KEY_LEFTSHIFT\", 43: \"KEY_BACKSLASH\", 44: \"KEY_Z\", 45: \"KEY_X\", 46: \"KEY_C\", 47: \"KEY_V\", 48: \"KEY_B\", 49: \"KEY_N\", 50: \"KEY_M\", 51: \"KEY_COMMA\", 52: \"KEY_DOT\", 53: \"KEY_SLASH\", 54: \"KEY_RIGHTSHIFT\", 55: \"KEY_KPASTERISK\", 56: \"KEY_LEFTALT\", 57: \"KEY_SPACE\", 58: \"KEY_CAPSLOCK\", 59: \"KEY_F1\", 60: \"KEY_F2\", 61: \"KEY_F3\", 62: \"KEY_F4\", 63: \"KEY_F5\", 64: \"KEY_F6\", 65: \"KEY_F7\", 66: \"KEY_F8\", 67: \"KEY_F9\", 68: \"KEY_F10\", 69: \"KEY_NUMLOCK\", 70: \"KEY_SCROLLLOCK\", 71: \"KEY_KP7\", 72: \"KEY_KP8\", 73: \"KEY_KP9\", 74: \"KEY_KPMINUS\", 75: \"KEY_KP4\", 76: \"KEY_KP5\", 77: \"KEY_KP6\", 78: \"KEY_KPPLUS\", 79: \"KEY_KP1\", 80: \"KEY_KP2\", 81: \"KEY_KP3\", 82: \"KEY_KP0\", 83: \"KEY_KPDOT\", 85: \"KEY_ZENKAKUHANKAKU\", 86: \"KEY_102ND\", 87: \"KEY_F11\", 88: \"KEY_F12\", 89: \"KEY_RO\", 90: \"KEY_KATAKANA\", 91: \"KEY_HIRAGANA\", 92: \"KEY_HENKAN\", 93: \"KEY_KATAKANAHIRAGANA\", 94: \"KEY_MUHENKAN\", 95: \"KEY_KPJPCOMMA\", 96: \"KEY_KPENTER\", 97: \"KEY_RIGHTCTRL\", 98: \"KEY_KPSLASH\", 99: \"KEY_SYSRQ\", 100: \"KEY_RIGHTALT\", 101: \"KEY_LINEFEED\", 102: \"KEY_HOME\", 103: \"KEY_UP\", 104: \"KEY_PAGEUP\", 105: \"KEY_LEFT\", 106: \"KEY_RIGHT\", 107: \"KEY_END\", 108: \"KEY_DOWN\", 109: \"KEY_PAGEDOWN\", 110: \"KEY_INSERT\", 111: \"KEY_DELETE\", 112: \"KEY_MACRO\", 113: \"KEY_MUTE\", 114: \"KEY_VOLUMEDOWN\", 115: \"KEY_VOLUMEUP\", 116: \"KEY_POWER\", 117: \"KEY_KPEQUAL\", 118: \"KEY_KPPLUSMINUS\", 119: \"KEY_PAUSE\", 120: \"KEY_SCALE\", 121: \"KEY_KPCOMMA\", 122: \"KEY_HANGEUL\", 123: \"KEY_HANJA\", 124: \"KEY_YEN\", 125: \"KEY_LEFTMETA\", 126: \"KEY_RIGHTMETA\", 127: \"KEY_COMPOSE\", 128: \"KEY_STOP\", 129: \"KEY_AGAIN\", 130: \"KEY_PROPS\", 131: \"KEY_UNDO\", 132: \"KEY_FRONT\", 133: \"KEY_COPY\", 134: \"KEY_OPEN\", 135: \"KEY_PASTE\", 136: \"KEY_FIND\", 137: \"KEY_CUT\", 138: \"KEY_HELP\", 139: \"KEY_MENU\", 140: \"KEY_CALC\", 141: \"KEY_SETUP\", 142: \"KEY_SLEEP\", 143: \"KEY_WAKEUP\", 144: \"KEY_FILE\", 145: \"KEY_SENDFILE\", 146: \"KEY_DELETEFILE\", 147: \"KEY_XFER\", 148: \"KEY_PROG1\", 149: \"KEY_PROG2\", 150: \"KEY_WWW\", 151: \"KEY_MSDOS\", 152: \"KEY_COFFEE\", 153: \"KEY_ROTATE_DISPLAY\", 154: \"KEY_CYCLEWINDOWS\", 155: \"KEY_MAIL\", 156: \"KEY_BOOKMARKS\", 157: \"KEY_COMPUTER\", 158: \"KEY_BACK\", 159: \"KEY_FORWARD\", 160: \"KEY_CLOSECD\", 161: \"KEY_EJECTCD\", 162: \"KEY_EJECTCLOSECD\", 163: \"KEY_NEXTSONG\", 164: \"KEY_PLAYPAUSE\", 165: \"KEY_PREVIOUSSONG\", 166: \"KEY_STOPCD\", 167: \"KEY_RECORD\", 168: \"KEY_REWIND\", 169: \"KEY_PHONE\", 170: \"KEY_ISO\", 171: \"KEY_CONFIG\", 172: \"KEY_HOMEPAGE\", 173: \"KEY_REFRESH\", 174: \"KEY_EXIT\", 175: \"KEY_MOVE\", 176: \"KEY_EDIT\", 177: \"KEY_SCROLLUP\", 178: \"KEY_SCROLLDOWN\", 179: \"KEY_KPLEFTPAREN\", 180: \"KEY_KPRIGHTPAREN\", 181: \"KEY_NEW\", 182: \"KEY_REDO\", 183: \"KEY_F13\", 184: \"KEY_F14\", 185: \"KEY_F15\", 186: \"KEY_F16\", 187: \"KEY_F17\", 188: \"KEY_F18\", 189: \"KEY_F19\", 190: \"KEY_F20\", 191: \"KEY_F21\", 192: \"KEY_F22\", 193: \"KEY_F23\", 194: \"KEY_F24\", 200: \"KEY_PLAYCD\", 201: \"KEY_PAUSECD\", 202: \"KEY_PROG3\", 203: \"KEY_PROG4\", 204: \"KEY_DASHBOARD\", 205: \"KEY_SUSPEND\", 206: \"KEY_CLOSE\", 207: \"KEY_PLAY\", 208: \"KEY_FASTFORWARD\", 209: \"KEY_BASSBOOST\", 210: \"KEY_PRINT\", 211: \"KEY_HP\", 212: \"KEY_CAMERA\", 213: \"KEY_SOUND\", 214: \"KEY_QUESTION\", 215: \"KEY_EMAIL\", 216: \"KEY_CHAT\", 217: \"KEY_SEARCH\", 218: \"KEY_CONNECT\", 219: \"KEY_FINANCE\", 220: \"KEY_SPORT\", 221: \"KEY_SHOP\", 222: \"KEY_ALTERASE\", 223: \"KEY_CANCEL\", 224: \"KEY_BRIGHTNESSDOWN\", 225: \"KEY_BRIGHTNESSUP\", 226: \"KEY_MEDIA\", 227: \"KEY_SWITCHVIDEOMODE\", 228: \"KEY_KBDILLUMTOGGLE\", 229: \"KEY_KBDILLUMDOWN\", 230: \"KEY_KBDILLUMUP\", 231: \"KEY_SEND\", 232: \"KEY_REPLY\", 233: \"KEY_FORWARDMAIL\", 234: \"KEY_SAVE\", 235: \"KEY_DOCUMENTS\", 236: \"KEY_BATTERY\", 237: \"KEY_BLUETOOTH\", 238: \"KEY_WLAN\", 239: \"KEY_UWB\", 240: \"KEY_UNKNOWN\", 241: \"KEY_VIDEO_NEXT\", 242: \"KEY_VIDEO_PREV\", 243: \"KEY_BRIGHTNESS_CYCLE\", 244: \"KEY_BRIGHTNESS_AUTO\", 245: \"KEY_DISPLAY_OFF\", 246: \"KEY_WWAN\", 247: \"KEY_RFKILL\", 248: \"KEY_MICMUTE\", 0x160: \"KEY_OK\", 0x161: \"KEY_SELECT\", 0x162: \"KEY_GOTO\", 0x163: \"KEY_CLEAR\", 0x164: \"KEY_POWER2\", 0x165: \"KEY_OPTION\", 0x166: \"KEY_INFO\", 0x167: \"KEY_TIME\", 0x168: \"KEY_VENDOR\", 0x169: \"KEY_ARCHIVE\", 0x16a: \"KEY_PROGRAM\", 0x16b: \"KEY_CHANNEL\", 0x16c: \"KEY_FAVORITES\", 0x16d: \"KEY_EPG\", 0x16e: \"KEY_PVR\", 0x16f: \"KEY_MHP\", 0x170: \"KEY_LANGUAGE\", 0x171: \"KEY_TITLE\", 0x172: \"KEY_SUBTITLE\", 0x173: \"KEY_ANGLE\", 0x174: \"KEY_ZOOM\", 0x175: \"KEY_MODE\", 0x176: \"KEY_KEYBOARD\", 0x177: \"KEY_SCREEN\", 0x178: \"KEY_PC\", 0x179: \"KEY_TV\", 0x17a: \"KEY_TV2\", 0x17b: \"KEY_VCR\", 0x17c: \"KEY_VCR2\", 0x17d: \"KEY_SAT\", 0x17e: \"KEY_SAT2\", 0x17f: \"KEY_CD\", 0x180: \"KEY_TAPE\", 0x181: \"KEY_RADIO\", 0x182: \"KEY_TUNER\", 0x183: \"KEY_PLAYER\", 0x184: \"KEY_TEXT\", 0x185: \"KEY_DVD\", 0x186: \"KEY_AUX\", 0x187: \"KEY_MP3\", 0x188: \"KEY_AUDIO\", 0x189: \"KEY_VIDEO\", 0x18a: \"KEY_DIRECTORY\", 0x18b: \"KEY_LIST\", 0x18c: \"KEY_MEMO\", 0x18d: \"KEY_CALENDAR\", 0x18e: \"KEY_RED\", 0x18f: \"KEY_GREEN\", 0x190: \"KEY_YELLOW\", 0x191: \"KEY_BLUE\", 0x192: \"KEY_CHANNELUP\", 0x193: \"KEY_CHANNELDOWN\", 0x194: \"KEY_FIRST\", 0x195: \"KEY_LAST\", 0x196: \"KEY_AB\", 0x197: \"KEY_NEXT\", 0x198: \"KEY_RESTART\", 0x199: \"KEY_SLOW\", 0x19a: \"KEY_SHUFFLE\", 0x19b: \"KEY_BREAK\", 0x19c: \"KEY_PREVIOUS\", 0x19d: \"KEY_DIGITS\", 0x19e: \"KEY_TEEN\", 0x19f: \"KEY_TWEN\", 0x1a0: \"KEY_VIDEOPHONE\", 0x1a1: \"KEY_GAMES\", 0x1a2: \"KEY_ZOOMIN\", 0x1a3: \"KEY_ZOOMOUT\", 0x1a4: \"KEY_ZOOMRESET\", 0x1a5: \"KEY_WORDPROCESSOR\", 0x1a6: \"KEY_EDITOR\", 0x1a7: \"KEY_SPREADSHEET\", 0x1a8: \"KEY_GRAPHICSEDITOR\", 0x1a9: \"KEY_PRESENTATION\", 0x1aa: \"KEY_DATABASE\", 0x1ab: \"KEY_NEWS\", 0x1ac: \"KEY_VOICEMAIL\", 0x1ad: \"KEY_ADDRESSBOOK\", 0x1ae: \"KEY_MESSENGER\", 0x1af: \"KEY_DISPLAYTOGGLE\", 0x1b0: \"KEY_SPELLCHECK\", 0x1b1: \"KEY_LOGOFF\", 0x1b2: \"KEY_DOLLAR\", 0x1b3: \"KEY_EURO\", 0x1b4: \"KEY_FRAMEBACK\", 0x1b5: \"KEY_FRAMEFORWARD\", 0x1b6: \"KEY_CONTEXT_MENU\", 0x1b7: \"KEY_MEDIA_REPEAT\", 0x1b8: \"KEY_10CHANNELSUP\", 0x1b9: \"KEY_10CHANNELSDOWN\", 0x1ba: \"KEY_IMAGES\", 0x1c0: \"KEY_DEL_EOL\", 0x1c1: \"KEY_DEL_EOS\", 0x1c2: \"KEY_INS_LINE\", 0x1c3: \"KEY_DEL_LINE\", 0x1d0: \"KEY_FN\", 0x1d1: \"KEY_FN_ESC\", 0x1d2: \"KEY_FN_F1\", 0x1d3: \"KEY_FN_F2\", 0x1d4: \"KEY_FN_F3\", 0x1d5: \"KEY_FN_F4\", 0x1d6: \"KEY_FN_F5\", 0x1d7: \"KEY_FN_F6\", 0x1d8: \"KEY_FN_F7\", 0x1d9: \"KEY_FN_F8\", 0x1da: \"KEY_FN_F9\", 0x1db: \"KEY_FN_F10\", 0x1dc: \"KEY_FN_F11\", 0x1dd: \"KEY_FN_F12\", 0x1de: \"KEY_FN_1\", 0x1df: \"KEY_FN_2\", 0x1e0: \"KEY_FN_D\", 0x1e1: \"KEY_FN_E\", 0x1e2: \"KEY_FN_F\", 0x1e3: \"KEY_FN_S\", 0x1e4: \"KEY_FN_B\", 0x1f1: \"KEY_BRL_DOT1\", 0x1f2: \"KEY_BRL_DOT2\", 0x1f3: \"KEY_BRL_DOT3\", 0x1f4: \"KEY_BRL_DOT4\", 0x1f5: \"KEY_BRL_DOT5\", 0x1f6: \"KEY_BRL_DOT6\", 0x1f7: \"KEY_BRL_DOT7\", 0x1f8: \"KEY_BRL_DOT8\", 0x1f9: \"KEY_BRL_DOT9\", 0x1fa: \"KEY_BRL_DOT10\", 0x200: \"KEY_NUMERIC_0\", 0x201: \"KEY_NUMERIC_1\", 0x202: \"KEY_NUMERIC_2\", 0x203: \"KEY_NUMERIC_3\", 0x204: \"KEY_NUMERIC_4\", 0x205: \"KEY_NUMERIC_5\", 0x206: \"KEY_NUMERIC_6\", 0x207: \"KEY_NUMERIC_7\", 0x208: \"KEY_NUMERIC_8\", 0x209: \"KEY_NUMERIC_9\", 0x20a: \"KEY_NUMERIC_STAR\", 0x20b: \"KEY_NUMERIC_POUND\", 0x20c: \"KEY_NUMERIC_A\", 0x20d: \"KEY_NUMERIC_B\", 0x20e: \"KEY_NUMERIC_C\", 0x20f: \"KEY_NUMERIC_D\", 0x210: \"KEY_CAMERA_FOCUS\", 0x211: \"KEY_WPS_BUTTON\", 0x212: \"KEY_TOUCHPAD_TOGGLE\", 0x213: \"KEY_TOUCHPAD_ON\", 0x214: \"KEY_TOUCHPAD_OFF\", 0x215: \"KEY_CAMERA_ZOOMIN\", 0x216: \"KEY_CAMERA_ZOOMOUT\", 0x217: \"KEY_CAMERA_UP\", 0x218: \"KEY_CAMERA_DOWN\", 0x219: \"KEY_CAMERA_LEFT\", 0x21a: \"KEY_CAMERA_RIGHT\", 0x21b: \"KEY_ATTENDANT_ON\", 0x21c: \"KEY_ATTENDANT_OFF\", 0x21d: \"KEY_ATTENDANT_TOGGLE\", 0x21e: \"KEY_LIGHTS_TOGGLE\", 0x230: \"KEY_ALS_TOGGLE\", 0x240: \"KEY_BUTTONCONFIG\", 0x241: \"KEY_TASKMANAGER\", 0x242: \"KEY_JOURNAL\", 0x243: \"KEY_CONTROLPANEL\", 0x244: \"KEY_APPSELECT\", 0x245: \"KEY_SCREENSAVER\", 0x246: \"KEY_VOICECOMMAND\", 0x247: \"KEY_ASSISTANT\", 0x250: \"KEY_BRIGHTNESS_MIN\", 0x260: \"KEY_KBDINPUTASSIST_PREV\", 0x261: \"KEY_KBDINPUTASSIST_NEXT\", 0x262: \"KEY_KBDINPUTASSIST_PREVGROUP\", 0x263: \"KEY_KBDINPUTASSIST_NEXTGROUP\", 0x264: \"KEY_KBDINPUTASSIST_ACCEPT\", 0x265: \"KEY_KBDINPUTASSIST_CANCEL\", 0x266: \"KEY_RIGHT_UP\", 0x267: \"KEY_RIGHT_DOWN\", 0x268: \"KEY_LEFT_UP\", 0x269: \"KEY_LEFT_DOWN\", 0x26a: \"KEY_ROOT_MENU\", 0x26b: \"KEY_MEDIA_TOP_MENU\", 0x26c: \"KEY_NUMERIC_11\", 0x26d: \"KEY_NUMERIC_12\", 0x26e: \"KEY_AUDIO_DESC\", 0x26f: \"KEY_3D_MODE\", 0x270: \"KEY_NEXT_FAVORITE\", 0x271: \"KEY_STOP_RECORD\", 0x272: \"KEY_PAUSE_RECORD\", 0x273: \"KEY_VOD\", 0x274: \"KEY_UNMUTE\", 0x275: \"KEY_FASTREVERSE\", 0x276: \"KEY_SLOWREVERSE\", 0x277: \"KEY_DATA\", 0x278: \"KEY_ONSCREEN_KEYBOARD\"}\nvar ABSMap = map[uint16]string{0x00: \"ABS_X\", 0x01: \"ABS_Y\", 0x02: \"ABS_Z\", 0x03: \"ABS_RX\", 0x04: \"ABS_RY\", 0x05: \"ABS_RZ\", 0x06: \"ABS_THROTTLE\", 0x07: \"ABS_RUDDER\", 0x08: \"ABS_WHEEL\", 0x09: \"ABS_GAS\", 0x0a: \"ABS_BRAKE\", 0x10: \"ABS_HAT0X\", 0x11: \"ABS_HAT0Y\", 0x12: \"ABS_HAT1X\", 0x13: \"ABS_HAT1Y\", 0x14: \"ABS_HAT2X\", 0x15: \"ABS_HAT2Y\", 0x16: \"ABS_HAT3X\", 0x17: \"ABS_HAT3Y\", 0x18: \"ABS_PRESSURE\", 0x19: \"ABS_DISTANCE\", 0x1a: \"ABS_TILT_X\", 0x1b: \"ABS_TILT_Y\", 0x1c: \"ABS_TOOL_WIDTH\", 0x20: \"ABS_VOLUME\", 0x28: \"ABS_MISC\", 0x2e: \"ABS_RESERVED\", 0x2f: \"ABS_MT_SLOT\", 0x30: \"ABS_MT_TOUCH_MAJOR\", 0x31: \"ABS_MT_TOUCH_MINOR\", 0x32: \"ABS_MT_WIDTH_MAJOR\", 0x33: \"ABS_MT_WIDTH_MINOR\", 0x34: \"ABS_MT_ORIENTATION\", 0x35: \"ABS_MT_POSITION_X\", 0x36: \"ABS_MT_POSITION_Y\", 0x37: \"ABS_MT_TOOL_TYPE\", 0x38: \"ABS_MT_BLOB_ID\", 0x39: \"ABS_MT_TRACKING_ID\", 0x3a: \"ABS_MT_PRESSURE\", 0x3b: \"ABS_MT_DISTANCE\", 0x3c: \"ABS_MT_TOOL_X\", 0x3d: \"ABS_MT_TOOL_Y\"}\nvar RELMap = map[uint16]string{0x00: \"REL_X\", 0x01: \"REL_Y\", 0x02: \"REL_Z\", 0x03: \"REL_RX\", 0x04: \"REL_RY\", 0x05: \"REL_RZ\", 0x06: \"REL_HWHEEL\", 0x07: \"REL_DIAL\", 0x08: \"REL_WHEEL\", 0x09: \"REL_MISC\"}\nvar SWMap = map[uint16]string{0x00: \"SW_LID\", 0x01: \"SW_TABLET_MODE\", 0x02: \"SW_HEADPHONE_INSERT\", 0x03: \"SW_RFKILL_ALL\", 0x04: \"SW_MICROPHONE_INSERT\", 0x05: \"SW_DOCK\", 0x06: \"SW_LINEOUT_INSERT\", 0x07: \"SW_JACK_PHYSICAL_INSERT\", 0x08: \"SW_VIDEOOUT_INSERT\", 0x09: \"SW_CAMERA_LENS_COVER\", 0x0a: \"SW_KEYPAD_SLIDE\", 0x0b: \"SW_FRONT_PROXIMITY\", 0x0c: \"SW_ROTATE_LOCK\", 0x0d: \"SW_LINEIN_INSERT\", 0x0e: \"SW_MUTE_DEVICE\", 0x0f: \"SW_PEN_INSERTED\"}\nvar MSCMap = map[uint16]string{0x00: \"MSC_SERIAL\", 0x01: \"MSC_PULSELED\", 0x02: \"MSC_GESTURE\", 0x03: \"MSC_RAW\", 0x04: \"MSC_SCAN\", 0x05: \"MSC_TIMESTAMP\"}\nvar LEDMap = map[uint16]string{0x00: \"LED_NUML\", 0x01: \"LED_CAPSL\", 0x02: \"LED_SCROLLL\", 0x03: \"LED_COMPOSE\", 0x04: \"LED_KANA\", 0x05: \"LED_SLEEP\", 0x06: \"LED_SUSPEND\", 0x07: \"LED_MUTE\", 0x08: \"LED_MISC\", 0x09: \"LED_MAIL\", 0x0a: \"LED_CHARGING\"}\nvar BTNMap = map[uint16]string{0x100: \"BTN_0\", 0x101: \"BTN_1\", 0x102: \"BTN_2\", 0x103: \"BTN_3\", 0x104: \"BTN_4\", 0x105: \"BTN_5\", 0x106: \"BTN_6\", 0x107: \"BTN_7\", 0x108: \"BTN_8\", 0x109: \"BTN_9\", 0x110: \"BTN_LEFT\", 0x111: \"BTN_RIGHT\", 0x112: \"BTN_MIDDLE\", 0x113: \"BTN_SIDE\", 0x114: \"BTN_EXTRA\", 0x115: \"BTN_FORWARD\", 0x116: \"BTN_BACK\", 0x117: \"BTN_TASK\", 0x120: \"BTN_JOYSTICK\", 0x121: \"BTN_THUMB\", 0x122: \"BTN_THUMB2\", 0x123: \"BTN_TOP\", 0x124: \"BTN_TOP2\", 0x125: \"BTN_PINKIE\", 0x126: \"BTN_BASE\", 0x127: \"BTN_BASE2\", 0x128: \"BTN_BASE3\", 0x129: \"BTN_BASE4\", 0x12a: \"BTN_BASE5\", 0x12b: \"BTN_BASE6\", 0x12f: \"BTN_DEAD\", 0x130: \"BTN_GAMEPAD\", 0x131: \"BTN_EAST\", 0x132: \"BTN_C\", 0x133: \"BTN_NORTH\", 0x134: \"BTN_WEST\", 0x135: \"BTN_Z\", 0x136: \"BTN_TL\", 0x137: \"BTN_TR\", 0x138: \"BTN_TL2\", 0x139: \"BTN_TR2\", 0x13a: \"BTN_SELECT\", 0x13b: \"BTN_START\", 0x13c: \"BTN_MODE\", 0x13d: \"BTN_THUMBL\", 0x13e: \"BTN_THUMBR\", 0x140: \"BTN_TOOL_PEN\", 0x141: \"BTN_TOOL_RUBBER\", 0x142: \"BTN_TOOL_BRUSH\", 0x143: \"BTN_TOOL_PENCIL\", 0x144: \"BTN_TOOL_AIRBRUSH\", 0x145: \"BTN_TOOL_FINGER\", 0x146: \"BTN_TOOL_MOUSE\", 0x147: \"BTN_TOOL_LENS\", 0x148: \"BTN_TOOL_QUINTTAP\", 0x149: \"BTN_STYLUS3\", 0x14a: \"BTN_TOUCH\", 0x14b: \"BTN_STYLUS\", 0x14c: \"BTN_STYLUS2\", 0x14d: \"BTN_TOOL_DOUBLETAP\", 0x14e: \"BTN_TOOL_TRIPLETAP\", 0x14f: \"BTN_TOOL_QUADTAP\", 0x150: \"BTN_GEAR_DOWN\", 0x151: \"BTN_GEAR_UP\", 0x220: \"BTN_DPAD_UP\", 0x221: \"BTN_DPAD_DOWN\", 0x222: \"BTN_DPAD_LEFT\", 0x223: \"BTN_DPAD_RIGHT\", 0x2c0: \"BTN_TRIGGER_HAPPY1\", 0x2c1: \"BTN_TRIGGER_HAPPY2\", 0x2c2: \"BTN_TRIGGER_HAPPY3\", 0x2c3: \"BTN_TRIGGER_HAPPY4\", 0x2c4: \"BTN_TRIGGER_HAPPY5\", 0x2c5: \"BTN_TRIGGER_HAPPY6\", 0x2c6: \"BTN_TRIGGER_HAPPY7\", 0x2c7: \"BTN_TRIGGER_HAPPY8\", 0x2c8: \"BTN_TRIGGER_HAPPY9\", 0x2c9: \"BTN_TRIGGER_HAPPY10\", 0x2ca: \"BTN_TRIGGER_HAPPY11\", 0x2cb: \"BTN_TRIGGER_HAPPY12\", 0x2cc: \"BTN_TRIGGER_HAPPY13\", 0x2cd: \"BTN_TRIGGER_HAPPY14\", 0x2ce: \"BTN_TRIGGER_HAPPY15\", 0x2cf: \"BTN_TRIGGER_HAPPY16\", 0x2d0: \"BTN_TRIGGER_HAPPY17\", 0x2d1: \"BTN_TRIGGER_HAPPY18\", 0x2d2: \"BTN_TRIGGER_HAPPY19\", 0x2d3: \"BTN_TRIGGER_HAPPY20\", 0x2d4: \"BTN_TRIGGER_HAPPY21\", 0x2d5: \"BTN_TRIGGER_HAPPY22\", 0x2d6: \"BTN_TRIGGER_HAPPY23\", 0x2d7: \"BTN_TRIGGER_HAPPY24\", 0x2d8: \"BTN_TRIGGER_HAPPY25\", 0x2d9: \"BTN_TRIGGER_HAPPY26\", 0x2da: \"BTN_TRIGGER_HAPPY27\", 0x2db: \"BTN_TRIGGER_HAPPY28\", 0x2dc: \"BTN_TRIGGER_HAPPY29\", 0x2dd: \"BTN_TRIGGER_HAPPY30\", 0x2de: \"BTN_TRIGGER_HAPPY31\", 0x2df: \"BTN_TRIGGER_HAPPY32\", 0x2e0: \"BTN_TRIGGER_HAPPY33\", 0x2e1: \"BTN_TRIGGER_HAPPY34\", 0x2e2: \"BTN_TRIGGER_HAPPY35\", 0x2e3: \"BTN_TRIGGER_HAPPY36\", 0x2e4: \"BTN_TRIGGER_HAPPY37\", 0x2e5: \"BTN_TRIGGER_HAPPY38\", 0x2e6: \"BTN_TRIGGER_HAPPY39\", 0x2e7: \"BTN_TRIGGER_HAPPY40\"}\nvar REPMap = map[uint16]string{0x00: \"REP_DELAY\", 0x01: \"REP_PERIOD\"}\nvar SNDMap = map[uint16]string{0x00: \"SND_CLICK\", 0x01: \"SND_BELL\", 0x02: \"SND_TONE\"}\nvar IDMap = map[uint16]string{0: \"ID_BUS\", 1: \"ID_VENDOR\", 2: \"ID_PRODUCT\", 3: \"ID_VERSION\"}\nvar EVMap = map[uint16]string{0x00: \"EV_SYN\", 0x01: \"EV_KEY\", 0x02: \"EV_REL\", 0x03: \"EV_ABS\", 0x04: \"EV_MSC\", 0x05: \"EV_SW\", 0x11: \"EV_LED\", 0x12: \"EV_SND\", 0x14: \"EV_REP\", 0x15: \"EV_FF\", 0x16: \"EV_PWR\", 0x17: \"EV_FF_STATUS\"}\nvar BUSMap = map[uint16]string{0x01: \"BUS_PCI\", 0x02: \"BUS_ISAPNP\", 0x03: \"BUS_USB\", 0x04: \"BUS_HIL\", 0x05: \"BUS_BLUETOOTH\", 0x06: \"BUS_VIRTUAL\", 0x10: \"BUS_ISA\", 0x11: \"BUS_I8042\", 0x12: \"BUS_XTKBD\", 0x13: \"BUS_RS232\", 0x14: \"BUS_GAMEPORT\", 0x15: \"BUS_PARPORT\", 0x16: \"BUS_AMIGA\", 0x17: \"BUS_ADB\", 0x18: \"BUS_I2C\", 0x19: \"BUS_HOST\", 0x1A: \"BUS_GSC\", 0x1B: \"BUS_ATARI\", 0x1C: \"BUS_SPI\", 0x1D: \"BUS_RMI\", 0x1E: \"BUS_CEC\", 0x1F: \"BUS_INTEL_ISHTP\"}\nvar SYNMap = map[uint16]string{0: \"SYN_REPORT\", 1: \"SYN_CONFIG\", 2: \"SYN_MT_REPORT\", 3: \"SYN_DROPPED\"}\nvar FFMap = map[uint16]string{0x00: \"FF_STATUS_STOPPED\", 0x01: \"FF_STATUS_PLAYING\", 0x50: \"FF_RUMBLE\", 0x51: \"FF_PERIODIC\", 0x52: \"FF_CONSTANT\", 0x53: \"FF_SPRING\", 0x54: \"FF_FRICTION\", 0x55: \"FF_DAMPER\", 0x56: \"FF_INERTIA\", 0x57: \"FF_RAMP\", 0x58: \"FF_SQUARE\", 0x59: \"FF_TRIANGLE\", 0x5a: \"FF_SINE\", 0x5b: \"FF_SAW_UP\", 0x5c: \"FF_SAW_DOWN\", 0x5d: \"FF_CUSTOM\", 0x60: \"FF_GAIN\", 0x61: \"FF_AUTOCENTER\"}\n\nfunc CodeString(etype uint16, code uint16) string {\n\tvar stype = EVMap[etype]\n\tswitch stype {\n\tcase \"EV_SYN\":\n\t\treturn SYNMap[code]\n\tcase \"EV_KEY\":\n\t\treturn KEYMap[code]\n\tcase \"EV_ABS\":\n\t\treturn ABSMap[code]\n\tcase \"EV_REL\":\n\t\treturn RELMap[code]\n\tcase \"EV_SW\":\n\t\treturn SWMap[code]\n\tcase \"EV_MSC\":\n\t\treturn MSCMap[code]\n\tcase \"EV_LED\":\n\t\treturn LEDMap[code]\n\tcase \"EV_SND\":\n\t\treturn SNDMap[code]\n\tcase \"EV_REP\":\n\t\treturn REPMap[code]\n\tcase \"EV_FF\":\n\t\treturn FFMap[code]\n\tdefault:\n\t\treturn \"\"\n\t}\n}\n"
  },
  {
    "path": "pkg/evdeviterator.go",
    "content": "// This file is part of remouseable.\n//\n// remouseable is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License version 3 as published\n// by the Free Software Foundation.\n//\n// remouseable is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with remouseable.  If not, see <https://www.gnu.org/licenses/>.\n\npackage remouseable\n\nimport (\n\t\"bytes\"\n\t\"encoding/binary\"\n\t\"io\"\n\t\"time\"\n)\n\ntype rawEvent struct {\n\t// The time values must be uint32 to work with the tablet build. The default\n\t// syscall.Timeval uses uint64 on a 64bit platform so we must adapt here.\n\tSec   uint32\n\tUsec  uint32\n\tType  uint16\n\tCode  uint16\n\tValue int32\n}\n\n// FileEvdevIterator implements the EvdevIterator interface by consuming from\n// an io.ReadCloser.\ntype FileEvdevIterator struct {\n\tSource  io.ReadCloser\n\terr     error\n\tcurrent EvdevEvent\n}\n\n// Next reads an event from the file source.\nfunc (it *FileEvdevIterator) Next() bool {\n\tif it.err != nil {\n\t\t// Prevent re-entry after an error.\n\t\treturn false\n\t}\n\n\tevt := rawEvent{}\n\tsize := binary.Size(evt)\n\tbuf := make([]byte, size)\n\n\tif _, err := it.Source.Read(buf); err != nil {\n\t\tit.err = err\n\t\treturn false\n\t}\n\n\tif err := binary.Read(bytes.NewReader(buf), binary.LittleEndian, &evt); err != nil {\n\t\tit.err = err\n\t\treturn false\n\t}\n\n\tit.current = EvdevEvent{\n\t\tTime:  time.Unix(int64(evt.Sec), int64(evt.Usec)),\n\t\tType:  evt.Type,\n\t\tCode:  evt.Code,\n\t\tValue: evt.Value,\n\t}\n\treturn true\n}\n\n// Current returns the iterator value.\nfunc (it *FileEvdevIterator) Current() EvdevEvent {\n\treturn it.current\n}\n\n// Close the underlying source and return any errors.\nfunc (it *FileEvdevIterator) Close() error {\n\terr := it.Source.Close()\n\tif it.err == nil {\n\t\treturn err\n\t}\n\treturn it.err\n}\n\n// SelectingEvdevIterator reduces an iterator output to a selection of top-level\n// event types.\ntype SelectingEvdevIterator struct {\n\tWrapped   EvdevIterator\n\tSelection []uint16\n\tcurrent   EvdevEvent\n}\n\n// Next continually calls the wrapped Next() until it either returns a value\n// that matches the selection criteria or it returns a false.\nfunc (it *SelectingEvdevIterator) Next() bool {\n\tfor it.Wrapped.Next() {\n\t\tc := it.Wrapped.Current()\n\t\tfor _, selection := range it.Selection {\n\t\t\tif c.Type == selection {\n\t\t\t\tit.current = c\n\t\t\t\treturn true\n\t\t\t}\n\t\t}\n\t}\n\treturn false\n}\n\n// Current returns the active element.\nfunc (it *SelectingEvdevIterator) Current() EvdevEvent {\n\treturn it.current\n}\n\n// Close proxies to the wrapped instance.\nfunc (it *SelectingEvdevIterator) Close() error {\n\treturn it.Wrapped.Close()\n}\n\n// FilteringEvdevIterator reduces an iterator output to all but a selection of\n// top-level event types.\ntype FilteringEvdevIterator struct {\n\tWrapped EvdevIterator\n\tFilter  []uint16\n\tcurrent EvdevEvent\n}\n\n// Next continually calls the wrapped Next() until it either returns a value\n// that matches the filter criteria or it returns a false.\nfunc (it *FilteringEvdevIterator) Next() bool {\n\tfor it.Wrapped.Next() {\n\t\tc := it.Wrapped.Current()\n\t\tok := true\n\t\tfor _, filter := range it.Filter {\n\t\t\tif c.Type == filter {\n\t\t\t\tok = false\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tif ok {\n\t\t\tit.current = c\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\n// Current returns the active element.\nfunc (it *FilteringEvdevIterator) Current() EvdevEvent {\n\treturn it.current\n}\n\n// Close proxies to the wrapped instance.\nfunc (it *FilteringEvdevIterator) Close() error {\n\treturn it.Wrapped.Close()\n}\n"
  },
  {
    "path": "pkg/evdeviterator_test.go",
    "content": "// This file is part of remouseable.\n//\n// remouseable is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License version 3 as published\n// by the Free Software Foundation.\n//\n// remouseable is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with remouseable.  If not, see <https://www.gnu.org/licenses/>.\n\npackage remouseable\n\nimport (\n\t\"fmt\"\n\t\"testing\"\n\n\tgomock \"github.com/golang/mock/gomock\"\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc TestFileEvdevIterator_Next(t *testing.T) {\n\tsentinelErr := fmt.Errorf(\"test\")\n\ttests := []struct {\n\t\tname        string\n\t\twant        bool\n\t\twantErr     bool\n\t\texpectedErr error\n\t\twantRead    bool\n\t\treadBytes   []byte\n\t\treadErr     error\n\t\tcloseErr    error\n\t}{\n\t\t{\n\t\t\tname:        \"read error\",\n\t\t\twant:        false,\n\t\t\twantErr:     true,\n\t\t\texpectedErr: sentinelErr,\n\t\t\twantRead:    true,\n\t\t\treadBytes:   nil,\n\t\t\treadErr:     sentinelErr,\n\t\t\tcloseErr:    nil,\n\t\t},\n\t\t{\n\t\t\tname:        \"read data\",\n\t\t\twant:        true,\n\t\t\twantErr:     false,\n\t\t\texpectedErr: nil,\n\t\t\twantRead:    true,\n\t\t\treadBytes:   []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\n\t\t\treadErr:     nil,\n\t\t\tcloseErr:    nil,\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tctrl := gomock.NewController(t)\n\t\t\tdefer ctrl.Finish()\n\n\t\t\tsrc := NewMockReadCloser(ctrl)\n\t\t\tit := &FileEvdevIterator{\n\t\t\t\tSource: src,\n\t\t\t}\n\t\t\tif tt.wantRead {\n\t\t\t\tsrc.EXPECT().Read(gomock.Any()).Do(func(b []byte) {\n\t\t\t\t\tcopy(b, tt.readBytes)\n\t\t\t\t}).Return(0, tt.readErr)\n\t\t\t}\n\t\t\tsrc.EXPECT().Close().Return(tt.closeErr).AnyTimes()\n\t\t\trequire.Equal(t, tt.want, it.Next())\n\t\t\tif tt.wantErr {\n\t\t\t\trequire.Equal(t, tt.expectedErr, it.Close())\n\t\t\t\trequire.Equal(t, false, it.Next())\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestSelectingEvdevIterator_Next(t *testing.T) {\n\ttype fields struct {\n\t\tSelection []uint16\n\t}\n\ttests := []struct {\n\t\tname     string\n\t\tfields   fields\n\t\tsource   []EvdevEvent\n\t\texpected []EvdevEvent\n\t}{\n\t\t{\n\t\t\tname:     \"empty source\",\n\t\t\tfields:   fields{Selection: []uint16{0}},\n\t\t\tsource:   []EvdevEvent{},\n\t\t\texpected: []EvdevEvent{},\n\t\t},\n\t\t{\n\t\t\tname:     \"full set\",\n\t\t\tfields:   fields{Selection: []uint16{0}},\n\t\t\tsource:   []EvdevEvent{{}, {}, {}},\n\t\t\texpected: []EvdevEvent{{}, {}, {}},\n\t\t},\n\t\t{\n\t\t\tname:     \"partial set\",\n\t\t\tfields:   fields{Selection: []uint16{0}},\n\t\t\tsource:   []EvdevEvent{{Type: 1}, {Type: 1}, {Type: 0}},\n\t\t\texpected: []EvdevEvent{{Type: 0}},\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tctrl := gomock.NewController(t)\n\t\t\tdefer ctrl.Finish()\n\n\t\t\twrapped := NewMockEvdevIterator(ctrl)\n\t\t\tit := &SelectingEvdevIterator{\n\t\t\t\tWrapped:   wrapped,\n\t\t\t\tSelection: tt.fields.Selection,\n\t\t\t}\n\t\t\tfor _, s := range tt.source {\n\t\t\t\twrapped.EXPECT().Next().Return(true)\n\t\t\t\twrapped.EXPECT().Current().Return(s)\n\t\t\t}\n\t\t\twrapped.EXPECT().Next().Return(false)\n\t\t\twrapped.EXPECT().Close().Return(nil)\n\t\t\tresults := make([]EvdevEvent, 0, len(tt.expected))\n\t\t\tfor it.Next() {\n\t\t\t\tresults = append(results, it.Current())\n\t\t\t}\n\t\t\trequire.Equal(t, nil, it.Close())\n\t\t\trequire.ElementsMatch(t, tt.expected, results)\n\t\t})\n\t}\n}\n\nfunc TestFilteringEvdevIterator_Next(t *testing.T) {\n\ttype fields struct {\n\t\tFilter []uint16\n\t}\n\ttests := []struct {\n\t\tname     string\n\t\tfields   fields\n\t\tsource   []EvdevEvent\n\t\texpected []EvdevEvent\n\t}{\n\t\t{\n\t\t\tname:     \"empty source\",\n\t\t\tfields:   fields{Filter: []uint16{0}},\n\t\t\tsource:   []EvdevEvent{},\n\t\t\texpected: []EvdevEvent{},\n\t\t},\n\t\t{\n\t\t\tname:     \"all filtered\",\n\t\t\tfields:   fields{Filter: []uint16{0}},\n\t\t\tsource:   []EvdevEvent{{}, {}, {}},\n\t\t\texpected: []EvdevEvent{},\n\t\t},\n\t\t{\n\t\t\tname:     \"partial filter\",\n\t\t\tfields:   fields{Filter: []uint16{0}},\n\t\t\tsource:   []EvdevEvent{{Type: 1}, {Type: 1}, {Type: 0}},\n\t\t\texpected: []EvdevEvent{{Type: 1}, {Type: 1}},\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tctrl := gomock.NewController(t)\n\t\t\tdefer ctrl.Finish()\n\n\t\t\twrapped := NewMockEvdevIterator(ctrl)\n\t\t\tit := &FilteringEvdevIterator{\n\t\t\t\tWrapped: wrapped,\n\t\t\t\tFilter:  tt.fields.Filter,\n\t\t\t}\n\t\t\tfor _, s := range tt.source {\n\t\t\t\twrapped.EXPECT().Next().Return(true)\n\t\t\t\twrapped.EXPECT().Current().Return(s)\n\t\t\t}\n\t\t\twrapped.EXPECT().Next().Return(false)\n\t\t\twrapped.EXPECT().Close().Return(nil)\n\t\t\tresults := make([]EvdevEvent, 0, len(tt.expected))\n\t\t\tfor it.Next() {\n\t\t\t\tresults = append(results, it.Current())\n\t\t\t}\n\t\t\trequire.Equal(t, nil, it.Close())\n\t\t\trequire.ElementsMatch(t, tt.expected, results)\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "pkg/gen.go",
    "content": "package remouseable\n\n//go:generate mockgen -destination mock_driver_test.go -package remouseable -self_package github.com/kevinconway/remouseable/pkg github.com/kevinconway/remouseable/pkg Driver\n//go:generate mockgen -destination mock_positionscaler_test.go -package remouseable -self_package github.com/kevinconway/remouseable/pkg github.com/kevinconway/remouseable/pkg PositionScaler\n//go:generate mockgen -destination mock_statemachine_test.go -package remouseable -self_package github.com/kevinconway/remouseable/pkg github.com/kevinconway/remouseable/pkg StateMachine\n//go:generate mockgen -destination mock_evdeviterator_test.go -package remouseable -self_package github.com/kevinconway/remouseable/pkg github.com/kevinconway/remouseable/pkg EvdevIterator\n//go:generate mockgen -destination mock_readcloser_test.go -package remouseable -self_package github.com/kevinconway/remouseable/pkg io ReadCloser\n"
  },
  {
    "path": "pkg/internal/gen.go",
    "content": "package internal\n\nimport (\n\t// Force a nimport of mock so that it guarantees that the mock package\n\t// will be included in vendor.\n\t_ \"github.com/golang/mock/mockgen/model\"\n)\n\n//go:generate go run ./gencodes --destination=../evdevcodes.go\n"
  },
  {
    "path": "pkg/internal/gencodes/main.go",
    "content": "// This file is part of remouseable.\n//\n// remouseable is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License version 3 as published\n// by the Free Software Foundation.\n//\n// remouseable is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with remouseable.  If not, see <https://www.gnu.org/licenses/>.\n\n// Package main generates a Go source file that contains a mapping of all\n// evdev codes by extracting them from the linux source code files.\npackage main\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"fmt\"\n\t\"os\"\n\t\"regexp\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/dave/jennifer/jen\"\n\tflag \"github.com/spf13/pflag\"\n\tsys \"golang.org/x/sys/unix\"\n)\n\nvar sourceFiles = []string{\n\t\"/usr/include/linux/input.h\",\n\t\"/usr/include/linux/input-event-codes.h\",\n}\n\n// pattern is copied from github.com/gvalkov/golang-evdev\nconst pattern = `#define +((?:KEY|ABS|REL|SW|MSC|LED|BTN|REP|SND|ID|EV|BUS|SYN|FF)_\\w+)\\s+(\\w+)`\n\nfunc main() {\n\tfs := flag.NewFlagSet(\"gencodes\", flag.ExitOnError)\n\tsrcs := fs.StringArray(\"sources\", sourceFiles, \"Linux header source files to process.\")\n\tdst := fs.String(\"destination\", \"evdevcodes.go\", \"The destination file path. Use - for stdout.\")\n\t_ = fs.Parse(os.Args[1:])\n\n\treg, err := regexp.Compile(pattern)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\tcodes := make([][]string, 0)\n\tfor _, src := range *srcs {\n\t\tf, fErr := os.Open(src)\n\t\tif fErr != nil {\n\t\t\tpanic(fErr)\n\t\t}\n\t\tdefer f.Close()\n\n\t\tbf := bufio.NewScanner(f)\n\t\tfor bf.Scan() {\n\t\t\tline := bf.Text()\n\t\t\tmatches := reg.FindAllStringSubmatch(line, -1)\n\t\t\tfor _, match := range matches {\n\t\t\t\tcodes = append(codes, match[1:])\n\t\t\t}\n\t\t}\n\t\tif bf.Err() != nil {\n\t\t\tpanic(bf.Err())\n\t\t}\n\t}\n\n\tun := &sys.Utsname{}\n\tif err = sys.Uname(un); err != nil {\n\t\tpanic(err)\n\t}\n\n\tf := jen.NewFile(\"remouseable\")\n\tf.Comment(\"// Code generated DO NOT EDIT\").Line()\n\tf.Comment(\n\t\tfmt.Sprintf(\n\t\t\t\"// Generated using %s %s %s.\",\n\t\t\tstring(bytes.Trim(un.Sysname[:], \"\\x00\")),\n\t\t\tstring(bytes.Trim(un.Release[:], \"\\x00\")),\n\t\t\tstring(bytes.Trim(un.Machine[:], \"\\x00\")),\n\t\t),\n\t)\n\tf.Comment(\n\t\tfmt.Sprintf(\n\t\t\t\"// Generated at %s.\",\n\t\t\ttime.Now().Format(time.RFC3339),\n\t\t),\n\t)\n\tf.Comment(\n\t\tfmt.Sprintf(\n\t\t\t\"// Generated from %s.\",\n\t\t\tstrings.Join(*srcs, \", \"),\n\t\t),\n\t)\n\n\tkeyMaps := make([]jen.Code, 0)\n\tabsMaps := make([]jen.Code, 0)\n\trelMaps := make([]jen.Code, 0)\n\tswMaps := make([]jen.Code, 0)\n\tmscMaps := make([]jen.Code, 0)\n\tledMaps := make([]jen.Code, 0)\n\tbtnMaps := make([]jen.Code, 0)\n\trepMaps := make([]jen.Code, 0)\n\tsndMaps := make([]jen.Code, 0)\n\tidMaps := make([]jen.Code, 0)\n\tevMaps := make([]jen.Code, 0)\n\tbusMaps := make([]jen.Code, 0)\n\tsynMaps := make([]jen.Code, 0)\n\tffMaps := make([]jen.Code, 0)\n\tdefs := make([]jen.Code, 0, len(codes))\n\tfor _, code := range codes {\n\t\tname := code[0]\n\t\tvalue := code[1]\n\t\tdefs = append(defs, jen.Id(name).Op(\"=\").Id(value))\n\n\t\tif name == \"EV_VERSION\" || strings.HasSuffix(name, \"_MAX\") {\n\t\t\t// EV_VERSION is not a uint16 value and is also not an event type.\n\t\t\t// *_MAX are often duplicated by other named values.\n\t\t\tcontinue\n\t\t}\n\t\tif name == \"BTN_TRIGGER\" || name == \"BTN_SOUTH\" || name == \"BTN_DIGI\" || name == \"BTN_WHEEL\" || name == \"BTN_TRIGGER_HAPPY\" || name == \"BTN_MISC\" || name == \"BTN_MOUSE\" {\n\t\t\t// BTN_TRIGGER is a duplicate of BTN_TASK\n\t\t\t// BTN_SOUTH is a duplicate of BTN_GAMEPAD\n\t\t\t// BTN_DIGI is a duplicate of BTN_TOOL_PEN\n\t\t\t// BTN_WHEEL is a duplicate of BTN_GEAR_DOWN\n\t\t\t// BTN_TRIGGER_HAPPY is a duplicate of BTN_TRIGGER_HAPPY1\n\t\t\t// BTN_MISC is a duplicate of BTN_0\n\t\t\t// BTN_MOUSE is a duplicate of BTN_LEFT\n\t\t\tcontinue\n\t\t}\n\t\tswitch {\n\t\tcase strings.HasPrefix(name, \"KEY\") && !strings.HasPrefix(value, \"KEY\"):\n\t\t\tkeyMaps = append(keyMaps, jen.Id(value).Op(\":\").Lit(name))\n\t\tcase strings.HasPrefix(name, \"ABS\") && !strings.HasPrefix(value, \"ABS\"):\n\t\t\tabsMaps = append(absMaps, jen.Id(value).Op(\":\").Lit(name))\n\t\tcase strings.HasPrefix(name, \"REL\") && !strings.HasPrefix(value, \"REL\"):\n\t\t\trelMaps = append(relMaps, jen.Id(value).Op(\":\").Lit(name))\n\t\tcase strings.HasPrefix(name, \"SW\") && !strings.HasPrefix(value, \"SW\"):\n\t\t\tswMaps = append(swMaps, jen.Id(value).Op(\":\").Lit(name))\n\t\tcase strings.HasPrefix(name, \"MSC\") && !strings.HasPrefix(value, \"MSC\"):\n\t\t\tmscMaps = append(mscMaps, jen.Id(value).Op(\":\").Lit(name))\n\t\tcase strings.HasPrefix(name, \"LED\") && !strings.HasPrefix(value, \"LED\"):\n\t\t\tledMaps = append(ledMaps, jen.Id(value).Op(\":\").Lit(name))\n\t\tcase strings.HasPrefix(name, \"BTN\") && !strings.HasPrefix(value, \"BTN\"):\n\t\t\tbtnMaps = append(btnMaps, jen.Id(value).Op(\":\").Lit(name))\n\t\tcase strings.HasPrefix(name, \"REP\") && !strings.HasPrefix(value, \"REP\"):\n\t\t\trepMaps = append(repMaps, jen.Id(value).Op(\":\").Lit(name))\n\t\tcase strings.HasPrefix(name, \"SND\") && !strings.HasPrefix(value, \"SND\"):\n\t\t\tsndMaps = append(sndMaps, jen.Id(value).Op(\":\").Lit(name))\n\t\tcase strings.HasPrefix(name, \"ID\") && !strings.HasPrefix(value, \"ID\"):\n\t\t\tidMaps = append(idMaps, jen.Id(value).Op(\":\").Lit(name))\n\t\tcase strings.HasPrefix(name, \"EV\") && !strings.HasPrefix(value, \"EV\"):\n\t\t\tevMaps = append(evMaps, jen.Id(value).Op(\":\").Lit(name))\n\t\tcase strings.HasPrefix(name, \"BUS\") && !strings.HasPrefix(value, \"BUS\"):\n\t\t\tbusMaps = append(busMaps, jen.Id(value).Op(\":\").Lit(name))\n\t\tcase strings.HasPrefix(name, \"SYN\") && !strings.HasPrefix(value, \"SYN\"):\n\t\t\tsynMaps = append(synMaps, jen.Id(value).Op(\":\").Lit(name))\n\t\tcase strings.HasPrefix(name, \"FF\") && !strings.HasPrefix(value, \"FF\"):\n\t\t\tffMaps = append(ffMaps, jen.Id(value).Op(\":\").Lit(name))\n\t\t}\n\t}\n\tf.Const().Defs(defs...)\n\tf.Var().Id(\"KEYMap\").Op(\"=\").Map(jen.Uint16()).String().Values(keyMaps...)\n\tf.Var().Id(\"ABSMap\").Op(\"=\").Map(jen.Uint16()).String().Values(absMaps...)\n\tf.Var().Id(\"RELMap\").Op(\"=\").Map(jen.Uint16()).String().Values(relMaps...)\n\tf.Var().Id(\"SWMap\").Op(\"=\").Map(jen.Uint16()).String().Values(swMaps...)\n\tf.Var().Id(\"MSCMap\").Op(\"=\").Map(jen.Uint16()).String().Values(mscMaps...)\n\tf.Var().Id(\"LEDMap\").Op(\"=\").Map(jen.Uint16()).String().Values(ledMaps...)\n\tf.Var().Id(\"BTNMap\").Op(\"=\").Map(jen.Uint16()).String().Values(btnMaps...)\n\tf.Var().Id(\"REPMap\").Op(\"=\").Map(jen.Uint16()).String().Values(repMaps...)\n\tf.Var().Id(\"SNDMap\").Op(\"=\").Map(jen.Uint16()).String().Values(sndMaps...)\n\tf.Var().Id(\"IDMap\").Op(\"=\").Map(jen.Uint16()).String().Values(idMaps...)\n\tf.Var().Id(\"EVMap\").Op(\"=\").Map(jen.Uint16()).String().Values(evMaps...)\n\tf.Var().Id(\"BUSMap\").Op(\"=\").Map(jen.Uint16()).String().Values(busMaps...)\n\tf.Var().Id(\"SYNMap\").Op(\"=\").Map(jen.Uint16()).String().Values(synMaps...)\n\tf.Var().Id(\"FFMap\").Op(\"=\").Map(jen.Uint16()).String().Values(ffMaps...)\n\n\tf.Func().Id(\"CodeString\").Params(jen.Id(\"etype\").Uint16(), jen.Id(\"code\").Uint16()).String().Block(\n\t\tjen.Var().Id(\"stype\").Op(\"=\").Id(\"EVMap\").Index(jen.Id(\"etype\")),\n\t\tjen.Switch(jen.Id(\"stype\")).Block(\n\t\t\tjen.Case(jen.Lit(\"EV_SYN\")).Block(\n\t\t\t\tjen.Return(jen.Id(\"SYNMap\").Index(jen.Id(\"code\"))),\n\t\t\t),\n\t\t\tjen.Case(jen.Lit(\"EV_KEY\")).Block(\n\t\t\t\tjen.Return(jen.Id(\"KEYMap\").Index(jen.Id(\"code\"))),\n\t\t\t),\n\t\t\tjen.Case(jen.Lit(\"EV_ABS\")).Block(\n\t\t\t\tjen.Return(jen.Id(\"ABSMap\").Index(jen.Id(\"code\"))),\n\t\t\t),\n\t\t\tjen.Case(jen.Lit(\"EV_REL\")).Block(\n\t\t\t\tjen.Return(jen.Id(\"RELMap\").Index(jen.Id(\"code\"))),\n\t\t\t),\n\t\t\tjen.Case(jen.Lit(\"EV_SW\")).Block(\n\t\t\t\tjen.Return(jen.Id(\"SWMap\").Index(jen.Id(\"code\"))),\n\t\t\t),\n\t\t\tjen.Case(jen.Lit(\"EV_MSC\")).Block(\n\t\t\t\tjen.Return(jen.Id(\"MSCMap\").Index(jen.Id(\"code\"))),\n\t\t\t),\n\t\t\tjen.Case(jen.Lit(\"EV_LED\")).Block(\n\t\t\t\tjen.Return(jen.Id(\"LEDMap\").Index(jen.Id(\"code\"))),\n\t\t\t),\n\t\t\tjen.Case(jen.Lit(\"EV_SND\")).Block(\n\t\t\t\tjen.Return(jen.Id(\"SNDMap\").Index(jen.Id(\"code\"))),\n\t\t\t),\n\t\t\tjen.Case(jen.Lit(\"EV_REP\")).Block(\n\t\t\t\tjen.Return(jen.Id(\"REPMap\").Index(jen.Id(\"code\"))),\n\t\t\t),\n\t\t\tjen.Case(jen.Lit(\"EV_FF\")).Block(\n\t\t\t\tjen.Return(jen.Id(\"FFMap\").Index(jen.Id(\"code\"))),\n\t\t\t),\n\t\t\tjen.Default().Block(\n\t\t\t\tjen.Return(jen.Lit(\"\")),\n\t\t\t),\n\t\t),\n\t)\n\n\tif *dst == \"-\" {\n\t\tif err = f.Render(os.Stdout); err != nil {\n\t\t\tpanic(err)\n\t\t}\n\t\treturn\n\t}\n\tif err = f.Save(*dst); err != nil {\n\t\tpanic(err)\n\t}\n}\n"
  },
  {
    "path": "pkg/internal/robotgo/base/LICENSE",
    "content": "The software is licensed under the terms of the MIT license.\n\nCopyright 2010 Michael Sanders, AE and the go-vgo Project Developers.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE."
  },
  {
    "path": "pkg/internal/robotgo/base/MMBitmap.h",
    "content": "#pragma once\n#ifndef MMBITMAP_H\n#define MMBITMAP_H\n\n#include \"types.h\"\n#include \"rgb.h\"\n#include <assert.h>\n// #include <stdint.h>\n#if defined(_MSC_VER)\n\t#include \"ms_stdint.h\"\n#else\n\t#include <stdint.h>\n#endif\n\n#ifdef __cplusplus\nextern \"C\"\n{\n#endif\n\nstruct _MMBitmap {\n\tuint8_t *imageBuffer;  /* Pixels stored in Quad I format; i.e., origin is in\n\t                        * top left. Length should be height * bytewidth. */\n\tsize_t width;          /* Never 0, unless image is NULL. */\n\tsize_t height;         /* Never 0, unless image is NULL. */\n\tsize_t bytewidth;      /* The aligned width (width + padding). */\n\tuint8_t bitsPerPixel;  /* Should be either 24 or 32. */\n\tuint8_t bytesPerPixel; /* For convenience; should be bitsPerPixel / 8. */\n};\n\ntypedef struct _MMBitmap MMBitmap;\ntypedef MMBitmap *MMBitmapRef;\n// MMBitmapRef bitmap;\n\n/* Creates new MMBitmap with the given values.\n * Follows the Create Rule (caller is responsible for destroy()'ing object). */\nMMBitmapRef createMMBitmap(uint8_t *buffer, size_t width, size_t height,\n                           size_t bytewidth, uint8_t bitsPerPixel,\n\t\t\t\t\t\t   uint8_t bytesPerPixel);\n\n/* Releases memory occupied by MMBitmap. */\nvoid destroyMMBitmap(MMBitmapRef bitmap);\n\n/* Releases memory occupied by MMBitmap. Acts via CallBack method*/\nvoid destroyMMBitmapBuffer(char * bitmapBuffer, void * hint);\n\n/* Returns copy of MMBitmap, to be destroy()'d by caller. */\nMMBitmapRef copyMMBitmap(MMBitmapRef bitmap);\n\n/* Returns copy of one MMBitmap juxtaposed in another (to be destroy()'d\n * by the caller.), or NULL on error. */\nMMBitmapRef copyMMBitmapFromPortion(MMBitmapRef source, MMRect rect);\n\n#define MMBitmapPointInBounds(image, p) ((p).x < (image)->width && \\\n                                         (p).y < (image)->height)\n#define MMBitmapRectInBounds(image, r)                    \\\n\t(((r).origin.x + (r).size.width <= (image)->width) && \\\n\t ((r).origin.y + (r).size.height <= (image)->height))\n\n#define MMBitmapGetBounds(image) MMRectMake(0, 0, image->width, image->height)\n\n/* Get pointer to pixel of MMBitmapRef. No bounds checking is performed (check\n * yourself before calling this with MMBitmapPointInBounds(). */\n#define MMRGBColorRefAtPoint(image, x, y) \\\n\t(MMRGBColor *)(assert(MMBitmapPointInBounds(image, MMPointMake(x, y))), \\\n\t               ((image)->imageBuffer) + (((image)->bytewidth * (y)) \\\n\t                                      + ((x) * (image)->bytesPerPixel)))\n\n/* Dereference pixel of MMBitmapRef. Again, no bounds checking is performed. */\n#define MMRGBColorAtPoint(image, x, y) *MMRGBColorRefAtPoint(image, x, y)\n\n/* Hex/integer value of color at point. */\n#define MMRGBHexAtPoint(image, x, y) \\\n\thexFromMMRGB(MMRGBColorAtPoint(image, x, y))\n\n/* Increment either point.x or point.y depending on the position of point.x.\n * That is, if x + 1 is >= width, increment y and start x at the beginning.\n * Otherwise, increment x.\n *\n * This is used as a convenience macro to scan rows when calling functions such\n * as findColorInRectAt() and findBitmapInBitmapAt(). */\n#define ITER_NEXT_POINT(pixel, width, start_x) \\\ndo {                                           \\\n  if (++(pixel).x >= (width)) {                \\\n    (pixel).x = start_x;                       \\\n    ++(point).y;                               \\\n  }                                            \\\n} while (0);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* MMBITMAP_H */"
  },
  {
    "path": "pkg/internal/robotgo/base/MMBitmap_c.h",
    "content": "#include \"MMBitmap.h\"\n#include <assert.h>\n#include <string.h>\n\n\n//MMBitmapRef createMMBitmap()\nMMBitmapRef createMMBitmap(\n\tuint8_t *buffer,\n    size_t width,\n    size_t height,\n    size_t bytewidth,\n    uint8_t bitsPerPixel,\n    uint8_t bytesPerPixel\n){\n\tMMBitmapRef bitmap = malloc(sizeof(MMBitmap));\n\tif (bitmap == NULL) return NULL;\n\n\tbitmap->imageBuffer = buffer;\n\tbitmap->width = width;\n\tbitmap->height = height;\n\tbitmap->bytewidth = bytewidth;\n\tbitmap->bitsPerPixel = bitsPerPixel;\n\tbitmap->bytesPerPixel = bytesPerPixel;\n\n\treturn bitmap;\n}\n\nvoid destroyMMBitmap(MMBitmapRef bitmap)\n{\n\tassert(bitmap != NULL);\n\n\tif (bitmap->imageBuffer != NULL) {\n\t\tfree(bitmap->imageBuffer);\n\t\tbitmap->imageBuffer = NULL;\n\t}\n\n\tfree(bitmap);\n}\n\nvoid destroyMMBitmapBuffer(char * bitmapBuffer, void * hint)\n{\n\tif (bitmapBuffer != NULL)\n\t{\n\t\tfree(bitmapBuffer);\n\t}\n}\n\nMMBitmapRef copyMMBitmap(MMBitmapRef bitmap)\n{\n\tuint8_t *copiedBuf = NULL;\n\n\tassert(bitmap != NULL);\n\tif (bitmap->imageBuffer != NULL) {\n\t\tconst size_t bufsize = bitmap->height * bitmap->bytewidth;\n\t\tcopiedBuf = malloc(bufsize);\n\t\tif (copiedBuf == NULL) return NULL;\n\n\t\tmemcpy(copiedBuf, bitmap->imageBuffer, bufsize);\n\t}\n\n\treturn createMMBitmap(copiedBuf,\n\t                      bitmap->width,\n\t                      bitmap->height,\n\t                      bitmap->bytewidth,\n\t                      bitmap->bitsPerPixel,\n\t                      bitmap->bytesPerPixel);\n}\n\nMMBitmapRef copyMMBitmapFromPortion(MMBitmapRef source, MMRect rect)\n{\n\tassert(source != NULL);\n\n\tif (source->imageBuffer == NULL || !MMBitmapRectInBounds(source, rect)) {\n\t\treturn NULL;\n\t} else {\n\t\tuint8_t *copiedBuf = NULL;\n\t\tconst size_t bufsize = rect.size.height * source->bytewidth;\n\t\tconst size_t offset = (source->bytewidth * rect.origin.y) +\n\t\t                      (rect.origin.x * source->bytesPerPixel);\n\n\t\t/* Don't go over the bounds, programmer! */\n\t\tassert((bufsize + offset) <= (source->bytewidth * source->height));\n\n\t\tcopiedBuf = malloc(bufsize);\n\t\tif (copiedBuf == NULL) return NULL;\n\n\t\tmemcpy(copiedBuf, source->imageBuffer + offset, bufsize);\n\n\t\treturn createMMBitmap(copiedBuf,\n\t\t                      rect.size.width,\n\t\t                      rect.size.height,\n\t\t                      source->bytewidth,\n\t\t                      source->bitsPerPixel,\n\t\t                      source->bytesPerPixel);\n\t}\n}\n"
  },
  {
    "path": "pkg/internal/robotgo/base/MMPointArray.h",
    "content": "#pragma once\n#ifndef MMARRAY_H\n#define MMARRAY_H\n\n#include \"types.h\"\n\nstruct _MMPointArray {\n\tMMPoint *array; /* Pointer to actual data. */\n\tsize_t count;   /* Number of elements in array. */\n\tsize_t _allocedCount; /* Private; do not use outside of MMPointArray.c. */\n};\n\ntypedef struct _MMPointArray MMPointArray;\ntypedef MMPointArray *MMPointArrayRef;\n\n/* Creates array of an initial size (the maximum size is still limitless).\n * This follows the \"Create\" Rule; i.e., responsibility for \"destroying\" the\n * array is given to the caller. */\nMMPointArrayRef createMMPointArray(size_t initialCount);\n\n/* Frees memory occupied by |pointArray|. Does not accept NULL. */\nvoid destroyMMPointArray(MMPointArrayRef pointArray);\n\n/* Appends a point to an array, increasing the internal size if necessary. */\nvoid MMPointArrayAppendPoint(MMPointArrayRef pointArray, MMPoint point);\n\n/* Retrieve point from array. */\n#define MMPointArrayGetItem(a, i) ((a)->array)[i]\n\n/* Set point in array. */\n#define MMPointArraySetItem(a, i, item) ((a)->array[i] = item)\n\n#endif /* MMARRAY_H */\n"
  },
  {
    "path": "pkg/internal/robotgo/base/MMPointArray_c.h",
    "content": "#include \"MMPointArray.h\"\n#include <stdlib.h>\n\nMMPointArrayRef createMMPointArray(size_t initialCount)\n{\n\tMMPointArrayRef pointArray = calloc(1, sizeof(MMPointArray));\n\n\tif (initialCount == 0) initialCount = 1;\n\n\tpointArray->_allocedCount = initialCount;\n\tpointArray->array = malloc(pointArray->_allocedCount * sizeof(MMPoint));\n\tif (pointArray->array == NULL) return NULL;\n\n\treturn pointArray;\n}\n\nvoid destroyMMPointArray(MMPointArrayRef pointArray)\n{\n\tif (pointArray->array != NULL) {\n\t\tfree(pointArray->array);\n\t\tpointArray->array = NULL;\n\t}\n\n\tfree(pointArray);\n}\n\nvoid MMPointArrayAppendPoint(MMPointArrayRef pointArray, MMPoint point)\n{\n\tconst size_t newCount = ++(pointArray->count);\n\tif (pointArray->_allocedCount < newCount) {\n\t\tdo {\n\t\t\t/* Double size each time to avoid calls to realloc(). */\n\t\t\tpointArray->_allocedCount <<= 1;\n\t\t} while (pointArray->_allocedCount < newCount);\n\t\tpointArray->array = realloc(pointArray->array,\n\t\t                            sizeof(point) *\n\t\t                            pointArray->_allocedCount);\n\t}\n\n\tpointArray->array[pointArray->count - 1] = point;\n}\n"
  },
  {
    "path": "pkg/internal/robotgo/base/UTHashTable.h",
    "content": "#pragma once\n#ifndef UTHASHTABLE_H\n#define UTHASHTABLE_H\n\n#include <stddef.h>\n#include \"uthash.h\"\n\n/* All node structs must begin with this (note that there is NO semicolon). */\n#define UTHashNode_HEAD UT_hash_handle hh;\n\n/* This file contains convenience macros and a standard struct for working with\n * uthash hash tables.\n *\n * The main purpose of this is for convenience of creating/freeing nodes. */\nstruct _UTHashTable {\n\tvoid *uttable; /* The uthash table -- must start out as NULL. */\n\tvoid *nodes; /* Contiguous array of nodes. */\n\tsize_t allocedNodeCount; /* Node count currently allocated for. */\n\tsize_t nodeCount; /* Current node count. */\n\tsize_t nodeSize; /* Size of each node. */\n};\n\ntypedef struct _UTHashTable UTHashTable;\n\n/* Initiates a hash table to the default values. |table| should point to an\n * already allocated UTHashTable struct.\n *\n * If the |initialCount| argument in initHashTable is given, |nodes| is\n * allocated immediately to the maximum size and new nodes are simply slices of\n * that array. This can save calls to malloc if many nodes are to be added, and\n * the a reasonable maximum number is known ahead of time.\n *\n * If the node count goes over this maximum, or if |initialCount| is 0, the\n * array is dynamically reallocated to fit the size.\n */\nvoid initHashTable(UTHashTable *table, size_t initialCount, size_t nodeSize);\n\n/* Frees memory occupied by a UTHashTable's members.\n *\n * Note that this does NOT free memory for the UTHashTable pointed to by\n * |table| itself; if that was allocated on the heap, you must free() it\n * yourself after calling this. */\nvoid destroyHashTable(UTHashTable *table);\n\n/* Returns memory allocated for a new node. Responsibility for freeing this is\n * up to the destroyHashTable() macro; this should NOT be freed by the caller.\n *\n * This is intended to be used with a HASH_ADD() macro, e.g.:\n * {%\n *     struct myNode *uttable = utHashTable->uttable;\n *     struct myNode *node = getNewNode(utHashTable);\n *     node->key = 42;\n *     node->value = someValue;\n *     HASH_ADD_INT(uttable, key, node);\n *     utHashTable->uttable = uttable;\n * %}\n *\n * Or, use the UTHASHTABLE_ADD_INT or UTHASHTABLE_ADD_STR macros\n * for convenience (they are exactly equivalent):\n * {%\n *     struct myNode *node = getNewNode(utHashTable);\n *     node->key = 42;\n *     node->value = someValue;\n *     UTHASHTABLE_ADD_INT(utHashTable, key, node, struct myNode);\n * %}\n */\nvoid *getNewNode(UTHashTable *table);\n\n#define UTHASHTABLE_ADD_INT(tablePtr, keyName, node, nodeType) \\\ndo {                                       \\\n  nodeType *uttable = (tablePtr)->uttable; \\\n  HASH_ADD_INT(uttable, keyName, node);    \\\n  (tablePtr)->uttable = uttable;           \\\n} while (0)\n\n#define UTHASHTABLE_ADD_STR(tablePtr, keyName, node, nodeType) \\\ndo {                                       \\\n  nodeType *uttable = (tablePtr)->uttable; \\\n  HASH_ADD_STR(uttable, keyName, node);    \\\n  (tablePtr)->uttable = uttable;           \\\n} while (0)\n\n#endif /* MMHASHTABLE_H */\n"
  },
  {
    "path": "pkg/internal/robotgo/base/UTHashTable_c.h",
    "content": "#include \"UTHashTable.h\"\n#include <stdlib.h>\n#include <assert.h>\n\n/* Base struct class (all nodes must contain at least the elements in\n * this struct). */\nstruct _UTHashNode {\n\tUTHashNode_HEAD\n};\n\ntypedef struct _UTHashNode UTHashNode;\n\nvoid initHashTable(UTHashTable *table, size_t initialCount, size_t nodeSize)\n{\n\tassert(table != NULL);\n\tassert(nodeSize >= sizeof(UTHashNode));\n\n\ttable->uttable = NULL; /* Must be set to NULL for uthash. */\n\ttable->allocedNodeCount = (initialCount == 0) ? 1 : initialCount;\n\ttable->nodeCount = 0;\n\ttable->nodeSize = nodeSize;\n\ttable->nodes = calloc(table->nodeSize, nodeSize * table->allocedNodeCount);\n}\n\nvoid destroyHashTable(UTHashTable *table)\n{\n\tUTHashNode *uttable = table->uttable;\n\tUTHashNode *node;\n\n\t/* Let uthash do its magic. */\n\twhile (uttable != NULL) {\n\t\tnode = uttable; /* Grab pointer to first item. */\n\t\tHASH_DEL(uttable, node); /* Delete it (table advances to next). */\n\t}\n\n\t/* Only giant malloc'd block containing each node must be freed. */\n\tif (table->nodes != NULL) free(table->nodes);\n\ttable->uttable = table->nodes = NULL;\n}\n\nvoid *getNewNode(UTHashTable *table)\n{\n\t/* Increment node count, resizing table if necessary. */\n\tconst size_t newNodeCount = ++(table->nodeCount);\n\tif (table->allocedNodeCount < newNodeCount) {\n\t\tdo {\n\t\t\t/* Double size each time to avoid calls to realloc(). */\n\t\t\ttable->allocedNodeCount <<= 1;\n\t\t} while (table->allocedNodeCount < newNodeCount);\n\n\t\ttable->nodes = realloc(table->nodes, table->nodeSize *\n\t\t                                     table->allocedNodeCount);\n\t}\n\n\treturn (char *)table->nodes + (table->nodeSize * (table->nodeCount - 1));\n}\n"
  },
  {
    "path": "pkg/internal/robotgo/base/base64.c",
    "content": "#include \"base64.h\"\n#include <string.h>\n#include <stdlib.h>\n#include <stdio.h>\n#include <assert.h>\n\n/* Encoding table as described in RFC1113. */\nconst static uint8_t b64_encode_table[] =\n\t\"ABCDEFGHIJKLMNOPQRSTUVWXYZ\"\n\t\"abcdefghijklmnopqrstuvwxyz0123456789+/\";\n\n/* Decoding table. */\nconst static int8_t b64_decode_table[256] = {\n\t-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\t/* 00-0F */\n\t-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\t/* 10-1F */\n\t-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,\t/* 20-2F */\n\t52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1,\t/* 30-3F */\n\t-1,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, /* 40-4F */\n\t15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,\t/* 50-5F */\n\t-1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,\t/* 60-6F */\n\t41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1,\t/* 70-7F */\n\t-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\t/* 80-8F */\n\t-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\t/* 90-9F */\n\t-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\t/* A0-AF */\n\t-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\t/* B0-BF */\n\t-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\t/* C0-CF */\n\t-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\t/* D0-DF */\n\t-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\t/* E0-EF */\n\t-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1\t/* F0-FF */\n};\n\nuint8_t *base64decode(const uint8_t *src, const size_t buflen, size_t *retlen){\n\tint8_t digit, lastdigit;\n\tsize_t i, j;\n\tuint8_t *decoded;\n\tconst size_t maxlen = ((buflen + 3) / 4) * 3;\n\n\t/* Sanity check */\n\tassert(src != NULL);\n\n\tdigit = lastdigit = j = 0;\n\tdecoded = malloc(maxlen + 1);\n\tif (decoded == NULL) return NULL;\n\tfor (i = 0; i < buflen; ++i) {\n\t\tif ((digit = b64_decode_table[src[i]]) != -1) {\n\t\t\t/* Decode block */\n\t\t\tswitch (i % 4) {\n\t\t\t\tcase 1:\n\t\t\t\t\tdecoded[j++] = ((lastdigit << 2) | ((digit & 0x30) >> 4));\n\t\t\t\t\tbreak;\n\t\t\t\tcase 2:\n\t\t\t\t\tdecoded[j++] = (((lastdigit & 0xF) << 4) | ((digit & 0x3C) >> 2));\n\t\t\t\t\tbreak;\n\t\t\t\tcase 3:\n\t\t\t\t\tdecoded[j++] = (((lastdigit & 0x03) << 6) | digit);\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\tlastdigit = digit;\n\t\t}\n\t}\n\n\tif (retlen != NULL) *retlen = j;\n\tdecoded[j] = '\\0';\n\treturn decoded; /* Must be free()'d by caller */\n}\n\nuint8_t *base64encode(const uint8_t *src, const size_t buflen, size_t *retlen){\n\tsize_t i, j;\n\tconst size_t maxlen = (((buflen + 3) & ~3)) * 4;\n\tuint8_t *encoded = malloc(maxlen + 1);\n\tif (encoded == NULL) return NULL;\n\n\t/* Sanity check */\n\tassert(src != NULL);\n\tassert(buflen > 0);\n\n\tj = 0;\n\tfor (i = 0; i < buflen + 1; ++i) {\n\t\t/* Encode block */\n\t\tswitch (i % 3) {\n\t\t\tcase 0:\n\t\t\t\tencoded[j++] = b64_encode_table[src[i] >> 2];\n\t\t\t\tencoded[j++] = b64_encode_table[((src[i] & 0x03) << 4) |\n\t\t\t\t                                ((src[i + 1] & 0xF0) >> 4)];\n\t\t\t\tbreak;\n\t\t\tcase 1:\n\t\t\t\tencoded[j++] = b64_encode_table[((src[i] & 0x0F) << 2) |\n\t\t\t\t                                ((src[i + 1] & 0xC0) >> 6)];\n\t\t\t\tbreak;\n\t\t\tcase 2:\n\t\t\t\tencoded[j++] = b64_encode_table[(src[i] & 0x3F)];\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\t/* Add padding if necessary */\n\tif ((j % 4) != 0) {\n\t\tconst size_t with_padding = ((j + 3) & ~3); /* Align to 4 bytes */\n\t\tdo {\n\t\t\tencoded[j++] = '=';\n\t\t} while (j < with_padding);\n\t}\n\n\tassert(j <= maxlen);\n\n\tif (retlen != NULL) *retlen = j;\n\tencoded[j] = '\\0';\n\treturn encoded; /* Must be free()'d by caller */\n}\n"
  },
  {
    "path": "pkg/internal/robotgo/base/base64.h",
    "content": "#pragma once\n#ifndef BASE64_H\n#define BASE64_H\n\n#include <stddef.h>\n\n#if defined(_MSC_VER)\n\t#include \"ms_stdint.h\"\n#else\n\t#include <stdint.h>\n#endif\n\n/* Decode a base64 encoded string discarding line breaks and noise.\n *\n * Returns a new string to be free()'d by caller, or NULL on error.\n * Returned string is guaranteed to be NUL-terminated.\n *\n * If |retlen| is not NULL, it is set to the length of the returned string\n * (minus the NUL-terminator) on successful return. */\nuint8_t *base64decode(const uint8_t *buf, const size_t buflen, size_t *retlen);\n\n/* Encode a base64 encoded string without line breaks or noise.\n *\n * Returns a new string to be free()'d by caller, or NULL on error.\n * Returned string is guaranteed to be NUL-terminated with the correct padding.\n *\n * If |retlen| is not NULL, it is set to the length of the returned string\n * (minus the NUL-terminator) on successful return. */\nuint8_t *base64encode(const uint8_t *buf, const size_t buflen, size_t *retlen);\n\n#endif /* BASE64_H */\n"
  },
  {
    "path": "pkg/internal/robotgo/base/base64_c.h",
    "content": "#include \"base64.h\"\n#include <string.h>\n#include <stdlib.h>\n#include <stdio.h>\n#include <assert.h>\n\n/* Encoding table as described in RFC1113. */\nconst static uint8_t b64_encode_table[] =\n\t\"ABCDEFGHIJKLMNOPQRSTUVWXYZ\"\n\t\"abcdefghijklmnopqrstuvwxyz0123456789+/\";\n\n/* Decoding table. */\nconst static int8_t b64_decode_table[256] = {\n\t-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\t/* 00-0F */\n\t-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\t/* 10-1F */\n\t-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,\t/* 20-2F */\n\t52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1,\t/* 30-3F */\n\t-1,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, /* 40-4F */\n\t15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,\t/* 50-5F */\n\t-1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,\t/* 60-6F */\n\t41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1,\t/* 70-7F */\n\t-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\t/* 80-8F */\n\t-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\t/* 90-9F */\n\t-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\t/* A0-AF */\n\t-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\t/* B0-BF */\n\t-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\t/* C0-CF */\n\t-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\t/* D0-DF */\n\t-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\t/* E0-EF */\n\t-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1\t/* F0-FF */\n};\n\nuint8_t *base64decode(const uint8_t *src, const size_t buflen, size_t *retlen)\n{\n\tint8_t digit, lastdigit;\n\tsize_t i, j;\n\tuint8_t *decoded;\n\tconst size_t maxlen = ((buflen + 3) / 4) * 3;\n\n\t/* Sanity check */\n\tassert(src != NULL);\n\n\tdigit = lastdigit = j = 0;\n\tdecoded = malloc(maxlen + 1);\n\tif (decoded == NULL) return NULL;\n\tfor (i = 0; i < buflen; ++i) {\n\t\tif ((digit = b64_decode_table[src[i]]) != -1) {\n\t\t\t/* Decode block */\n\t\t\tswitch (i % 4) {\n\t\t\t\tcase 1:\n\t\t\t\t\tdecoded[j++] = ((lastdigit << 2) | ((digit & 0x30) >> 4));\n\t\t\t\t\tbreak;\n\t\t\t\tcase 2:\n\t\t\t\t\tdecoded[j++] = (((lastdigit & 0xF) << 4) | ((digit & 0x3C) >> 2));\n\t\t\t\t\tbreak;\n\t\t\t\tcase 3:\n\t\t\t\t\tdecoded[j++] = (((lastdigit & 0x03) << 6) | digit);\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\tlastdigit = digit;\n\t\t}\n\t}\n\n\tif (retlen != NULL) *retlen = j;\n\tdecoded[j] = '\\0';\n\treturn decoded; /* Must be free()'d by caller */\n}\n\nuint8_t *base64encode(const uint8_t *src, const size_t buflen, size_t *retlen)\n{\n\tsize_t i, j;\n\tconst size_t maxlen = (((buflen + 3) & ~3)) * 4;\n\tuint8_t *encoded = malloc(maxlen + 1);\n\tif (encoded == NULL) return NULL;\n\n\t/* Sanity check */\n\tassert(src != NULL);\n\tassert(buflen > 0);\n\n\tj = 0;\n\tfor (i = 0; i < buflen + 1; ++i) {\n\t\t/* Encode block */\n\t\tswitch (i % 3) {\n\t\t\tcase 0:\n\t\t\t\tencoded[j++] = b64_encode_table[src[i] >> 2];\n\t\t\t\tencoded[j++] = b64_encode_table[((src[i] & 0x03) << 4) |\n\t\t\t\t                                ((src[i + 1] & 0xF0) >> 4)];\n\t\t\t\tbreak;\n\t\t\tcase 1:\n\t\t\t\tencoded[j++] = b64_encode_table[((src[i] & 0x0F) << 2) |\n\t\t\t\t                                ((src[i + 1] & 0xC0) >> 6)];\n\t\t\t\tbreak;\n\t\t\tcase 2:\n\t\t\t\tencoded[j++] = b64_encode_table[(src[i] & 0x3F)];\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\t/* Add padding if necessary */\n\tif ((j % 4) != 0) {\n\t\tconst size_t with_padding = ((j + 3) & ~3); /* Align to 4 bytes */\n\t\tdo {\n\t\t\tencoded[j++] = '=';\n\t\t} while (j < with_padding);\n\t}\n\n\tassert(j <= maxlen);\n\n\tif (retlen != NULL) *retlen = j;\n\tencoded[j] = '\\0';\n\treturn encoded; /* Must be free()'d by caller */\n}\n"
  },
  {
    "path": "pkg/internal/robotgo/base/bmp_io.h",
    "content": "#pragma once\n#ifndef BMP_IO_H\n#define BMP_IO_H\n\n#include \"MMBitmap.h\"\n#include \"file_io.h\"\n\nenum _BMPReadError {\n\tkBMPGenericError = 0,\n\tkBMPAccessError,\n\tkBMPInvalidKeyError,\n\tkBMPUnsupportedHeaderError,\n\tkBMPInvalidColorPanesError,\n\tkBMPUnsupportedColorDepthError,\n\tkBMPUnsupportedCompressionError,\n\tkBMPInvalidPixelDataError\n};\n\ntypedef MMIOError MMBMPReadError;\n\n/* Returns description of given MMBMPReadError.\n * Returned string is constant and hence should not be freed. */\nconst char *MMBMPReadErrorString(MMIOError error);\n\n/* Attempts to read bitmap file at path; returns new MMBitmap on success, or\n * NULL on error. If |error| is non-NULL, it will be set to the error code\n * on return.\n *\n * Currently supports:\n *     - Uncompressed Windows v3/v4/v5 24-bit or 32-bit BMP.\n *     - OS/2 v1 or v2 24-bit BMP.\n *     - Does NOT yet support: 1-bit, 4-bit, 8-bit, 16-bit, compressed bitmaps,\n *       or PNGs/JPEGs disguised as BMPs (and returns NULL if those are given).\n *\n * Responsibility for destroy()'ing returned MMBitmap is left up to caller. */\nMMBitmapRef newMMBitmapFromBMP(const char *path, MMBMPReadError *error);\n\n/* Returns a buffer containing the raw BMP file data in Windows v3 BMP format,\n * ready to be saved to a file. If |len| is not NULL, it will be set to the\n * number of bytes allocated in the returned buffer.\n *\n * Responsibility for free()'ing data is left up to the caller. */\nuint8_t *createBitmapData(MMBitmapRef bitmap, size_t *len);\n\n/* Saves bitmap to file in Windows v3 BMP format.\n * Returns 0 on success, -1 on error. */\nint saveMMBitmapAsBMP(MMBitmapRef bitmap, const char *path);\n\n/* Swaps bitmap from Quadrant 1 to Quadran III format, or vice versa\n * (upside-down Cartesian/PostScript/GL <-> right side up QD/CG raster format).\n */\nvoid flipBitmapData(void *data, size_t width, size_t height, size_t bytewidth);\n\n#endif /* BMP_IO_H */\n"
  },
  {
    "path": "pkg/internal/robotgo/base/bmp_io_c.h",
    "content": "#include \"bmp_io.h\"\n#include \"os.h\"\n#include \"endian.h\"\n#include <stdio.h> /* fopen() */\n#include <string.h> /* memcpy() */\n\n#if defined(_MSC_VER)\n\t#include \"ms_stdbool.h\"\n\t#include \"ms_stdint.h\"\n#else\n\t#include <stdbool.h>\n\t#include <stdint.h>\n#endif\n\n#pragma pack(push, 1) /* The following structs should be continguous, so we can\n                       * copy them in one read. */\n/*\n * Standard, initial BMP Header\n */\nstruct BITMAP_FILE_HEADER {\n\tuint16_t magic;       /* First two byes of the file; should be 0x4D42. */\n\tuint32_t fileSize;    /* Size of the BMP file in bytes (unreliable). */\n\tuint32_t reserved;    /* Application-specific. */\n\tuint32_t imageOffset; /* Offset to bitmap data. */\n};\n\n#define BMP_MAGIC 0x4D42 /* The starting key that marks the file as a BMP. */\n\nenum _BMP_COMPRESSION {\n\tkBMP_RGB = 0, /* No compression. */\n\tkBMP_RLE8 = 1, /* Can only be used with 8-bit bitmaps. */\n\tkBMP_RLE4 = 2, /* Can only be used with 4-bit bitmaps. */\n\tkBMP_BITFIELDS = 3, /* Can only be used with 16/32-bit bitmaps. */\n\tkBMP_JPEG = 4, /* Bitmap contains a JPEG image. */\n\tkBMP_PNG = 5 /* Bitmap contains a PNG image. */\n};\n\ntypedef uint32_t BMP_COMPRESSION;\n\n/*\n * Windows 3 Header\n */\nstruct BITMAP_INFO_HEADER {\n\tuint32_t headerSize;         /* The size of this header (40 bytes). */\n\tint32_t width;               /* The bitmap width in pixels. */\n\tint32_t height;              /* The bitmap height in pixels. */\n\t                             /* (A negative value denotes that the image\n\t\t\t\t\t\t\t\t  * is flipped.) */\n\tuint16_t colorPlanes;        /* The number of color planes; must be 1. */\n\tuint16_t bitsPerPixel;       /* The color depth of the image (1, 4, 8, 16,\n\t                              * 24, or 32). */\n\tBMP_COMPRESSION compression; /* The compression method being used. */\n\tuint32_t imageSize;          /* Size of the bitmap in bytes (unreliable).*/\n\tint32_t xRes;                /* The horizontal resolution (unreliable). */\n\tint32_t yRes;                /* The vertical resolution (unreliable). */\n\tuint32_t colorsUsed;         /* The number of colors in the color table,\n\t                              * or 0 to default to 2^n. */\n\tuint32_t colorsImportant;    /* Colors important for displaying bitmap,\n\t                              * or 0 when every color is equally important;\n\t                              * ignored. */\n};\n\n/*\n * OS/2 v1 Header\n */\nstruct BITMAP_CORE_HEADER {\n\tuint32_t headerSize;   /* The size of this header (12 bytes). */\n\tuint16_t width;        /* The bitmap width in pixels. */\n\tuint16_t height;       /* The bitmap height in pixels. */\n\tuint16_t colorPlanes;  /* The number of color planes; must be 1. */\n\tuint16_t bitsPerPixel; /* Color depth of the image (1, 4, 8, or 24). */\n};\n\n#pragma pack(pop) /* Let the compiler do what it wants now. */\n\n/* BMP files are always saved in little endian format (x86), so we need to\n * convert them if we're not on a little endian machine (e.g., ARM & ppc). */\n\n#if __BYTE_ORDER == __BIG_ENDIAN\n\n/* Converts bitmap file header from to and from little endian, if and only if\n * host is big endian. */\nstatic void convertBitmapFileHeader(struct BITMAP_FILE_HEADER *header)\n{\n\theader->magic = swapLittleAndHost16(header->magic);\n\tswapLittleAndHost32(header->fileSize);\n\tswapLittleAndHost32(header->reserved);\n\tswapLittleAndHost32(header->imageOffset);\n}\n\n/* Converts bitmap info header from to and from little endian, if and only if\n * host is big endian. */\nstatic void convertBitmapInfoHeader(struct BITMAP_INFO_HEADER *header)\n{\n\theader->headerSize = swapLittleAndHost32(header->headerSize);\n\theader->width = swapLittleAndHost32(header->width);\n\theader->height = swapLittleAndHost32(header->height);\n\theader->colorPlanes = swapLittleAndHost16(header->colorPlanes);\n\theader->bitsPerPixel = swapLittleAndHost16(header->bitsPerPixel);\n\theader->compression = swapLittleAndHost32(header->compression);\n\theader->imageSize = swapLittleAndHost32(header->imageSize);\n\theader->xRes = swapLittleAndHost32(header->xRes);\n\theader->yRes = swapLittleAndHost32(header->yRes);\n\theader->colorsUsed = swapLittleAndHost32(header->colorsUsed);\n\theader->colorsImportant = swapLittleAndHost32(header->colorsImportant);\n}\n\n#elif __BYTE_ORDER == __LITTLE_ENDIAN\n\t/* No conversion necessary if we are already little endian. */\n\t#define convertBitmapFileHeader(header)\n\t#define convertBitmapInfoHeader(header)\n#endif\n\n/* Returns newly alloc'd image data from bitmap file. The current position of\n * the file must be at the start of the image before calling this. */\nstatic uint8_t *readImageData(FILE *fp, size_t width, size_t height,\n                              uint8_t bytesPerPixel, size_t bytewidth);\n\n/* Copys image buffer from |bitmap| to |dest| in BGR format. */\nstatic void copyBGRDataFromMMBitmap(MMBitmapRef bitmap, uint8_t *dest);\n\nconst char *MMBMPReadErrorString(MMIOError error)\n{\n\tswitch (error) {\n\t\tcase kBMPAccessError:\n\t\t\treturn \"Could not open file\";\n\t\tcase kBMPInvalidKeyError:\n\t\t\treturn \"Not a BMP file\";\n\t\tcase kBMPUnsupportedHeaderError:\n\t\t\treturn \"Unsupported BMP header\";\n\t\tcase kBMPInvalidColorPanesError:\n\t\t\treturn \"Invalid number of color panes in BMP file\";\n\t\tcase kBMPUnsupportedColorDepthError:\n\t\t\treturn \"Unsupported color depth in BMP file\";\n\t\tcase kBMPUnsupportedCompressionError:\n\t\t\treturn \"Unsupported file compression in BMP file\";\n\t\tcase kBMPInvalidPixelDataError:\n\t\t\treturn \"Could not read BMP pixel data\";\n\t\tdefault:\n\t\t\treturn NULL;\n\t}\n}\n\nMMBitmapRef newMMBitmapFromBMP(const char *path, MMBMPReadError *err)\n{\n\tFILE *fp;\n\tstruct BITMAP_FILE_HEADER fileHeader = {0}; /* Initialize elements to 0. */\n\tstruct BITMAP_INFO_HEADER dibHeader = {0};\n\tuint32_t headerSize = 0;\n\tuint8_t bytesPerPixel;\n\tsize_t bytewidth;\n\tuint8_t *imageBuf;\n\n\tif ((fp = fopen(path, \"rb\")) == NULL) {\n\t\tif (err != NULL) *err = kBMPAccessError;\n\t\treturn NULL;\n\t}\n\n\t/* Initialize error code to generic value. */\n\tif (err != NULL) *err = kBMPGenericError;\n\n\tif (fread(&fileHeader, sizeof(fileHeader), 1, fp) == 0) goto bail;\n\n\t/* Convert from little-endian if it's not already. */\n\tconvertBitmapFileHeader(&fileHeader);\n\n\t/* First two bytes should always be 0x4D42. */\n\tif (fileHeader.magic != BMP_MAGIC) {\n\t\tif (err != NULL) *err = kBMPInvalidKeyError;\n\t\tgoto bail;\n\t}\n\n\t/* Get header size. */\n\tif (fread(&headerSize, sizeof(headerSize), 1, fp) == 0) goto bail;\n\theaderSize = swapLittleAndHost32(headerSize);\n\n\t/* Back up before reading header. */\n\tif (fseek(fp, -(long)sizeof(headerSize), SEEK_CUR) < 0) goto bail;\n\n\tif (headerSize == 12) { /* OS/2 v1 header */\n\t\tstruct BITMAP_CORE_HEADER coreHeader = {0};\n\t\tif (fread(&coreHeader, sizeof(coreHeader), 1, fp) == 0) goto bail;\n\n\t\tdibHeader.width = coreHeader.width;\n\t\tdibHeader.height = coreHeader.height;\n\t\tdibHeader.colorPlanes = coreHeader.colorPlanes;\n\t\tdibHeader.bitsPerPixel = coreHeader.bitsPerPixel;\n\t} else if (headerSize == 40 || headerSize == 108 || headerSize == 124) {\n\t\t/* Windows v3/v4/v5 header */\n\t\t/* Read only the common part (v3) and skip over the rest. */\n\t\tif (fread(&dibHeader, sizeof(dibHeader), 1, fp) == 0) goto bail;\n\t} else {\n\t\tif (err != NULL) *err = kBMPUnsupportedHeaderError;\n\t\tgoto bail;\n\t}\n\n\tconvertBitmapInfoHeader(&dibHeader);\n\n\tif (dibHeader.colorPlanes != 1) {\n\t\tif (err != NULL) *err = kBMPInvalidColorPanesError;\n\t\tgoto bail;\n\t}\n\n\t/* Currently only 24-bit and 32-bit are supported. */\n\tif (dibHeader.bitsPerPixel != 24 && dibHeader.bitsPerPixel != 32) {\n\t\tif (err != NULL) *err = kBMPUnsupportedColorDepthError;\n\t\tgoto bail;\n\t}\n\n\tif (dibHeader.compression != kBMP_RGB) {\n\t\tif (err != NULL) *err = kBMPUnsupportedCompressionError;\n\t\tgoto bail;\n\t}\n\n\t/* This can happen because we don't fully parse Windows v4/v5 headers. */\n\tif (ftell(fp) != (long)fileHeader.imageOffset) {\n\t\tfseek(fp, fileHeader.imageOffset, SEEK_SET);\n\t}\n\n\t/* Get bytes per row, including padding. */\n\tbytesPerPixel = dibHeader.bitsPerPixel / 8;\n\tbytewidth = ADD_PADDING(dibHeader.width * bytesPerPixel);\n\n\timageBuf = readImageData(fp, dibHeader.width, abs(dibHeader.height),\n\t                         bytesPerPixel, bytewidth);\n\tfclose(fp);\n\n\tif (imageBuf == NULL) {\n\t\tif (err != NULL) *err = kBMPInvalidPixelDataError;\n\t\treturn NULL;\n\t}\n\n\t/* A negative height indicates that the image is flipped.\n\t *\n\t * We store our bitmaps as \"flipped\" according to the BMP format; i.e., (0, 0)\n\t * is the top left, not bottom left. So we only need to flip the bitmap if\n\t * the height is NOT negative. */\n\tif (dibHeader.height < 0) {\n\t\tdibHeader.height = -dibHeader.height;\n\t} else {\n\t\tflipBitmapData(imageBuf, dibHeader.width, dibHeader.height, bytewidth);\n\t}\n\n\treturn createMMBitmap(imageBuf, dibHeader.width, dibHeader.height,\n\t                      bytewidth, (uint8_t)dibHeader.bitsPerPixel,\n\t                      bytesPerPixel);\n\nbail:\n\tfclose(fp);\n\treturn NULL;\n}\n\nuint8_t *createBitmapData(MMBitmapRef bitmap, size_t *len)\n{\n\t/* BMP files are always aligned to 4 bytes. */\n\tconst size_t bytewidth = ((bitmap->width * bitmap->bytesPerPixel) + 3) & ~3;\n\n\tconst size_t imageSize = bytewidth * bitmap->height;\n\tstruct BITMAP_FILE_HEADER *fileHeader;\n\tstruct BITMAP_INFO_HEADER *dibHeader;\n\n\t/* Should always be 54. */\n\tconst size_t imageOffset = sizeof(*fileHeader) + sizeof(*dibHeader);\n\tuint8_t *data;\n\tconst size_t dataLen = imageOffset + imageSize;\n\n\tdata = calloc(1, dataLen);\n\tif (data == NULL) return NULL;\n\n\t/* Save top header. */\n\tfileHeader = (struct BITMAP_FILE_HEADER *)data;\n\tfileHeader->magic = BMP_MAGIC;\n\tfileHeader->fileSize = (uint32_t)(sizeof(*dibHeader) + imageSize);\n\tfileHeader->imageOffset = (uint32_t)imageOffset;\n\n\t/* BMP files are always stored as little-endian, so we need to convert back\n\t * if necessary. */\n\tconvertBitmapFileHeader(fileHeader);\n\n\t/* Copy Windows v3 header. */\n\tdibHeader = (struct BITMAP_INFO_HEADER *)(data + sizeof(*fileHeader));\n\tdibHeader->headerSize = sizeof(*dibHeader); /* Should always be 40. */\n\tdibHeader->width = (int32_t)bitmap->width;\n\tdibHeader->height = -(int32_t)bitmap->height; /* Our bitmaps are \"flipped\". */\n\tdibHeader->colorPlanes = 1;\n\tdibHeader->bitsPerPixel = bitmap->bitsPerPixel;\n\tdibHeader->compression = kBMP_RGB; /* Don't save with compression. */\n\tdibHeader->imageSize = (uint32_t)imageSize;\n\n\tconvertBitmapInfoHeader(dibHeader);\n\n\t/* Lastly, copy the pixel data. */\n\tcopyBGRDataFromMMBitmap(bitmap, data + imageOffset);\n\n\tif (len != NULL) *len = dataLen;\n\treturn data;\n}\n\nint saveMMBitmapAsBMP(MMBitmapRef bitmap, const char *path)\n{\n\tFILE *fp;\n\tsize_t dataLen;\n\tuint8_t *data;\n\n\tif ((fp = fopen(path, \"wb\")) == NULL) return -1;\n\n\tif ((data = createBitmapData(bitmap, &dataLen)) == NULL) {\n\t\tfclose(fp);\n\t\treturn -1;\n\t}\n\n\tif (fwrite(data, dataLen, 1, fp) == 0) {\n\t\tfree(data);\n\t\tfclose(fp);\n\t\treturn -1;\n\t}\n\n\tfree(data);\n\tfclose(fp);\n\treturn 0;\n}\n\nuint8_t *saveMMBitmapAsBytes(MMBitmapRef bitmap, size_t *dataLen)\n{\n\tuint8_t *data;\n\tif ((data = createBitmapData(bitmap, dataLen)) == NULL) {\n\t\t*dataLen = -1;\n\t\treturn NULL;\n\t}\n\treturn data;\n}\n\nstatic uint8_t *readImageData(FILE *fp, size_t width, size_t height,\n                              uint8_t bytesPerPixel, size_t bytewidth)\n{\n\tsize_t imageSize = bytewidth * height;\n\tuint8_t *imageBuf = calloc(1, imageSize);\n\n\tif (MMRGB_IS_BGR && (bytewidth % 4) == 0) { /* No conversion needed. */\n\t\tif (fread(imageBuf, imageSize, 1, fp) == 0) {\n\t\t\tfree(imageBuf);\n\t\t\treturn NULL;\n\t\t}\n\t} else { /* Convert from BGR with 4-byte alignment. */\n\t\tuint8_t *row = malloc(bytewidth);\n\t\tsize_t y;\n\t\tconst size_t bmp_bytewidth = (width * bytesPerPixel + 3) & ~3;\n\n\t\tif (row == NULL) return NULL;\n\t\tassert(bmp_bytewidth <= bytewidth);\n\n\t\t/* Read image data row by row. */\n\t\tfor (y = 0; y < height; ++y) {\n\t\t\tconst size_t rowOffset = y * bytewidth;\n\t\t\tsize_t x;\n\t\t\tuint8_t *rowptr = row;\n\t\t\tif (fread(row, bmp_bytewidth, 1, fp) == 0) {\n\t\t\t\tfree(imageBuf);\n\t\t\t\tfree(row);\n\t\t\t\treturn NULL;\n\t\t\t}\n\n\t\t\tfor (x = 0; x < width; ++x) {\n\t\t\t\tconst size_t colOffset = x * bytesPerPixel;\n\t\t\t\tMMRGBColor *color = (MMRGBColor *)(imageBuf +\n\t\t\t\t                                   rowOffset + colOffset);\n\n\t\t\t\t/* BMP files are stored in BGR format. */\n\t\t\t\tcolor->blue = rowptr[0];\n\t\t\t\tcolor->green = rowptr[1];\n\t\t\t\tcolor->red = rowptr[2];\n\t\t\t\trowptr += bytesPerPixel;\n\t\t\t}\n\t\t}\n\n\t\tfree(row);\n\t}\n\n\treturn imageBuf;\n}\n\nstatic void copyBGRDataFromMMBitmap(MMBitmapRef bitmap, uint8_t *dest)\n{\n\tif (MMRGB_IS_BGR && (bitmap->bytewidth % 4) == 0) { /* No conversion needed. */\n\t\tmemcpy(dest, bitmap->imageBuffer, bitmap->bytewidth * bitmap->height);\n\t} else { /* Convert to RGB with other-than-4-byte alignment. */\n\t\tconst size_t bytewidth = (bitmap->width * bitmap->bytesPerPixel + 3) & ~3;\n\t\tsize_t y;\n\n\t\t/* Copy image data row by row. */\n\t\tfor (y = 0; y < bitmap->height; ++y) {\n\t\t\tuint8_t *rowptr = dest + (y * bytewidth);\n\t\t\tsize_t x;\n\t\t\tfor (x = 0; x < bitmap->width; ++x) {\n\t\t\t\tMMRGBColor *color = MMRGBColorRefAtPoint(bitmap, x, y);\n\n\t\t\t\t/* BMP files are stored in BGR format. */\n\t\t\t\trowptr[0] = color->blue;\n\t\t\t\trowptr[1] = color->green;\n\t\t\t\trowptr[2] = color->red;\n\n\t\t\t\trowptr += bitmap->bytesPerPixel;\n\t\t\t}\n\t\t}\n\t}\n}\n\n/* Perform an in-place swap from Quadrant 1 to Quadrant III format (upside-down\n * PostScript/GL to right side up QD/CG raster format) We do this in-place,\n * which requires more copying, but will touch only half the pages.\n *\n * This is blatantly copied from Apple's glGrab example code. */\nvoid flipBitmapData(void *data, size_t width, size_t height, size_t bytewidth)\n{\n\tsize_t top, bottom;\n\tvoid *topP;\n\tvoid *bottomP;\n\tvoid *tempbuf;\n\n\tif (height <= 1) return; /* No flipping necessary if height is <= 1. */\n\n\ttop = 0;\n\tbottom = height - 1;\n\ttempbuf = malloc(bytewidth);\n\tif (tempbuf == NULL) return;\n\n\twhile (top < bottom) {\n\t\ttopP = (void *)((top * bytewidth) + (intptr_t)data);\n\t\tbottomP = (void *)((bottom * bytewidth) + (intptr_t)data);\n\n\t\t/* Save and swap scanlines.\n\t\t * Does a simple in-place exchange with a temp buffer. */\n\t\tmemcpy(tempbuf, topP, bytewidth);\n\t\tmemcpy(topP, bottomP, bytewidth);\n\t\tmemcpy(bottomP, tempbuf, bytewidth);\n\n\t\t++top;\n\t\t--bottom;\n\t}\n\tfree(tempbuf);\n}\n"
  },
  {
    "path": "pkg/internal/robotgo/base/color_find.h",
    "content": "#pragma once\n#ifndef COLOR_FIND_H\n#define COLOR_FIND_H\n\n#include \"MMBitmap.h\"\n#include \"MMPointArray.h\"\n\n/* Convenience wrapper around findColorInRect(), where |rect| is the bounds of\n * the image. */\n#define findColorInImage(image, color, pointPtr, tolerance) \\\n\tfindColorInRect(image, color, pointPtr, MMBitmapGetBounds(image), tolerance)\n\n/* Attempt to find a pixel with the given color in |image| inside |rect|.\n * Returns 0 on success, non-zero on failure. If the color was found and\n * |point| is not NULL, it will be initialized to the (x, y) coordinates the\n * RGB color.\n *\n * |tolerance| should be in the range 0.0f - 1.0f, denoting how closely the\n * colors need to match, with 0 being exact and 1 being any. */\nint findColorInRect(MMBitmapRef image, MMRGBHex color, MMPoint *point,\n                    MMRect rect, float tolerance);\n\n/* Convenience wrapper around findAllRGBInRect(), where |rect| is the bounds of\n * the image. */\n#define findAllColorInImage(image, color, tolerance) \\\n\tfindAllColorInRect(image, color, MMBitmapGetBounds(image), tolerance)\n\n/* Returns MMPointArray of all pixels of given color in |image| inside of\n * |rect|. Note that an array is returned regardless of whether the color was\n * found; check array->count to see if it actually was.\n *\n * Responsibility for freeing the MMPointArray with destroyMMPointArray() is\n * given to the caller.\n *\n * |tolerance| should be in the range 0.0f - 1.0f, denoting how closely the\n * colors need to match, with 0 being exact and 1 being any. */\nMMPointArrayRef findAllColorInRect(MMBitmapRef image, MMRGBHex color,\n                                   MMRect rect, float tolerance);\n\n/* Convenience wrapper around countOfColorsInRect, where |rect| is the bounds\n * of the image. */\n#define countOfColorsInImage(image, color, tolerance) \\\n\tcountOfColorsInRect(image, color, MMBitmapGetBounds(image), tolerance)\n\n/* Returns the count of the given color in |rect| inside of |image|. */\nsize_t countOfColorsInRect(MMBitmapRef image, MMRGBHex color, MMRect rect,\n                           float tolerance);\n\n#endif /* COLOR_FIND_H */\n"
  },
  {
    "path": "pkg/internal/robotgo/base/color_find_c.h",
    "content": "#include \"color_find.h\"\n// #include \"../screen/screen_init.h\"\n#include <stdlib.h>\n\n/* Abstracted, general function to avoid repeated code. */\nstatic int findColorInRectAt(MMBitmapRef image, MMRGBHex color, MMPoint *point,\n                             MMRect rect, float tolerance, MMPoint startPoint)\n{\n\tMMPoint scan = startPoint;\n\tif (!MMBitmapRectInBounds(image, rect)) return -1;\n\n\tfor (; scan.y < rect.size.height; ++scan.y) {\n\t\tfor (; scan.x < rect.size.width; ++scan.x) {\n\t\t\tMMRGBHex found = MMRGBHexAtPoint(image, scan.x, scan.y);\n\t\t\tif (MMRGBHexSimilarToColor(color, found, tolerance)) {\n\t\t\t\tif (point != NULL) *point = scan;\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t}\n\t\tscan.x = rect.origin.x;\n\t}\n\n\treturn -1;\n}\n\nint findColorInRect(MMBitmapRef image, MMRGBHex color,\n                    MMPoint *point, MMRect rect, float tolerance)\n{\n\treturn findColorInRectAt(image, color, point, rect, tolerance, rect.origin);\n}\n\nMMPointArrayRef findAllColorInRect(MMBitmapRef image, MMRGBHex color,\n                                   MMRect rect, float tolerance)\n{\n\tMMPointArrayRef pointArray = createMMPointArray(0);\n\tMMPoint point = MMPointZero;\n\n\twhile (findColorInRectAt(image, color, &point, rect, tolerance, point) == 0) {\n\t\tMMPointArrayAppendPoint(pointArray, point);\n\t\tITER_NEXT_POINT(point, rect.size.width, rect.origin.x);\n\t}\n\n\treturn pointArray;\n}\n\nsize_t countOfColorsInRect(MMBitmapRef image, MMRGBHex color, MMRect rect,\n                           float tolerance)\n{\n\tsize_t count = 0;\n\tMMPoint point = MMPointZero;\n\n\twhile (findColorInRectAt(image, color, &point, rect, tolerance, point) == 0) {\n\t\tITER_NEXT_POINT(point, rect.size.width, rect.origin.x);\n\t\t++count;\n\t}\n\n\treturn count;\n}\n"
  },
  {
    "path": "pkg/internal/robotgo/base/deadbeef_rand.h",
    "content": "#ifndef DEADBEEF_RAND_H\n#define DEADBEEF_RAND_H\n\n#include <stdint.h>\n\n#define DEADBEEF_MAX UINT32_MAX\n\n/* Dead Beef Random Number Generator\n * From: http://inglorion.net/software/deadbeef_rand\n * A fast, portable psuedo-random number generator by BJ Amsterdam Zuidoost.\n * Stated in license terms: \"Feel free to use the code in your own software.\" */\n\n/* Generates a random number between 0 and DEADBEEF_MAX. */\nuint32_t deadbeef_rand(void);\n\n/* Seeds with the given integer. */\nvoid deadbeef_srand(uint32_t x);\n\n/* Generates seed from the current time. */\nuint32_t deadbeef_generate_seed(void);\n\n/* Seeds with the above function. */\n#define deadbeef_srand_time() deadbeef_srand(deadbeef_generate_seed())\n\n/* Returns random double in the range [a, b).\n * Taken directly from the rand() man page. */\n#define DEADBEEF_UNIFORM(a, b) \\\n\t((a) + (deadbeef_rand() / (((double)DEADBEEF_MAX / (b - a) + 1))))\n\n/* Returns random integer in the range [a, b).\n * Also taken from the rand() man page. */\n#define DEADBEEF_RANDRANGE(a, b) \\\n\t(uint32_t)DEADBEEF_UNIFORM(a, b)\n\n#endif /* DEADBEEF_RAND_H */\n"
  },
  {
    "path": "pkg/internal/robotgo/base/deadbeef_rand_c.h",
    "content": "#include \"deadbeef_rand.h\"\n#include <time.h>\n\nstatic uint32_t deadbeef_seed;\nstatic uint32_t deadbeef_beef = 0xdeadbeef;\n\nuint32_t deadbeef_rand(void)\n{\n\tdeadbeef_seed = (deadbeef_seed << 7) ^ ((deadbeef_seed >> 25) + deadbeef_beef);\n\tdeadbeef_beef = (deadbeef_beef << 7) ^ ((deadbeef_beef >> 25) + 0xdeadbeef);\n\treturn deadbeef_seed;\n}\n\nvoid deadbeef_srand(uint32_t x)\n{\n\tdeadbeef_seed = x;\n\tdeadbeef_beef = 0xdeadbeef;\n}\n\n/* Taken directly from the documentation:\n * http://inglorion.net/software/cstuff/deadbeef_rand/ */\nuint32_t deadbeef_generate_seed(void)\n{\n\t  uint32_t t = (uint32_t)time(NULL);\n\t  uint32_t c = (uint32_t)clock();\n\t  return (t << 24) ^ (c << 11) ^ t ^ (size_t) &c;\n}\n"
  },
  {
    "path": "pkg/internal/robotgo/base/endian.h",
    "content": "#pragma once\n#ifndef ENDIAN_H\n#define ENDIAN_H\n\n#include \"os.h\"\n\n/*\n * (Mostly) cross-platform endian definitions and bit swapping macros.\n * Unfortunately, there is no standard C header for this, so we just\n * include the most common ones and fallback to our own custom macros.\n */\n\n#if defined(__linux__) /* Linux */\n\t#include <endian.h>\n\t#include <byteswap.h>\n#elif (defined(__FreeBSD__) && __FreeBSD_version >= 470000) || \\\n       defined(__OpenBSD__) || defined(__NetBSD__) /* (Free|Open|Net)BSD */\n\t#include <sys/endian.h>\n\t#define __BIG_ENDIAN BIG_ENDIAN\n\t#define __LITTLE_ENDIAN LITTLE_ENDIAN\n\t#define __BYTE_ORDER BYTE_ORDER\n#elif defined(IS_MACOSX) || (defined(BSD) && (BSD >= 199103)) /* Other BSD */\n\t#include <machine/endian.h>\n\t#define __BIG_ENDIAN BIG_ENDIAN\n\t#define __LITTLE_ENDIAN LITTLE_ENDIAN\n\t#define __BYTE_ORDER BYTE_ORDER\n#elif defined(IS_WINDOWS) /* Windows is assumed to be little endian only. */\n\t#define __BIG_ENDIAN 4321\n\t#define __LITTLE_ENDIAN 1234\n\t#define __BYTE_ORDER __LITTLE_ENDIAN\n#endif\n\n/* Fallback to custom constants. */\n#if !defined(__BIG_ENDIAN)\n\t#define __BIG_ENDIAN 4321\n#endif\n\n#if !defined(__LITTLE_ENDIAN)\n\t#define __LITTLE_ENDIAN 1234\n#endif\n\n/* Prefer compiler flag settings if given. */\n#if defined(MM_BIG_ENDIAN)\n\t#undef __BYTE_ORDER /* Avoid redefined macro compiler warning. */\n\t#define __BYTE_ORDER  __BIG_ENDIAN\n#elif defined(MM_LITTLE_ENDIAN)\n\t#undef __BYTE_ORDER /* Avoid redefined macro compiler warning. */\n\t#define __BYTE_ORDER __LITTLE_ENDIAN\n#endif\n\n/* Define default endian-ness. */\n#ifndef __LITTLE_ENDIAN\n\t#define __LITTLE_ENDIAN 1234\n#endif /* __LITTLE_ENDIAN */\n\n#ifndef __BIG_ENDIAN\n\t#define __BIG_ENDIAN 4321\n#endif /* __BIG_ENDIAN */\n\n#ifndef __BYTE_ORDER\n\t#warning \"Byte order not defined on your system; assuming little endian\"\n\t#define __BYTE_ORDER __LITTLE_ENDIAN\n#endif /* __BYTE_ORDER */\n\n#if __BYTE_ORDER != __BIG_ENDIAN && __BYTE_ORDER != __LITTLE_ENDIAN\n\t#error \"__BYTE_ORDER set to unknown byte order\"\n#endif\n\n#if defined(IS_MACOSX)\n\t#include <libkern/OSByteOrder.h>\n\n\t/* OS X system functions. */\n\t#define bitswap16(i) OSSwapInt16(i)\n\t#define bitswap32(i) OSSwapInt32(i)\n\t#define swapLittleAndHost32(i) OSSwapLittleToHostInt32(i)\n\t#define swapLittleAndHost16(i) OSSwapLittleToHostInt16(i)\n#else\n\t#ifndef bitswap16\n\t\t#if defined(bswap16)\n\t\t\t#define bitswap16(i) bswap16(i) /* FreeBSD system function */\n\t\t#elif defined(bswap_16)\n\t\t\t#define bitswap16(i) bswap_16(i) /* Linux system function */\n\t\t#else /* Default macro */\n\t\t\t#define bitswap16(i) (((uint16_t)(i) & 0xFF00) >> 8) | \\\n \t\t                          (((uint16_t)(i) & 0x00FF) << 8)\n\t\t#endif\n\t#endif /* bitswap16 */\n\n\t#ifndef bitswap32\n\t\t#if defined(bswap32)\n\t\t\t#define bitswap32(i) bswap32(i) /* FreeBSD system function. */\n\t\t#elif defined(bswap_32)\n\t\t\t#define bitswap32(i) bswap_32(i) /* Linux system function. */\n\t\t#else /* Default macro */\n\t\t\t#define bitswap32(i) (((uint32_t)(i) & 0xFF000000) >> 24) | \\\n\t\t\t                      ((uint32_t)((i) & 0x00FF0000) >> 8) | \\\n\t\t\t                      ((uint32_t)((i) & 0x0000FF00) << 8) | \\\n\t\t\t                      ((uint32_t)((i) & 0x000000FF) << 24)\n\t\t#endif\n\t#endif /* bitswap32 */\n#endif\n\n#if __BYTE_ORDER == __BIG_ENDIAN\n\t/* Little endian to/from host byte order (big endian). */\n\t#ifndef swapLittleAndHost16\n\t\t#define swapLittleAndHost16(i) bitswap16(i)\n\t#endif /* swapLittleAndHost16 */\n\n\t#ifndef swapLittleAndHost32\n\t\t#define swapLittleAndHost32(i) bitswap32(i)\n\t#endif /* swapLittleAndHost32 */\n#elif __BYTE_ORDER == __LITTLE_ENDIAN\n\t/* We are already little endian, so no conversion is needed. */\n\t#ifndef swapLittleAndHost16\n\t\t#define swapLittleAndHost16(i) i\n\t#endif /* swapLittleAndHost16 */\n\n\t#ifndef swapLittleAndHost32\n\t\t#define swapLittleAndHost32(i) i\n\t#endif /* swapLittleAndHost32 */\n#endif\n\n#endif /* ENDIAN_H */\n"
  },
  {
    "path": "pkg/internal/robotgo/base/file_io.h",
    "content": "#pragma once\n#ifndef FILE_IO_H\n#define FILE_IO_H\n\n#include \"MMBitmap.h\"\n#include <stddef.h>\n#include <stdint.h>\n\n\nenum _MMImageType {\n\tkInvalidImageType = 0,\n\tkPNGImageType,\n\tkBMPImageType /* Currently only PNG and BMP are supported. */\n};\n\ntypedef uint16_t MMImageType;\n\nenum _MMIOError {\n\tkMMIOUnsupportedTypeError = 0\n};\n\ntypedef uint16_t MMIOError;\n\nconst char *getExtension(const char *fname, size_t len);\n\n/* Returns best guess at the MMImageType based on a file extension, or\n * |kInvalidImageType| if no matching type was found. */\nMMImageType imageTypeFromExtension(const char *ext);\n\n/* Attempts to parse the file of the given type at the given path.\n * |filepath| is an ASCII string describing the absolute POSIX path.\n * Returns new bitmap (to be destroy()'d by caller) on success, NULL on error.\n * If |error| is non-NULL, it will be set to the error code on return.\n */\nMMBitmapRef newMMBitmapFromFile(const char *path, MMImageType type, MMIOError *err);\n\n/* Saves |bitmap| to a file of the given type at the given path.\n * |filepath| is an ASCII string describing the absolute POSIX path.\n * Returns 0 on success, -1 on error. */\nint saveMMBitmapToFile(MMBitmapRef bitmap, const char *path, MMImageType type);\n\n/* Returns description of given error code.\n * Returned string is constant and hence should not be freed. */\nconst char *MMIOErrorString(MMImageType type, MMIOError error);\n\n#endif /* IO_H */\n"
  },
  {
    "path": "pkg/internal/robotgo/base/file_io_c.h",
    "content": "#include \"file_io.h\"\n// #include \"os.h\"\n// #include \"bmp_io_c.h\"\n#include \"png_io_c.h\"\n#include <stdio.h> /* For fputs() */\n#include <string.h> /* For strcmp() */\n#include <ctype.h> /* For tolower() */\n\nconst char *getExtension(const char *fname, size_t len){\n\tif (fname == NULL || len <= 0) return NULL;\n\n\twhile (--len > 0 && fname[len] != '.' && fname[len] != '\\0')\n\t\t;\n\n\treturn fname + len + 1;\n}\n\nMMImageType imageTypeFromExtension(const char *extension){\n\tchar ext[4];\n\tconst size_t maxlen = sizeof(ext) / sizeof(ext[0]);\n\tsize_t i;\n\n\tfor (i = 0; extension[i] != '\\0'; ++i) {\n\t\tif (i >= maxlen) return kInvalidImageType;\n\t\text[i] = tolower(extension[i]);\n\t}\n\text[i] = '\\0';\n\n\tif (strcmp(ext, \"png\") == 0) {\n\t\treturn kPNGImageType;\n\t} else if (strcmp(ext, \"bmp\") == 0) {\n\t\treturn kBMPImageType;\n\t} else {\n\t\treturn kInvalidImageType;\n\t}\n}\n\nMMBitmapRef newMMBitmapFromFile(const char *path, MMImageType type, MMIOError *err){\n\tswitch (type) {\n\t\tcase kBMPImageType:\n\t\t\treturn newMMBitmapFromBMP(path, err);\n\t\tcase kPNGImageType:\n\t\t\treturn newMMBitmapFromPNG(path, err);\n\t\tdefault:\n\t\t\tif (err != NULL) *err = kMMIOUnsupportedTypeError;\n\t\t\treturn NULL;\n\t}\n}\n\nint saveMMBitmapToFile(MMBitmapRef bitmap, const char *path, MMImageType type){\n\tswitch (type) {\n\t\tcase kBMPImageType:\n\t\t\treturn saveMMBitmapAsBMP(bitmap, path);\n\t\tcase kPNGImageType:\n\t\t\treturn saveMMBitmapAsPNG(bitmap, path);\n\t\tdefault:\n\t\t\treturn -1;\n\t}\n}\n\nconst char *MMIOErrorString(MMImageType type, MMIOError error){\n\tswitch (type) {\n\t\tcase kBMPImageType:\n\t\t\treturn MMBMPReadErrorString(error);\n\t\tcase kPNGImageType:\n\t\t\treturn MMPNGReadErrorString(error);\n\t\tdefault:\n\t\t\treturn \"Unsupported image type\";\n\t}\n}\n"
  },
  {
    "path": "pkg/internal/robotgo/base/inline_keywords.h",
    "content": "#pragma once\n\n/* A complicated, portable model for declaring inline functions in\n * header files. */\n#if !defined(H_INLINE)\n    #if defined(__GNUC__)\n        #define H_INLINE static __inline__ __attribute__((always_inline))\n    #elif defined(__MWERKS__) || defined(__cplusplus)\n        #define H_INLINE static inline\n    #elif defined(_MSC_VER)\n        #define H_INLINE static __inline\n    #elif TARGET_OS_WIN32\n        #define H_INLINE static __inline__\n    #endif\n#endif /* H_INLINE */\n"
  },
  {
    "path": "pkg/internal/robotgo/base/io.c",
    "content": "#include \"file_io.h\"\n#include \"os.h\"\n#include \"bmp_io.h\"\n#include \"png_io.h\"\n#include <stdio.h> /* For fputs() */\n#include <string.h> /* For strcmp() */\n#include <ctype.h> /* For tolower() */\n\nconst char *getExtension(const char *fname, size_t len){\n\tif (fname == NULL || len <= 0) return NULL;\n\n\twhile (--len > 0 && fname[len] != '.' && fname[len] != '\\0')\n\t\t;\n\n\treturn fname + len + 1;\n}\n\nMMImageType imageTypeFromExtension(const char *extension){\n\tchar ext[4];\n\tconst size_t maxlen = sizeof(ext) / sizeof(ext[0]);\n\tsize_t i;\n\n\tfor (i = 0; extension[i] != '\\0'; ++i) {\n\t\tif (i >= maxlen) return kInvalidImageType;\n\t\text[i] = tolower(extension[i]);\n\t}\n\text[i] = '\\0';\n\n\tif (strcmp(ext, \"png\") == 0) {\n\t\treturn kPNGImageType;\n\t} else if (strcmp(ext, \"bmp\") == 0) {\n\t\treturn kBMPImageType;\n\t} else {\n\t\treturn kInvalidImageType;\n\t}\n}\n\nMMBitmapRef newMMBitmapFromFile(const char *path, MMImageType type, MMIOError *err){\n\tswitch (type) {\n\t\tcase kBMPImageType:\n\t\t\treturn newMMBitmapFromBMP(path, err);\n\t\tcase kPNGImageType:\n\t\t\treturn newMMBitmapFromPNG(path, err);\n\t\tdefault:\n\t\t\tif (err != NULL) *err = kMMIOUnsupportedTypeError;\n\t\t\treturn NULL;\n\t}\n}\n\nint saveMMBitmapToFile(MMBitmapRef bitmap, const char *path, MMImageType type){\n\tswitch (type) {\n\t\tcase kBMPImageType:\n\t\t\treturn saveMMBitmapAsBMP(bitmap, path);\n\t\tcase kPNGImageType:\n\t\t\treturn saveMMBitmapAsPNG(bitmap, path);\n\t\tdefault:\n\t\t\treturn -1;\n\t}\n}\n\nconst char *MMIOErrorString(MMImageType type, MMIOError error){\n\tswitch (type) {\n\t\tcase kBMPImageType:\n\t\t\treturn MMBMPReadErrorString(error);\n\t\tcase kPNGImageType:\n\t\t\treturn MMPNGReadErrorString(error);\n\t\tdefault:\n\t\t\treturn \"Unsupported image type\";\n\t}\n}\n"
  },
  {
    "path": "pkg/internal/robotgo/base/microsleep.h",
    "content": "#pragma once\n#ifndef MICROSLEEP_H\n#define MICROSLEEP_H\n\n#include \"os.h\"\n#include \"inline_keywords.h\"\n\n#if !defined(IS_WINDOWS)\n\t/* Make sure nanosleep gets defined even when using C89. */\n\t#if !defined(__USE_POSIX199309) || !__USE_POSIX199309\n\t\t#define __USE_POSIX199309 1\n\t#endif\n\n\t#include <time.h> /* For nanosleep() */\n#endif\n\n/*\n * A more widely supported alternative to usleep(), based on Sleep() in Windows\n * and nanosleep() everywhere else.\n *\n * Pauses execution for the given amount of milliseconds.\n */\nH_INLINE void microsleep(double milliseconds)\n{\n#if defined(IS_WINDOWS)\n\tSleep((DWORD)milliseconds); /* (Unfortunately truncated to a 32-bit integer.) */\n#else\n\t/* Technically, nanosleep() is not an ANSI function, but it is the most\n\t * supported precise sleeping function I can find.\n\t *\n\t * If it is really necessary, it may be possible to emulate this with some\n\t * hack using select() in the future if we really have to. */\n\tstruct timespec sleepytime;\n\tsleepytime.tv_sec = milliseconds / 1000;\n\tsleepytime.tv_nsec = (milliseconds - (sleepytime.tv_sec * 1000)) * 1000000;\n\tnanosleep(&sleepytime, NULL);\n#endif\n}\n\n#endif /* MICROSLEEP_H */\n"
  },
  {
    "path": "pkg/internal/robotgo/base/ms_stdbool.h",
    "content": "#pragma once\n#if !defined(MS_STDBOOL_H) && \\\n\t(!defined(__bool_true_false_are_defined) || __bool_true_false_are_defined)\n#define MS_STDBOOL_H\n\n#ifndef _MSC_VER\n\t#error \"Use this header only with Microsoft Visual C++ compilers!\"\n#endif /* _MSC_VER */\n\n#define __bool_true_false_are_defined 1\n\n#ifndef __cplusplus\n\n\t#if defined(true) || defined(false) || defined(bool)\n\t\t#error \"Boolean type already defined\"\n\t#endif\n\n\tenum {\n\t\tfalse = 0,\n\t\ttrue = 1\n\t};\n\n\ttypedef unsigned char bool;\n\n#endif /* !__cplusplus */\n\n#endif /* MS_STDBOOL_H */\n"
  },
  {
    "path": "pkg/internal/robotgo/base/ms_stdint.h",
    "content": "/* ISO C9x  compliant stdint.h for Microsoft Visual Studio\n * Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124\n *\n *  Copyright (c) 2006-2008 Alexander Chemeris\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are met:\n *\n *   1. Redistributions of source code must retain the above copyright notice,\n *      this list of conditions and the following disclaimer.\n *\n *   2. Redistributions in binary form must reproduce the above copyright\n *      notice, this list of conditions and the following disclaimer in the\n *      documentation and/or other materials provided with the distribution.\n *\n *   3. The name of the author may be used to endorse or promote products\n *      derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED\n * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\n * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO\n * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;\n * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\n * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR\n * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF\n * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n#ifndef _MSC_VER\n\t#error \"Use this header only with Microsoft Visual C++ compilers!\"\n#endif /* _MSC_VER */\n\n#ifndef MSC_STDINT_H\n#define MSC_STDINT_H\n\n#if _MSC_VER > 1000\n\t#pragma once\n#endif\n\n#include <limits.h>\n\n/* For Visual Studio 6 in C++ mode and for many Visual Studio versions when\n * compiling for ARM we should wrap <wchar.h> include with 'extern \"C++\" {}'\n * or compiler give many errors like this: */\n#if defined(__cplusplus)\nextern \"C\" {\n#endif /* __cplusplus */\n\t#include <wchar.h>\n#if defined(__cplusplus)\n}\n#endif /* __cplusplus */\n\n/* Define _W64 macros to mark types changing their size, like intptr_t. */\n#ifndef _W64\n\t#if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300\n\t\t#define _W64 __w64\n\t#else\n\t\t#define _W64\n\t#endif\n#endif\n\n\n/* 7.18.1 Integer types */\n\n/* 7.18.1.1 Exact-width integer types */\n\n/* Visual Studio 6 and Embedded Visual C++ 4 doesn't\n * realize that, e.g. char has the same size as __int8\n * so we give up on __intX for them. */\n#if _MSC_VER < 1300\n\ttypedef signed char       int8_t;\n\ttypedef signed short      int16_t;\n\ttypedef signed int        int32_t;\n\ttypedef unsigned char     uint8_t;\n\ttypedef unsigned short    uint16_t;\n\ttypedef unsigned int      uint32_t;\n#else\n\ttypedef signed __int8     int8_t;\n\ttypedef signed __int16    int16_t;\n\ttypedef signed __int32    int32_t;\n\ttypedef unsigned __int8   uint8_t;\n\ttypedef unsigned __int16  uint16_t;\n\ttypedef unsigned __int32  uint32_t;\n#endif\ntypedef signed __int64       int64_t;\ntypedef unsigned __int64     uint64_t;\n\n/* 7.18.1.2 Minimum-width integer types */\ntypedef int8_t    int_least8_t;\ntypedef int16_t   int_least16_t;\ntypedef int32_t   int_least32_t;\ntypedef int64_t   int_least64_t;\ntypedef uint8_t   uint_least8_t;\ntypedef uint16_t  uint_least16_t;\ntypedef uint32_t  uint_least32_t;\ntypedef uint64_t  uint_least64_t;\n\n/* 7.18.1.3 Fastest minimum-width integer types */\ntypedef int8_t    int_fast8_t;\ntypedef int16_t   int_fast16_t;\ntypedef int32_t   int_fast32_t;\ntypedef int64_t   int_fast64_t;\ntypedef uint8_t   uint_fast8_t;\ntypedef uint16_t  uint_fast16_t;\ntypedef uint32_t  uint_fast32_t;\ntypedef uint64_t  uint_fast64_t;\n\n/* 7.18.1.4 Integer types capable of holding object pointers */\n#if defined(_WIN64)\n\ttypedef signed __int64    intptr_t;\n\ttypedef unsigned __int64  uintptr_t;\n#else\n\ttypedef _W64 signed int   intptr_t;\n\ttypedef _W64 unsigned int uintptr_t;\n#endif /* _WIN64 ] */\n\n/* 7.18.1.5 Greatest-width integer types */\ntypedef int64_t   intmax_t;\ntypedef uint64_t  uintmax_t;\n\n/* 7.18.2 Limits of specified-width integer types */\n\n/* See footnote 220 at page 257 and footnote 221 at page 259 */\n#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS)\n\n\t/* 7.18.2.1 Limits of exact-width integer types */\n\t#define INT8_MIN     ((int8_t)_I8_MIN)\n\t#define INT8_MAX     _I8_MAX\n\t#define INT16_MIN    ((int16_t)_I16_MIN)\n\t#define INT16_MAX    _I16_MAX\n\t#define INT32_MIN    ((int32_t)_I32_MIN)\n\t#define INT32_MAX    _I32_MAX\n\t#define INT64_MIN    ((int64_t)_I64_MIN)\n\t#define INT64_MAX    _I64_MAX\n\t#define UINT8_MAX    _UI8_MAX\n\t#define UINT16_MAX   _UI16_MAX\n\t#define UINT32_MAX   _UI32_MAX\n\t#define UINT64_MAX   _UI64_MAX\n\n\t/* 7.18.2.2 Limits of minimum-width integer types */\n\t#define INT_LEAST8_MIN    INT8_MIN\n\t#define INT_LEAST8_MAX    INT8_MAX\n\t#define INT_LEAST16_MIN   INT16_MIN\n\t#define INT_LEAST16_MAX   INT16_MAX\n\t#define INT_LEAST32_MIN   INT32_MIN\n\t#define INT_LEAST32_MAX   INT32_MAX\n\t#define INT_LEAST64_MIN   INT64_MIN\n\t#define INT_LEAST64_MAX   INT64_MAX\n\t#define UINT_LEAST8_MAX   UINT8_MAX\n\t#define UINT_LEAST16_MAX  UINT16_MAX\n\t#define UINT_LEAST32_MAX  UINT32_MAX\n\t#define UINT_LEAST64_MAX  UINT64_MAX\n\n\t/* 7.18.2.4 Limits of integer types capable of holding object pointers */\n\t#if defined(_WIN64)\n\t\t#define INTPTR_MIN   INT64_MIN\n\t\t#define INTPTR_MAX   INT64_MAX\n\t\t#define UINTPTR_MAX  UINT64_MAX\n\t#else\n\t\t#define INTPTR_MIN   INT32_MIN\n\t\t#define INTPTR_MAX   INT32_MAX\n\t\t#define UINTPTR_MAX  UINT32_MAX\n\t#endif\n\n\t/* 7.18.3 Limits of other integer types */\n\n\t#if defined(_WIN64)\n\t\t#define PTRDIFF_MIN  _I64_MIN\n\t\t#define PTRDIFF_MAX  _I64_MAX\n\t#else\n\t\t#define PTRDIFF_MIN  _I32_MIN\n\t\t#define PTRDIFF_MAX  _I32_MAX\n\t#endif  /* _WIN64 */\n\n\t#define SIG_ATOMIC_MIN  INT_MIN\n\t#define SIG_ATOMIC_MAX  INT_MAX\n\n\t#ifndef SIZE_MAX\n\t\t#if defined(_WIN64)\n\t\t\t#define SIZE_MAX  _UI64_MAX\n\t\t#else\n\t\t\t#define SIZE_MAX  _UI32_MAX\n\t\t#endif\n\t#endif\n\n\t/* WCHAR_MIN and WCHAR_MAX are also defined in <wchar.h> */\n\t#ifndef WCHAR_MIN\n\t\t#define WCHAR_MIN  0\n\t#endif  /* WCHAR_MIN */\n\n\t#ifndef WCHAR_MAX\n\t\t#define WCHAR_MAX  _UI16_MAX\n\t#endif  /* WCHAR_MAX */\n\n\t#define WINT_MIN  0\n\t#define WINT_MAX  _UI16_MAX\n#endif /* __STDC_LIMIT_MACROS */\n\n\n/* 7.18.4 Limits of other integer types */\n\n#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) /* See footnote 224 at page 260 */\n\n\t/* 7.18.4.1 Macros for minimum-width integer constants */\n\n\t#define INT8_C(val)  val##i8\n\t#define INT16_C(val) val##i16\n\t#define INT32_C(val) val##i32\n\t#define INT64_C(val) val##i64\n\n\t#define UINT8_C(val)  val##ui8\n\t#define UINT16_C(val) val##ui16\n\t#define UINT32_C(val) val##ui32\n\t#define UINT64_C(val) val##ui64\n\n\t/* 7.18.4.2 Macros for greatest-width integer constants */\n\t#define INTMAX_C   INT64_C\n\t#define UINTMAX_C  UINT64_C\n\n#endif /* __STDC_CONSTANT_MACROS */\n\n#endif /* MSC_STDINT_H */\n"
  },
  {
    "path": "pkg/internal/robotgo/base/os.h",
    "content": "#pragma once\n#ifndef OS_H\n#define OS_H\n\n/* Python versions under 2.5 don't support this macro, but it's not\n * terribly difficult to replicate: */\n#ifndef PyModule_AddIntMacro\n\t#define PyModule_AddIntMacro(module, macro) \\\n\t\tPyModule_AddIntConstant(module, #macro, macro)\n#endif /* PyModule_AddIntMacro */\n\n#if !defined(IS_MACOSX) && defined(__APPLE__) && defined(__MACH__)\n\t#define IS_MACOSX\n#endif /* IS_MACOSX */\n\n#if !defined(IS_WINDOWS) && (defined(WIN32) || defined(_WIN32) || \\\n                             defined(__WIN32__) || defined(__WINDOWS__) || defined(__CYGWIN__))\n\t#define IS_WINDOWS\n#endif /* IS_WINDOWS */\n\n#if !defined(USE_X11) && !defined(NUSE_X11) && !defined(IS_MACOSX) && !defined(IS_WINDOWS)\n\t#define USE_X11\n#endif /* USE_X11 */\n\n#if defined(IS_WINDOWS)\n\t#define STRICT /* Require use of exact types. */\n\t#define WIN32_LEAN_AND_MEAN 1 /* Speed up compilation. */\n\t#include <windows.h>\n#elif !defined(IS_MACOSX) && !defined(USE_X11)\n\t#error \"Sorry, this platform isn't supported yet!\"\n#endif\n\n/* Interval to align by for large buffers (e.g. bitmaps). */\n/* Must be a power of 2. */\n#ifndef BYTE_ALIGN\n\t#define BYTE_ALIGN 4 /* Bytes to align pixel buffers to. */\n\t/* #include <stddef.h> */\n\t/* #define BYTE_ALIGN (sizeof(size_t)) */\n#endif /* BYTE_ALIGN */\n\n#if BYTE_ALIGN == 0\n\t/* No alignment needed. */\n\t#define ADD_PADDING(width) (width)\n#else\n\t/* Aligns given width to padding. */\n\t#define ADD_PADDING(width) (BYTE_ALIGN + (((width) - 1) & ~(BYTE_ALIGN - 1)))\n#endif\n\n#endif /* OS_H */\n"
  },
  {
    "path": "pkg/internal/robotgo/base/pasteboard.h",
    "content": "#pragma once\n#ifndef PASTEBOARD_H\n#define PASTEBOARD_H\n\n#include \"MMBitmap.h\"\n#include \"file_io.h\"\n\nenum _MMBitmapPasteError {\n\tkMMPasteNoError = 0,\n\tkMMPasteGenericError,\n\tkMMPasteOpenError,\n\tkMMPasteClearError,\n\tkMMPasteDataError,\n\tkMMPastePasteError,\n\tkMMPasteUnsupportedError\n};\n\ntypedef MMIOError MMPasteError;\n\n/* Copies |bitmap| to the pasteboard as a PNG.\n * Returns 0 on success, non-zero on error. */\nMMPasteError copyMMBitmapToPasteboard(MMBitmapRef bitmap);\n\n/* Returns description of given MMPasteError.\n * Returned string is constant and hence should not be freed. */\nconst char *MMPasteErrorString(MMPasteError error);\n\n#endif /* PASTEBOARD_H */\n"
  },
  {
    "path": "pkg/internal/robotgo/base/pasteboard_c.h",
    "content": "#include \"pasteboard.h\"\n#include \"os.h\"\n\n#if defined(IS_MACOSX)\n\t#include \"png_io.h\"\n\t#include <ApplicationServices/ApplicationServices.h>\n#elif defined(IS_WINDOWS)\n\t#include \"bmp_io.h\"\n#endif\n\nMMPasteError copyMMBitmapToPasteboard(MMBitmapRef bitmap)\n{\n#if defined(IS_MACOSX)\n\tPasteboardRef clipboard;\n\n\tsize_t len;\n\tuint8_t *pngbuf;\n\tCFDataRef data;\n\tOSStatus err;\n\n\tif (PasteboardCreate(kPasteboardClipboard, &clipboard) != noErr) {\n\t\treturn kMMPasteOpenError;\n\t}\n\n\tif (PasteboardClear(clipboard) != noErr) {\n\t\tCFRelease(clipboard);\n\t\treturn kMMPasteClearError;\n\t}\n\n\tpngbuf = createPNGData(bitmap, &len);\n\tif (pngbuf == NULL) {\n\t\tCFRelease(clipboard);\n\t\treturn kMMPasteDataError;\n\t}\n\n\tdata = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, pngbuf, len,\n\t                                   kCFAllocatorNull);\n\tif (data == NULL) {\n\t\tCFRelease(clipboard);\n\t\tfree(pngbuf);\n\t\treturn kMMPasteDataError;\n\t}\n\n\terr = PasteboardPutItemFlavor(clipboard, bitmap, kUTTypePNG, data, 0);\n\tCFRelease(data);\n\tCFRelease(clipboard);\n\tfree(pngbuf);\n\treturn (err == noErr) ? kMMPasteNoError : kMMPastePasteError;\n#elif defined(IS_WINDOWS)\n\tMMPasteError ret = kMMPasteNoError;\n\tuint8_t *bmpData;\n\tsize_t len;\n\tHGLOBAL handle;\n\n\tif (!OpenClipboard(NULL)) return kMMPasteOpenError;\n\tif (!EmptyClipboard()) return kMMPasteClearError;\n\n\tbmpData = createBitmapData(bitmap, &len);\n\tif (bmpData == NULL) return kMMPasteDataError;\n\n\t/* CF_DIB does not include the BITMAPFILEHEADER struct (and displays a\n\t * cryptic error if it is included). */\n\tlen -= sizeof(BITMAPFILEHEADER);\n\n\t/* SetClipboardData() needs a \"handle\", not just a buffer, so we have to\n\t * allocate one with GlobalAlloc(). */\n\tif ((handle = GlobalAlloc(GMEM_MOVEABLE, len)) == NULL) {\n\t\tCloseClipboard();\n\t\tfree(bmpData);\n\t\treturn kMMPasteDataError;\n\t}\n\n\tmemcpy(GlobalLock(handle), bmpData + sizeof(BITMAPFILEHEADER), len);\n\tGlobalUnlock(handle);\n\tfree(bmpData);\n\n\tif (SetClipboardData(CF_DIB, handle) == NULL) {\n\t\tret = kMMPastePasteError;\n\t}\n\n\tCloseClipboard();\n\tGlobalFree(handle);\n\treturn ret;\n#elif defined(USE_X11)\n\t/* TODO (X11's clipboard is _weird_.) */\n\treturn kMMPasteUnsupportedError;\n#endif\n}\n\nconst char *MMPasteErrorString(MMPasteError err)\n{\n\tswitch (err) {\n\t\tcase kMMPasteOpenError:\n\t\t\treturn \"Could not open pasteboard\";\n\t\tcase kMMPasteClearError:\n\t\t\treturn \"Could not clear pasteboard\";\n\t\tcase kMMPasteDataError:\n\t\t\treturn \"Could not create image data from bitmap\";\n\t\tcase kMMPastePasteError:\n\t\t\treturn \"Could not paste data\";\n\t\tcase kMMPasteUnsupportedError:\n\t\t\treturn \"Unsupported platform\";\n\t\tdefault:\n\t\t\treturn NULL;\n\t}\n}\n"
  },
  {
    "path": "pkg/internal/robotgo/base/png_io.h",
    "content": "#pragma once\n#ifndef PNG_IO_H\n#define PNG_IO_H\n\n// #include \"MMBitmap_c.h\"\n// #include \"file_io_c.h\"\n\nenum _PNGReadError {\n\tkPNGGenericError = 0,\n\tkPNGReadError,\n\tkPNGAccessError,\n\tkPNGInvalidHeaderError\n};\n\ntypedef MMIOError MMPNGReadError;\n\n/* Returns description of given MMPNGReadError.\n * Returned string is constant and hence should not be freed. */\nconst char *MMPNGReadErrorString(MMIOError error);\n\n/* Attempts to read PNG file at path; returns new MMBitmap on success, or\n * NULL on error. If |error| is non-NULL, it will be set to the error code\n * on return.\n * Responsibility for destroy()'ing returned MMBitmap is left up to caller. */\nMMBitmapRef newMMBitmapFromPNG(const char *path, MMPNGReadError *error);\n\n/* Attempts to write PNG at path; returns 0 on success, -1 on error. */\nint saveMMBitmapAsPNG(MMBitmapRef bitmap, const char *path);\n\n/* Returns a buffer containing the raw PNG file data, ready to be saved to a\n * file. |len| will be set to the number of bytes allocated in the returned\n * buffer (it cannot be NULL).\n *\n * Responsibility for free()'ing data is left up to the caller. */\nuint8_t *createPNGData(MMBitmapRef bitmap, size_t *len);\n\n#endif /* PNG_IO_H */\n"
  },
  {
    "path": "pkg/internal/robotgo/base/png_io_c.h",
    "content": "#include \"png_io.h\"\n#include \"os.h\"\n// #include \"libpng/png.c\"\n#if defined(IS_MACOSX)\n\t#include \"../cdeps/mac/png.h\"\n#elif defined(USE_X11)\n\t#include <png.h>\n#elif defined(IS_WINDOWS)\n\t#if defined (__x86_64__)\n\t\t#include \"../cdeps/win64/png.h\"\n\t#else\n\t\t#include \"../cdeps/win32/png.h\"\n\t#endif\n#endif\n\n#include <stdio.h> /* fopen() */\n#include <stdlib.h> /* malloc/realloc */\n#include <assert.h>\n\n#if defined(_MSC_VER)\n\t#include \"ms_stdint.h\"\n\t#include \"ms_stdbool.h\"\n#else\n\t#include <stdint.h>\n\t#include <stdbool.h>\n#endif\n\nconst char *MMPNGReadErrorString(MMIOError error)\n{\n\tswitch (error) {\n\t\tcase kPNGAccessError:\n\t\t\treturn \"Could not open file\";\n\t\tcase kPNGReadError:\n\t\t\treturn \"Could not read file\";\n\t\tcase kPNGInvalidHeaderError:\n\t\t\treturn \"Not a PNG file\";\n\t\tdefault:\n\t\t\treturn NULL;\n\t}\n}\n\nMMBitmapRef newMMBitmapFromPNG(const char *path, MMPNGReadError *err)\n{\n\tFILE *fp;\n\tuint8_t header[8];\n\tpng_struct *png_ptr = NULL;\n\tpng_info *info_ptr = NULL;\n\tpng_byte bit_depth, color_type;\n\tuint8_t *row, *bitmapData;\n\tuint8_t bytesPerPixel;\n\tpng_uint_32 width, height, y;\n\tuint32_t bytewidth;\n\n\tif ((fp = fopen(path, \"rb\")) == NULL) {\n\t\tif (err != NULL) *err = kPNGAccessError;\n\t\treturn NULL;\n\t}\n\n\t/* Initialize error code to generic value. */\n\tif (err != NULL) *err = kPNGGenericError;\n\n\t/* Validate the PNG. */\n\tif (fread(header, 1, sizeof header, fp) == 0) {\n\t\tif (err != NULL) *err = kPNGReadError;\n\t\tgoto bail;\n\t} else if (png_sig_cmp(header, 0, sizeof(header)) != 0) {\n\t\tif (err != NULL) *err = kPNGInvalidHeaderError;\n\t\tgoto bail;\n\t}\n\n\tpng_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);\n\tif (png_ptr == NULL) goto bail;\n\n\tinfo_ptr = png_create_info_struct(png_ptr);\n\tif (info_ptr == NULL) goto bail;\n\n\t/* Set up error handling. */\n\tif (setjmp(png_jmpbuf(png_ptr))) {\n\t\tgoto bail;\n\t}\n\n\tpng_init_io(png_ptr, fp);\n\n\t/* Skip past the header. */\n\tpng_set_sig_bytes(png_ptr, sizeof header);\n\n\tpng_read_info(png_ptr, info_ptr);\n\n\t/* Convert different image types to common type to be read. */\n\tbit_depth = png_get_bit_depth(png_ptr, info_ptr);\n\tcolor_type = png_get_color_type(png_ptr, info_ptr);\n\n\t/* Convert color palettes to RGB. */\n\tif (color_type == PNG_COLOR_TYPE_PALETTE) {\n\t\tpng_set_palette_to_rgb(png_ptr);\n\t}\n\n\t/* Convert PNG to bit depth of 8. */\n\tif (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) {\n\t\tpng_set_expand_gray_1_2_4_to_8(png_ptr);\n\t} else if (bit_depth == 16) {\n\t\tpng_set_strip_16(png_ptr);\n\t}\n\n\t/* Convert transparency chunk to alpha channel. */\n\tif (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))  {\n\t\tpng_set_tRNS_to_alpha(png_ptr);\n\t}\n\n\t/* Convert gray images to RGB. */\n\tif (color_type == PNG_COLOR_TYPE_GRAY ||\n\t    color_type == PNG_COLOR_TYPE_GRAY_ALPHA) {\n\t\tpng_set_gray_to_rgb(png_ptr);\n\t}\n\n\t/* Ignore alpha for now. */\n\tif (color_type & PNG_COLOR_MASK_ALPHA) {\n\t\tpng_set_strip_alpha(png_ptr);\n\t}\n\n\t/* Get image attributes. */\n\twidth = png_get_image_width(png_ptr, info_ptr);\n\theight = png_get_image_height(png_ptr, info_ptr);\n\tbytesPerPixel = 3; /* All images decompress to this size. */\n\tbytewidth = ADD_PADDING(width * bytesPerPixel); /* Align width. */\n\n\t/* Decompress the PNG row by row. */\n\tbitmapData = calloc(1, bytewidth * height);\n\trow = png_malloc(png_ptr, png_get_rowbytes(png_ptr, info_ptr));\n\tif (bitmapData == NULL || row == NULL) goto bail;\n\tfor (y = 0; y < height; ++y) {\n\t\tpng_uint_32 x;\n\t\tconst uint32_t rowOffset = y * bytewidth;\n\t\tuint8_t *rowptr = row;\n\t\tpng_read_row(png_ptr, (png_byte *)row, NULL);\n\n\t\tfor (x = 0; x < width; ++x) {\n\t\t\tconst uint32_t colOffset = x * bytesPerPixel;\n\t\t\tMMRGBColor *color = (MMRGBColor *)(bitmapData + rowOffset + colOffset);\n\t\t\tcolor->red = *rowptr++;\n\t\t\tcolor->green = *rowptr++;\n\t\t\tcolor->blue = *rowptr++;\n\t\t}\n\t}\n\tfree(row);\n\n\t/* Finish reading. */\n\tpng_read_end(png_ptr, NULL);\n\tpng_destroy_read_struct(&png_ptr, &info_ptr, NULL);\n\tfclose(fp);\n\n\treturn createMMBitmap(bitmapData, width, height,\n\t                      bytewidth, bytesPerPixel * 8, bytesPerPixel);\n\nbail:\n\tpng_destroy_read_struct(&png_ptr, &info_ptr, NULL);\n\tfclose(fp);\n\treturn NULL;\n}\n\nstruct _PNGWriteInfo {\n\tpng_struct *png_ptr;\n\tpng_info *info_ptr;\n\tpng_byte **row_pointers;\n\tsize_t row_count;\n\tbool free_row_pointers;\n};\n\ntypedef struct _PNGWriteInfo PNGWriteInfo;\ntypedef PNGWriteInfo *PNGWriteInfoRef;\n\n/* Returns pointer to PNGWriteInfo struct containing data ready to be used with\n * functions such as png_write_png().\n *\n * It is the caller's responsibility to destroy() the returned structure with\n * destroyPNGWriteInfo(). */\nstatic PNGWriteInfoRef createPNGWriteInfo(MMBitmapRef bitmap)\n{\n\tPNGWriteInfoRef info = malloc(sizeof(PNGWriteInfo));\n\tpng_uint_32 y;\n\n\tif (info == NULL) return NULL;\n\tinfo->png_ptr = NULL;\n\tinfo->info_ptr = NULL;\n\tinfo->row_pointers = NULL;\n\n\tassert(bitmap != NULL);\n\n\t/* Initialize the write struct. */\n\tinfo->png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,\n\t                                        NULL, NULL, NULL);\n\tif (info->png_ptr == NULL) goto bail;\n\n\t/* Set up error handling. */\n\tif (setjmp(png_jmpbuf(info->png_ptr))) {\n\t\tpng_destroy_write_struct(&(info->png_ptr), &(info->info_ptr));\n\t\tgoto bail;\n\t}\n\n\t/* Initialize the info struct. */\n\tinfo->info_ptr = png_create_info_struct(info->png_ptr);\n\tif (info->info_ptr == NULL) {\n\t\tpng_destroy_write_struct(&(info->png_ptr), NULL);\n\t\tgoto bail;\n\t}\n\n\t/* Set image attributes. */\n\tpng_set_IHDR(info->png_ptr,\n\t             info->info_ptr,\n\t             (png_uint_32)bitmap->width,\n\t             (png_uint_32)bitmap->height,\n\t             8,\n\t             PNG_COLOR_TYPE_RGB,\n\t             PNG_INTERLACE_NONE,\n\t             PNG_COMPRESSION_TYPE_DEFAULT,\n\t             PNG_FILTER_TYPE_DEFAULT);\n\n\tinfo->row_count = bitmap->height;\n\tinfo->row_pointers = png_malloc(info->png_ptr,\n\t                                sizeof(png_byte *) * info->row_count);\n\n\tif (bitmap->bytesPerPixel == 3) {\n\t\t/* No alpha channel; image data can be copied directly. */\n\t\tfor (y = 0; y < info->row_count; ++y) {\n\t\t\tinfo->row_pointers[y] = bitmap->imageBuffer + (bitmap->bytewidth * y);\n\t\t}\n\t\tinfo->free_row_pointers = false;\n\n\t\t/* Convert BGR to RGB if necessary. */\n\t\tif (MMRGB_IS_BGR) {\n\t\t\tpng_set_bgr(info->png_ptr);\n\t\t}\n\t} else {\n\t\t/* Ignore alpha channel; copy image data row by row. */\n\t\tconst size_t bytesPerPixel = 3;\n\t\tconst size_t bytewidth = ADD_PADDING(bitmap->width * bytesPerPixel);\n\n\t\tfor (y = 0; y < info->row_count; ++y) {\n\t\t\tpng_uint_32 x;\n\t\t\tpng_byte *row_ptr = png_malloc(info->png_ptr, bytewidth);\n\t\t\tinfo->row_pointers[y] = row_ptr;\n\t\t\tfor (x = 0; x < bitmap->width; ++x) {\n\t\t\t\tMMRGBColor *color = MMRGBColorRefAtPoint(bitmap, x, y);\n\t\t\t\trow_ptr[0] = color->red;\n\t\t\t\trow_ptr[1] = color->green;\n\t\t\t\trow_ptr[2] = color->blue;\n\n\t\t\t\trow_ptr += bytesPerPixel;\n\t\t\t}\n\t\t}\n\t\tinfo->free_row_pointers = true;\n\t}\n\n\tpng_set_rows(info->png_ptr, info->info_ptr, info->row_pointers);\n\treturn info;\n\nbail:\n\tif (info != NULL) free(info);\n\treturn NULL;\n}\n\n/* Free memory in use by |info|. */\nstatic void destroyPNGWriteInfo(PNGWriteInfoRef info)\n{\n\tassert(info != NULL);\n\tif (info->row_pointers != NULL) {\n\t\tif (info->free_row_pointers) {\n\t\t\tsize_t y;\n\t\t\tfor (y = 0; y < info->row_count; ++y) {\n\t\t\t\tfree(info->row_pointers[y]);\n\t\t\t}\n\t\t}\n\t\tpng_free(info->png_ptr, info->row_pointers);\n\t}\n\n\tpng_destroy_write_struct(&(info->png_ptr), &(info->info_ptr));\n\tfree(info);\n}\n\nint saveMMBitmapAsPNG(MMBitmapRef bitmap, const char *path)\n{\n\tFILE *fp = fopen(path, \"wb\");\n\tPNGWriteInfoRef info;\n\tif (fp == NULL) return -1;\n\n\tif ((info = createPNGWriteInfo(bitmap)) == NULL) {\n\t\tfclose(fp);\n\t\treturn -1;\n\t}\n\n\tpng_init_io(info->png_ptr, fp);\n\tpng_write_png(info->png_ptr, info->info_ptr, PNG_TRANSFORM_IDENTITY, NULL);\n\tfclose(fp);\n\n\tdestroyPNGWriteInfo(info);\n\treturn 0;\n}\n\n/* Structure to store PNG image bytes. */\nstruct io_data\n{\n\tuint8_t *buffer; /* Pointer to raw file data. */\n\tsize_t size; /* Number of bytes actually written to buffer. */\n\tsize_t allocedSize; /* Number of bytes allocated for buffer. */\n};\n\n/* Called each time libpng attempts to write data in createPNGData(). */\nvoid png_append_data(png_struct *png_ptr,\n                     png_byte *new_data,\n                     png_size_t length)\n{\n\tstruct io_data *data = png_get_io_ptr(png_ptr);\n\tdata->size += length;\n\n\t/* Allocate or grow buffer. */\n\tif (data->buffer == NULL) {\n\t\tdata->allocedSize = data->size;\n\t\tdata->buffer = png_malloc(png_ptr, data->allocedSize);\n\t\tassert(data->buffer != NULL);\n\t} else if (data->allocedSize < data->size) {\n\t\tdo {\n\t\t\t/* Double size each time to avoid calls to realloc. */\n\t\t\tdata->allocedSize <<= 1;\n\t\t} while (data->allocedSize < data->size);\n\n\t\tdata->buffer = realloc(data->buffer, data->allocedSize);\n\t}\n\n\t/* Copy new bytes to end of buffer. */\n\tmemcpy(data->buffer + data->size - length, new_data, length);\n}\n\nuint8_t *createPNGData(MMBitmapRef bitmap, size_t *len)\n{\n\tPNGWriteInfoRef info = NULL;\n\tstruct io_data data = {NULL, 0, 0};\n\n\tassert(bitmap != NULL);\n\tassert(len != NULL);\n\n\tif ((info = createPNGWriteInfo(bitmap)) == NULL) return NULL;\n\n\tpng_set_write_fn(info->png_ptr, &data, &png_append_data, NULL);\n\tpng_write_png(info->png_ptr, info->info_ptr, PNG_TRANSFORM_IDENTITY, NULL);\n\n\tdestroyPNGWriteInfo(info);\n\n\t*len = data.size;\n\treturn data.buffer;\n}\n"
  },
  {
    "path": "pkg/internal/robotgo/base/rgb.h",
    "content": "#pragma once\n#ifndef RGB_H\n#define RGB_H\n\n#include <stdlib.h> /* For abs() */\n#include <math.h>\n#include \"inline_keywords.h\" /* For H_INLINE */\n// #include <stdint.h>\n#if defined(_MSC_VER)\n\t#include \"ms_stdint.h\"\n#else\n\t#include <stdint.h>\n#endif\n\n\n/* RGB colors in MMBitmaps are stored as BGR for convenience in converting\n * to/from certain formats (mainly OpenGL).\n *\n * It is best not to rely on the order (simply use rgb.{blue,green,red} to\n * access values), but some situations (e.g., glReadPixels) require one to\n * do so. In that case, check to make sure to use MMRGB_IS_BGR for future\n * compatibility. */\n\n/* #define MMRGB_IS_BGR (offsetof(MMRGBColor, red) > offsetof(MMRGBColor, blue)) */\n#define MMRGB_IS_BGR 1\n\nstruct _MMRGBColor {\n\tuint8_t blue;\n\tuint8_t green;\n\tuint8_t red;\n};\n\ntypedef struct _MMRGBColor MMRGBColor;\n\n/* MMRGBHex is a hexadecimal color value, akin to HTML's, in the form 0xRRGGBB\n * where RR is the red value expressed as hexadecimal, GG is the green value,\n * and BB is the blue value. */\ntypedef uint32_t MMRGBHex;\n\n#define MMRGBHEX_MIN 0x000000\n#define MMRGBHEX_MAX 0xFFFFFF\n\n/* Converts rgb color to hexadecimal value.\n * |red|, |green|, and |blue| should each be of the type |uint8_t|, where the\n * range is 0 - 255. */\n#define RGB_TO_HEX(red, green, blue) (((red) << 16) | ((green) << 8) | (blue))\n\n/* Convenience wrapper for MMRGBColors. */\nH_INLINE MMRGBHex hexFromMMRGB(MMRGBColor rgb)\n{\n\treturn RGB_TO_HEX(rgb.red, rgb.green, rgb.blue);\n}\n\n#define RED_FROM_HEX(hex) ((hex >> 16) & 0xFF)\n#define GREEN_FROM_HEX(hex) ((hex >> 8) & 0xFF)\n#define BLUE_FROM_HEX(hex) (hex & 0xFF)\n\n/* Converts hexadecimal color to MMRGBColor. */\nH_INLINE MMRGBColor MMRGBFromHex(MMRGBHex hex)\n{\n\tMMRGBColor color;\n\tcolor.red = RED_FROM_HEX(hex);\n\tcolor.green = GREEN_FROM_HEX(hex);\n\tcolor.blue = BLUE_FROM_HEX(hex);\n\treturn color;\n}\n\n/* Check absolute equality of two RGB colors. */\n#define MMRGBColorEqualToColor(c1, c2) ((c1).red == (c2).red && \\\n                                        (c1).blue == (c2).blue && \\\n                                        (c1).green == (c2).green)\n\n/* Returns whether two colors are similar within the given range, |tolerance|.\n * Tolerance can be in the range 0.0f - 1.0f, where 0 denotes the exact\n * color and 1 denotes any color. */\nH_INLINE int MMRGBColorSimilarToColor(MMRGBColor c1, MMRGBColor c2,\n                                      float tolerance)\n{\n\t/* Speedy case */\n\tif (tolerance <= 0.0f) {\n\t\treturn MMRGBColorEqualToColor(c1, c2);\n\t} else { /* Otherwise, use a Euclidean space to determine similarity */\n\t\tuint8_t d1 = c1.red - c2.red;\n\t\tuint8_t d2 = c1.green - c2.green;\n\t\tuint8_t d3 = c1.blue - c2.blue;\n\t\treturn sqrt((double)(d1 * d1) +\n\t\t            (d2 * d2) +\n\t\t            (d3 * d3)) <= (tolerance * 442.0f);\n\t}\n\n}\n\n/* Identical to MMRGBColorSimilarToColor, only for hex values. */\nH_INLINE int MMRGBHexSimilarToColor(MMRGBHex h1, MMRGBHex h2, float tolerance)\n{\n\tif (tolerance <= 0.0f) {\n\t\treturn h1 == h2;\n\t} else {\n\t\t// uint8_t d1 = RED_FROM_HEX(h1) - RED_FROM_HEX(h2);\n\t\t// uint8_t d2 = GREEN_FROM_HEX(h1) - GREEN_FROM_HEX(h2);\n\t\t// uint8_t d3 = BLUE_FROM_HEX(h1) - BLUE_FROM_HEX(h2);\n\t\tint d1 = RED_FROM_HEX(h1) - RED_FROM_HEX(h2);\n\t\tint d2 = GREEN_FROM_HEX(h1) - GREEN_FROM_HEX(h2);\n\t\tint d3 = BLUE_FROM_HEX(h1) - BLUE_FROM_HEX(h2);\n\t\treturn sqrt((double)(d1 * d1) +\n\t\t            (d2 * d2) +\n\t\t            (d3 * d3)) <= (tolerance * 442.0f);\n\t}\n}\n\n#endif /* RGB_H */\n"
  },
  {
    "path": "pkg/internal/robotgo/base/snprintf.h",
    "content": "#ifndef _PORTABLE_SNPRINTF_H_\n#define _PORTABLE_SNPRINTF_H_\n\n#define PORTABLE_SNPRINTF_VERSION_MAJOR 2\n#define PORTABLE_SNPRINTF_VERSION_MINOR 2\n\n#include \"os.h\"\n#if defined(IS_MACOSX)\n\t#define HAVE_SNPRINTF\n#else\n\t#define HAVE_SNPRINTF\n\t#define PREFER_PORTABLE_SNPRINTF\n#endif\n\n#include <stddef.h>\n#include <stdarg.h>\n\n#ifdef __cplusplus\nextern \"C\" \n{\n#endif\n\n#ifdef HAVE_SNPRINTF\n#include <stdio.h>\n#else\nextern int snprintf(char *, size_t, const char *, /*args*/ ...);\nextern int vsnprintf(char *, size_t, const char *, va_list);\n#endif\n\n#if defined(HAVE_SNPRINTF) && defined(PREFER_PORTABLE_SNPRINTF)\nextern int portable_snprintf(char *str, size_t str_m, const char *fmt, /*args*/ ...);\nextern int portable_vsnprintf(char *str, size_t str_m, const char *fmt, va_list ap);\n#define snprintf  portable_snprintf\n#define vsnprintf portable_vsnprintf\n#endif\n\nextern int asprintf  (char **ptr, const char *fmt, /*args*/ ...);\nextern int vasprintf (char **ptr, const char *fmt, va_list ap);\nextern int asnprintf (char **ptr, size_t str_m, const char *fmt, /*args*/ ...);\nextern int vasnprintf(char **ptr, size_t str_m, const char *fmt, va_list ap);\n\n#endif\n\n#ifdef __cplusplus\n}\n#endif"
  },
  {
    "path": "pkg/internal/robotgo/base/snprintf_c.h",
    "content": "/*\n * snprintf.c - a portable implementation of snprintf\n *\n * AUTHOR\n *   Mark Martinec <mark.martinec@ijs.si>, April 1999.\n *\n *   Copyright 1999, Mark Martinec. All rights reserved.\n *\n * TERMS AND CONDITIONS\n *   This program is free software; you can redistribute it and/or modify\n *   it under the terms of the \"Frontier Artistic License\" which comes\n *   with this Kit.\n *\n *   This program is distributed in the hope that it will be useful,\n *   but WITHOUT ANY WARRANTY; without even the implied warranty\n *   of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n *   See the Frontier Artistic License for more details.\n *\n *   You should have received a copy of the Frontier Artistic License\n *   with this Kit in the file named LICENSE.txt .\n *   If not, I'll be glad to provide one.\n *\n * FEATURES\n * - careful adherence to specs regarding flags, field width and precision;\n * - good performance for large string handling (large format, large\n *   argument or large paddings). Performance is similar to system's sprintf\n *   and in several cases significantly better (make sure you compile with\n *   optimizations turned on, tell the compiler the code is strict ANSI\n *   if necessary to give it more freedom for optimizations);\n * - return value semantics per ISO/IEC 9899:1999 (\"ISO C99\");\n * - written in standard ISO/ANSI C - requires an ANSI C compiler.\n *\n * SUPPORTED CONVERSION SPECIFIERS AND DATA TYPES\n *\n * This snprintf only supports the following conversion specifiers:\n * s, c, d, u, o, x, X, p  (and synonyms: i, D, U, O - see below)\n * with flags: '-', '+', ' ', '0' and '#'.\n * An asterisk is supported for field width as well as precision.\n *\n * Length modifiers 'h' (short int), 'l' (long int),\n * and 'll' (long long int) are supported.\n * NOTE:\n *   If macro SNPRINTF_LONGLONG_SUPPORT is not defined (default) the\n *   length modifier 'll' is recognized but treated the same as 'l',\n *   which may cause argument value truncation! Defining\n *   SNPRINTF_LONGLONG_SUPPORT requires that your system's sprintf also\n *   handles length modifier 'll'.  long long int is a language extension\n *   which may not be portable.\n *\n * Conversion of numeric data (conversion specifiers d, u, o, x, X, p)\n * with length modifiers (none or h, l, ll) is left to the system routine\n * sprintf, but all handling of flags, field width and precision as well as\n * c and s conversions is done very carefully by this portable routine.\n * If a string precision (truncation) is specified (e.g. %.8s) it is\n * guaranteed the string beyond the specified precision will not be referenced.\n *\n * Length modifiers h, l and ll are ignored for c and s conversions (data\n * types wint_t and wchar_t are not supported).\n *\n * The following common synonyms for conversion characters are supported:\n *   - i is a synonym for d\n *   - D is a synonym for ld, explicit length modifiers are ignored\n *   - U is a synonym for lu, explicit length modifiers are ignored\n *   - O is a synonym for lo, explicit length modifiers are ignored\n * The D, O and U conversion characters are nonstandard, they are supported\n * for backward compatibility only, and should not be used for new code.\n *\n * The following is specifically NOT supported:\n *   - flag ' (thousands' grouping character) is recognized but ignored\n *   - numeric conversion specifiers: f, e, E, g, G and synonym F,\n *     as well as the new a and A conversion specifiers\n *   - length modifier 'L' (long double) and 'q' (quad - use 'll' instead)\n *   - wide character/string conversions: lc, ls, and nonstandard\n *     synonyms C and S\n *   - writeback of converted string length: conversion character n\n *   - the n$ specification for direct reference to n-th argument\n *   - locales\n *\n * It is permitted for str_m to be zero, and it is permitted to specify NULL\n * pointer for resulting string argument if str_m is zero (as per ISO C99).\n *\n * The return value is the number of characters which would be generated\n * for the given input, excluding the trailing null. If this value\n * is greater or equal to str_m, not all characters from the result\n * have been stored in str, output bytes beyond the (str_m-1) -th character\n * are discarded. If str_m is greater than zero it is guaranteed\n * the resulting string will be null-terminated.\n *\n * NOTE that this matches the ISO C99, OpenBSD, and GNU C library 2.1,\n * but is different from some older and vendor implementations,\n * and is also different from XPG, XSH5, SUSv2 specifications.\n * For historical discussion on changes in the semantics and standards\n * of snprintf see printf(3) man page in the Linux programmers manual.\n *\n * Routines asprintf and vasprintf return a pointer (in the ptr argument)\n * to a buffer sufficiently large to hold the resulting string. This pointer\n * should be passed to free(3) to release the allocated storage when it is\n * no longer needed. If sufficient space cannot be allocated, these functions\n * will return -1 and set ptr to be a NULL pointer. These two routines are a\n * GNU C library extensions (glibc).\n *\n * Routines asnprintf and vasnprintf are similar to asprintf and vasprintf,\n * yet, like snprintf and vsnprintf counterparts, will write at most str_m-1\n * characters into the allocated output string, the last character in the\n * allocated buffer then gets the terminating null. If the formatted string\n * length (the return value) is greater than or equal to the str_m argument,\n * the resulting string was truncated and some of the formatted characters\n * were discarded. These routines present a handy way to limit the amount\n * of allocated memory to some sane value.\n *\n * AVAILABILITY\n *   http://www.ijs.si/software/snprintf/\n *\n * REVISION HISTORY\n * 1999-04\tV0.9  Mark Martinec\n *\t\t- initial version, some modifications after comparing printf\n *\t\t  man pages for Digital Unix 4.0, Solaris 2.6 and HPUX 10,\n *\t\t  and checking how Perl handles sprintf (differently!);\n * 1999-04-09\tV1.0  Mark Martinec <mark.martinec@ijs.si>\n *\t\t- added main test program, fixed remaining inconsistencies,\n *\t\t  added optional (long long int) support;\n * 1999-04-12\tV1.1  Mark Martinec <mark.martinec@ijs.si>\n *\t\t- support the 'p' conversion (pointer to void);\n *\t\t- if a string precision is specified\n *\t\t  make sure the string beyond the specified precision\n *\t\t  will not be referenced (e.g. by strlen);\n * 1999-04-13\tV1.2  Mark Martinec <mark.martinec@ijs.si>\n *\t\t- support synonyms %D=%ld, %U=%lu, %O=%lo;\n *\t\t- speed up the case of long format string with few conversions;\n * 1999-06-30\tV1.3  Mark Martinec <mark.martinec@ijs.si>\n *\t\t- fixed runaway loop (eventually crashing when str_l wraps\n *\t\t  beyond 2^31) while copying format string without\n *\t\t  conversion specifiers to a buffer that is too short\n *\t\t  (thanks to Edwin Young <edwiny@autonomy.com> for\n *\t\t  spotting the problem);\n *\t\t- added macros PORTABLE_SNPRINTF_VERSION_(MAJOR|MINOR)\n *\t\t  to snprintf.h\n * 2000-02-14\tV2.0 (never released) Mark Martinec <mark.martinec@ijs.si>\n *\t\t- relaxed license terms: The Artistic License now applies.\n *\t\t  You may still apply the GNU GENERAL PUBLIC LICENSE\n *\t\t  as was distributed with previous versions, if you prefer;\n *\t\t- changed REVISION HISTORY dates to use ISO 8601 date format;\n *\t\t- added vsnprintf (patch also independently proposed by\n *\t\t  Caolan McNamara 2000-05-04, and Keith M Willenson 2000-06-01)\n * 2000-06-27\tV2.1  Mark Martinec <mark.martinec@ijs.si>\n *\t\t- removed POSIX check for str_m<1; value 0 for str_m is\n *\t\t  allowed by ISO C99 (and GNU C library 2.1) - (pointed out\n *\t\t  on 2000-05-04 by Caolan McNamara, caolan@ csn dot ul dot ie).\n *\t\t  Besides relaxed license this change in standards adherence\n *\t\t  is the main reason to bump up the major version number;\n *\t\t- added nonstandard routines asnprintf, vasnprintf, asprintf,\n *\t\t  vasprintf that dynamically allocate storage for the\n *\t\t  resulting string; these routines are not compiled by default,\n *\t\t  see comments where NEED_V?ASN?PRINTF macros are defined;\n *\t\t- autoconf contributed by Caolan McNamara\n * 2000-10-06\tV2.2  Mark Martinec <mark.martinec@ijs.si>\n *\t\t- BUG FIX: the %c conversion used a temporary variable\n *\t\t  that was no longer in scope when referenced,\n *\t\t  possibly causing incorrect resulting character;\n *\t\t- BUG FIX: make precision and minimal field width unsigned\n *\t\t  to handle huge values (2^31 <= n < 2^32) correctly;\n *\t\t  also be more careful in the use of signed/unsigned/size_t\n *\t\t  internal variables - probably more careful than many\n *\t\t  vendor implementations, but there may still be a case\n *\t\t  where huge values of str_m, precision or minimal field\n *\t\t  could cause incorrect behaviour;\n *\t\t- use separate variables for signed/unsigned arguments,\n *\t\t  and for short/int, long, and long long argument lengths\n *\t\t  to avoid possible incompatibilities on certain\n *\t\t  computer architectures. Also use separate variable\n *\t\t  arg_sign to hold sign of a numeric argument,\n *\t\t  to make code more transparent;\n *\t\t- some fiddling with zero padding and \"0x\" to make it\n *\t\t  Linux compatible;\n *\t\t- systematically use macros fast_memcpy and fast_memset\n *\t\t  instead of case-by-case hand optimization; determine some\n *\t\t  breakeven string lengths for different architectures;\n *\t\t- terminology change: 'format' -> 'conversion specifier',\n *\t\t  'C9x' -> 'ISO/IEC 9899:1999 (\"ISO C99\")',\n *\t\t  'alternative form' -> 'alternate form',\n *\t\t  'data type modifier' -> 'length modifier';\n *\t\t- several comments rephrased and new ones added;\n *\t\t- make compiler not complain about 'credits' defined but\n *\t\t  not used;\n */\n\n\n/* Define HAVE_SNPRINTF if your system already has snprintf and vsnprintf.\n *\n * If HAVE_SNPRINTF is defined this module will not produce code for\n * snprintf and vsnprintf, unless PREFER_PORTABLE_SNPRINTF is defined as well,\n * causing this portable version of snprintf to be called portable_snprintf\n * (and portable_vsnprintf).\n */\n/* #define HAVE_SNPRINTF */\n\n/* Define PREFER_PORTABLE_SNPRINTF if your system does have snprintf and\n * vsnprintf but you would prefer to use the portable routine(s) instead.\n * In this case the portable routine is declared as portable_snprintf\n * (and portable_vsnprintf) and a macro 'snprintf' (and 'vsnprintf')\n * is defined to expand to 'portable_v?snprintf' - see file snprintf.h .\n * Defining this macro is only useful if HAVE_SNPRINTF is also defined,\n * but does does no harm if defined nevertheless.\n */\n/* #define PREFER_PORTABLE_SNPRINTF */\n\n/* Define SNPRINTF_LONGLONG_SUPPORT if you want to support\n * data type (long long int) and length modifier 'll' (e.g. %lld).\n * If undefined, 'll' is recognized but treated as a single 'l'.\n *\n * If the system's sprintf does not handle 'll'\n * the SNPRINTF_LONGLONG_SUPPORT must not be defined!\n *\n * This is off by default as (long long int) is a language extension.\n */\n/* #define SNPRINTF_LONGLONG_SUPPORT */\n\n/* Define NEED_SNPRINTF_ONLY if you only need snprintf, and not vsnprintf.\n * If NEED_SNPRINTF_ONLY is defined, the snprintf will be defined directly,\n * otherwise both snprintf and vsnprintf routines will be defined\n * and snprintf will be a simple wrapper around vsnprintf, at the expense\n * of an extra procedure call.\n */\n/* #define NEED_SNPRINTF_ONLY */\n\n/* Define NEED_V?ASN?PRINTF macros if you need library extension\n * routines asprintf, vasprintf, asnprintf, vasnprintf respectively,\n * and your system library does not provide them. They are all small\n * wrapper routines around portable_vsnprintf. Defining any of the four\n * NEED_V?ASN?PRINTF macros automatically turns off NEED_SNPRINTF_ONLY\n * and turns on PREFER_PORTABLE_SNPRINTF.\n *\n * Watch for name conflicts with the system library if these routines\n * are already present there.\n *\n * NOTE: vasprintf and vasnprintf routines need va_copy() from stdarg.h, as\n * specified by C99, to be able to traverse the same list of arguments twice.\n * I don't know of any other standard and portable way of achieving the same.\n * With some versions of gcc you may use __va_copy(). You might even get away\n * with \"ap2 = ap\", in this case you must not call va_end(ap2) !\n *   #define va_copy(ap2,ap) ap2 = ap\n */\n/* #define NEED_ASPRINTF   */\n/* #define NEED_ASNPRINTF  */\n/* #define NEED_VASPRINTF  */\n/* #define NEED_VASNPRINTF */\n\n\n/* Define the following macros if desired:\n *   SOLARIS_COMPATIBLE, SOLARIS_BUG_COMPATIBLE,\n *   HPUX_COMPATIBLE, HPUX_BUG_COMPATIBLE, LINUX_COMPATIBLE,\n *   DIGITAL_UNIX_COMPATIBLE, DIGITAL_UNIX_BUG_COMPATIBLE,\n *   PERL_COMPATIBLE, PERL_BUG_COMPATIBLE,\n *\n * - For portable applications it is best not to rely on peculiarities\n *   of a given implementation so it may be best not to define any\n *   of the macros that select compatibility and to avoid features\n *   that vary among the systems.\n *\n * - Selecting compatibility with more than one operating system\n *   is not strictly forbidden but is not recommended.\n *\n * - 'x'_BUG_COMPATIBLE implies 'x'_COMPATIBLE .\n *\n * - 'x'_COMPATIBLE refers to (and enables) a behaviour that is\n *   documented in a sprintf man page on a given operating system\n *   and actually adhered to by the system's sprintf (but not on\n *   most other operating systems). It may also refer to and enable\n *   a behaviour that is declared 'undefined' or 'implementation specific'\n *   in the man page but a given implementation behaves predictably\n *   in a certain way.\n *\n * - 'x'_BUG_COMPATIBLE refers to (and enables) a behaviour of system's sprintf\n *   that contradicts the sprintf man page on the same operating system.\n *\n * - I do not claim that the 'x'_COMPATIBLE and 'x'_BUG_COMPATIBLE\n *   conditionals take into account all idiosyncrasies of a particular\n *   implementation, there may be other incompatibilities.\n */\n\n\n\f\n/* ============================================= */\n/* NO USER SERVICABLE PARTS FOLLOWING THIS POINT */\n/* ============================================= */\n\n#define PORTABLE_SNPRINTF_VERSION_MAJOR 2\n#define PORTABLE_SNPRINTF_VERSION_MINOR 2\n\n#if defined(NEED_ASPRINTF) || defined(NEED_ASNPRINTF) || defined(NEED_VASPRINTF) || defined(NEED_VASNPRINTF)\n# if defined(NEED_SNPRINTF_ONLY)\n# undef NEED_SNPRINTF_ONLY\n# endif\n# if !defined(PREFER_PORTABLE_SNPRINTF)\n# define PREFER_PORTABLE_SNPRINTF\n# endif\n#endif\n\n#if defined(SOLARIS_BUG_COMPATIBLE) && !defined(SOLARIS_COMPATIBLE)\n#define SOLARIS_COMPATIBLE\n#endif\n\n#if defined(HPUX_BUG_COMPATIBLE) && !defined(HPUX_COMPATIBLE)\n#define HPUX_COMPATIBLE\n#endif\n\n#if defined(DIGITAL_UNIX_BUG_COMPATIBLE) && !defined(DIGITAL_UNIX_COMPATIBLE)\n#define DIGITAL_UNIX_COMPATIBLE\n#endif\n\n#if defined(PERL_BUG_COMPATIBLE) && !defined(PERL_COMPATIBLE)\n#define PERL_COMPATIBLE\n#endif\n\n#if defined(LINUX_BUG_COMPATIBLE) && !defined(LINUX_COMPATIBLE)\n#define LINUX_COMPATIBLE\n#endif\n\n#include \"snprintf.h\"\n#include <sys/types.h>\n#include <string.h>\n#include <stdlib.h>\n#include <stdio.h>\n#include <stdarg.h>\n#include <assert.h>\n#include <errno.h>\n\n#ifdef isdigit\n#undef isdigit\n#endif\n#define isdigit(c) ((c) >= '0' && (c) <= '9')\n\n/* For copying strings longer or equal to 'breakeven_point'\n * it is more efficient to call memcpy() than to do it inline.\n * The value depends mostly on the processor architecture,\n * but also on the compiler and its optimization capabilities.\n * The value is not critical, some small value greater than zero\n * will be just fine if you don't care to squeeze every drop\n * of performance out of the code.\n *\n * Small values favor memcpy, large values favor inline code.\n */\n#if defined(__alpha__) || defined(__alpha)\n#  define breakeven_point   2\t/* AXP (DEC Alpha)     - gcc or cc or egcs */\n#endif\n#if defined(__i386__)  || defined(__i386)\n#  define breakeven_point  12\t/* Intel Pentium/Linux - gcc 2.96 */\n#endif\n#if defined(__hppa)\n#  define breakeven_point  10\t/* HP-PA               - gcc */\n#endif\n#if defined(__sparc__) || defined(__sparc)\n#  define breakeven_point  33\t/* Sun Sparc 5         - gcc 2.8.1 */\n#endif\n\n/* some other values of possible interest: */\n/* #define breakeven_point  8 */  /* VAX 4000          - vaxc */\n/* #define breakeven_point 19 */  /* VAX 4000          - gcc 2.7.0 */\n\n#ifndef breakeven_point\n#  define breakeven_point   6\t/* some reasonable one-size-fits-all value */\n#endif\n\n#define fast_memcpy(d,s,n) \\\n  { register size_t nn = (size_t)(n); \\\n    if (nn >= breakeven_point) memcpy((d), (s), nn); \\\n    else if (nn > 0) { /* proc call overhead is worth only for large strings*/\\\n      register char *dd; register const char *ss; \\\n      for (ss=(s), dd=(d); nn>0; nn--) *dd++ = *ss++; } }\n\n#define fast_memset(d,c,n) \\\n  { register size_t nn = (size_t)(n); \\\n    if (nn >= breakeven_point) memset((d), (int)(c), nn); \\\n    else if (nn > 0) { /* proc call overhead is worth only for large strings*/\\\n      register char *dd; register const int cc=(int)(c); \\\n      for (dd=(d); nn>0; nn--) *dd++ = cc; } }\n\n/* prototypes */\n\n#if defined(NEED_ASPRINTF)\nint asprintf   (char **ptr, const char *fmt, /*args*/ ...);\n#endif\n#if defined(NEED_VASPRINTF)\nint vasprintf  (char **ptr, const char *fmt, va_list ap);\n#endif\n#if defined(NEED_ASNPRINTF)\nint asnprintf  (char **ptr, size_t str_m, const char *fmt, /*args*/ ...);\n#endif\n#if defined(NEED_VASNPRINTF)\nint vasnprintf (char **ptr, size_t str_m, const char *fmt, va_list ap);\n#endif\n\n#if defined(HAVE_SNPRINTF)\n/* declare our portable snprintf  routine under name portable_snprintf  */\n/* declare our portable vsnprintf routine under name portable_vsnprintf */\n#else\n/* declare our portable routines under names snprintf and vsnprintf */\n#define portable_snprintf snprintf\n#if !defined(NEED_SNPRINTF_ONLY)\n#define portable_vsnprintf vsnprintf\n#endif\n#endif\n\n#if !defined(HAVE_SNPRINTF) || defined(PREFER_PORTABLE_SNPRINTF)\nint portable_snprintf(char *str, size_t str_m, const char *fmt, /*args*/ ...);\n#if !defined(NEED_SNPRINTF_ONLY)\nint portable_vsnprintf(char *str, size_t str_m, const char *fmt, va_list ap);\n#endif\n#endif\n\n/* declarations */\n\n#if defined(NEED_ASPRINTF)\nint asprintf(char **ptr, const char *fmt, /*args*/ ...) {\n  va_list ap;\n  size_t str_m;\n  int str_l;\n\n  *ptr = NULL;\n  va_start(ap, fmt);                            /* measure the required size */\n  str_l = portable_vsnprintf(NULL, (size_t)0, fmt, ap);\n  va_end(ap);\n  assert(str_l >= 0);        /* possible integer overflow if str_m > INT_MAX */\n  *ptr = (char *) malloc(str_m = (size_t)str_l + 1);\n  if (*ptr == NULL) { errno = ENOMEM; str_l = -1; }\n  else {\n    int str_l2;\n    va_start(ap, fmt);\n    str_l2 = portable_vsnprintf(*ptr, str_m, fmt, ap);\n    va_end(ap);\n    assert(str_l2 == str_l);\n  }\n  return str_l;\n}\n#endif\n\n#if defined(NEED_VASPRINTF)\nint vasprintf(char **ptr, const char *fmt, va_list ap) {\n  size_t str_m;\n  int str_l;\n\n  *ptr = NULL;\n  { va_list ap2;\n    va_copy(ap2, ap);  /* don't consume the original ap, we'll need it again */\n    str_l = portable_vsnprintf(NULL, (size_t)0, fmt, ap2);/*get required size*/\n    va_end(ap2);\n  }\n  assert(str_l >= 0);        /* possible integer overflow if str_m > INT_MAX */\n  *ptr = (char *) malloc(str_m = (size_t)str_l + 1);\n  if (*ptr == NULL) { errno = ENOMEM; str_l = -1; }\n  else {\n    int str_l2 = portable_vsnprintf(*ptr, str_m, fmt, ap);\n    assert(str_l2 == str_l);\n  }\n  return str_l;\n}\n#endif\n\n#if defined(NEED_ASNPRINTF)\nint asnprintf (char **ptr, size_t str_m, const char *fmt, /*args*/ ...) {\n  va_list ap;\n  int str_l;\n\n  *ptr = NULL;\n  va_start(ap, fmt);                            /* measure the required size */\n  str_l = portable_vsnprintf(NULL, (size_t)0, fmt, ap);\n  va_end(ap);\n  assert(str_l >= 0);        /* possible integer overflow if str_m > INT_MAX */\n  if ((size_t)str_l + 1 < str_m) str_m = (size_t)str_l + 1;      /* truncate */\n  /* if str_m is 0, no buffer is allocated, just set *ptr to NULL */\n  if (str_m == 0) {  /* not interested in resulting string, just return size */\n  } else {\n    *ptr = (char *) malloc(str_m);\n    if (*ptr == NULL) { errno = ENOMEM; str_l = -1; }\n    else {\n      int str_l2;\n      va_start(ap, fmt);\n      str_l2 = portable_vsnprintf(*ptr, str_m, fmt, ap);\n      va_end(ap);\n      assert(str_l2 == str_l);\n    }\n  }\n  return str_l;\n}\n#endif\n\n#if defined(NEED_VASNPRINTF)\nint vasnprintf (char **ptr, size_t str_m, const char *fmt, va_list ap) {\n  int str_l;\n\n  *ptr = NULL;\n  { va_list ap2;\n    va_copy(ap2, ap);  /* don't consume the original ap, we'll need it again */\n    str_l = portable_vsnprintf(NULL, (size_t)0, fmt, ap2);/*get required size*/\n    va_end(ap2);\n  }\n  assert(str_l >= 0);        /* possible integer overflow if str_m > INT_MAX */\n  if ((size_t)str_l + 1 < str_m) str_m = (size_t)str_l + 1;      /* truncate */\n  /* if str_m is 0, no buffer is allocated, just set *ptr to NULL */\n  if (str_m == 0) {  /* not interested in resulting string, just return size */\n  } else {\n    *ptr = (char *) malloc(str_m);\n    if (*ptr == NULL) { errno = ENOMEM; str_l = -1; }\n    else {\n      int str_l2 = portable_vsnprintf(*ptr, str_m, fmt, ap);\n      assert(str_l2 == str_l);\n    }\n  }\n  return str_l;\n}\n#endif\n\n/*\n * If the system does have snprintf and the portable routine is not\n * specifically required, this module produces no code for snprintf/vsnprintf.\n */\n#if !defined(HAVE_SNPRINTF) || defined(PREFER_PORTABLE_SNPRINTF)\n\n#if !defined(NEED_SNPRINTF_ONLY)\nint portable_snprintf(char *str, size_t str_m, const char *fmt, /*args*/ ...) {\n  va_list ap;\n  int str_l;\n\n  va_start(ap, fmt);\n  str_l = portable_vsnprintf(str, str_m, fmt, ap);\n  va_end(ap);\n  return str_l;\n}\n#endif\n\n#if defined(NEED_SNPRINTF_ONLY)\nint portable_snprintf(char *str, size_t str_m, const char *fmt, /*args*/ ...) {\n#else\nint portable_vsnprintf(char *str, size_t str_m, const char *fmt, va_list ap) {\n#endif\n\n#if defined(NEED_SNPRINTF_ONLY)\n  va_list ap;\n#endif\n  size_t str_l = 0;\n  const char *p = fmt;\n\n/* In contrast with POSIX, the ISO C99 now says\n * that str can be NULL and str_m can be 0.\n * This is more useful than the old:  if (str_m < 1) return -1; */\n\n#if defined(NEED_SNPRINTF_ONLY)\n  va_start(ap, fmt);\n#endif\n  if (!p) p = \"\";\n  while (*p) {\n    if (*p != '%') {\n   /* if (str_l < str_m) str[str_l++] = *p++;    -- this would be sufficient */\n   /* but the following code achieves better performance for cases\n    * where format string is long and contains few conversions */\n      const char *q = strchr(p+1,'%');\n      size_t n = !q ? strlen(p) : (q-p);\n      if (str_l < str_m) {\n        size_t avail = str_m-str_l;\n        fast_memcpy(str+str_l, p, (n>avail?avail:n));\n      }\n      p += n; str_l += n;\n    } else {\n      const char *starting_p;\n      size_t min_field_width = 0, precision = 0;\n      int zero_padding = 0, precision_specified = 0, justify_left = 0;\n      int alternate_form = 0, force_sign = 0;\n      int space_for_positive = 1; /* If both the ' ' and '+' flags appear,\n                                     the ' ' flag should be ignored. */\n      char length_modifier = '\\0';            /* allowed values: \\0, h, l, L */\n      char tmp[32];/* temporary buffer for simple numeric->string conversion */\n\n      const char *str_arg;      /* string address in case of string argument */\n      size_t str_arg_l;         /* natural field width of arg without padding\n                                   and sign */\n      unsigned char uchar_arg;\n        /* unsigned char argument value - only defined for c conversion.\n           N.B. standard explicitly states the char argument for\n           the c conversion is unsigned */\n\n      size_t number_of_zeros_to_pad = 0;\n        /* number of zeros to be inserted for numeric conversions\n           as required by the precision or minimal field width */\n\n      size_t zero_padding_insertion_ind = 0;\n        /* index into tmp where zero padding is to be inserted */\n\n      char fmt_spec = '\\0';\n        /* current conversion specifier character */\n\n      starting_p = p; p++;  /* skip '%' */\n   /* parse flags */\n      while (*p == '0' || *p == '-' || *p == '+' ||\n             *p == ' ' || *p == '#' || *p == '\\'') {\n        switch (*p) {\n        case '0': zero_padding = 1; break;\n        case '-': justify_left = 1; break;\n        case '+': force_sign = 1; space_for_positive = 0; break;\n        case ' ': force_sign = 1;\n     /* If both the ' ' and '+' flags appear, the ' ' flag should be ignored */\n#ifdef PERL_COMPATIBLE\n     /* ... but in Perl the last of ' ' and '+' applies */\n                  space_for_positive = 1;\n#endif\n                  break;\n        case '#': alternate_form = 1; break;\n        case '\\'': break;\n        }\n        p++;\n      }\n   /* If the '0' and '-' flags both appear, the '0' flag should be ignored. */\n\n   /* parse field width */\n      if (*p == '*') {\n        int j;\n        p++; j = va_arg(ap, int);\n        if (j >= 0) min_field_width = j;\n        else { min_field_width = -j; justify_left = 1; }\n      } else if (isdigit((int)(*p))) {\n        /* size_t could be wider than unsigned int;\n           make sure we treat argument like common implementations do */\n        unsigned int uj = *p++ - '0';\n        while (isdigit((int)(*p))) uj = 10*uj + (unsigned int)(*p++ - '0');\n        min_field_width = uj;\n      }\n   /* parse precision */\n      if (*p == '.') {\n        p++; precision_specified = 1;\n        if (*p == '*') {\n          int j = va_arg(ap, int);\n          p++;\n          if (j >= 0) precision = j;\n          else {\n            precision_specified = 0; precision = 0;\n         /* NOTE:\n          *   Solaris 2.6 man page claims that in this case the precision\n          *   should be set to 0.  Digital Unix 4.0, HPUX 10 and BSD man page\n          *   claim that this case should be treated as unspecified precision,\n          *   which is what we do here.\n          */\n          }\n        } else if (isdigit((int)(*p))) {\n          /* size_t could be wider than unsigned int;\n             make sure we treat argument like common implementations do */\n          unsigned int uj = *p++ - '0';\n          while (isdigit((int)(*p))) uj = 10*uj + (unsigned int)(*p++ - '0');\n          precision = uj;\n        }\n      }\n   /* parse 'h', 'l' and 'll' length modifiers */\n      if (*p == 'h' || *p == 'l') {\n        length_modifier = *p; p++;\n        if (length_modifier == 'l' && *p == 'l') {   /* double l = long long */\n#ifdef SNPRINTF_LONGLONG_SUPPORT\n          length_modifier = '2';                  /* double l encoded as '2' */\n#else\n          length_modifier = 'l';                 /* treat it as a single 'l' */\n#endif\n          p++;\n        }\n      }\n      fmt_spec = *p;\n   /* common synonyms: */\n      switch (fmt_spec) {\n      case 'i': fmt_spec = 'd'; break;\n      case 'D': fmt_spec = 'd'; length_modifier = 'l'; break;\n      case 'U': fmt_spec = 'u'; length_modifier = 'l'; break;\n      case 'O': fmt_spec = 'o'; length_modifier = 'l'; break;\n      default: break;\n      }\n   /* get parameter value, do initial processing */\n      switch (fmt_spec) {\n      case '%': /* % behaves similar to 's' regarding flags and field widths */\n      case 'c': /* c behaves similar to 's' regarding flags and field widths */\n      case 's':\n        length_modifier = '\\0';          /* wint_t and wchar_t not supported */\n     /* the result of zero padding flag with non-numeric conversion specifier*/\n     /* is undefined. Solaris and HPUX 10 does zero padding in this case,    */\n     /* Digital Unix and Linux does not. */\n#if !defined(SOLARIS_COMPATIBLE) && !defined(HPUX_COMPATIBLE)\n        zero_padding = 0;    /* turn zero padding off for string conversions */\n#endif\n        str_arg_l = 1;\n        switch (fmt_spec) {\n        case '%':\n          str_arg = p; break;\n        case 'c': {\n          int j = va_arg(ap, int);\n          uchar_arg = (unsigned char) j;   /* standard demands unsigned char */\n          str_arg = (const char *) &uchar_arg;\n          break;\n        }\n        case 's':\n          str_arg = va_arg(ap, const char *);\n          if (!str_arg) str_arg_l = 0;\n       /* make sure not to address string beyond the specified precision !!! */\n          else if (!precision_specified) str_arg_l = strlen(str_arg);\n       /* truncate string if necessary as requested by precision */\n          else if (precision == 0) str_arg_l = 0;\n          else {\n       /* memchr on HP does not like n > 2^31  !!! */\n            const char *q = memchr(str_arg, '\\0',\n                             precision <= 0x7fffffff ? precision : 0x7fffffff);\n            str_arg_l = !q ? precision : (q-str_arg);\n          }\n          break;\n        default: break;\n        }\n        break;\n      case 'd': case 'u': case 'o': case 'x': case 'X': case 'p': {\n        /* NOTE: the u, o, x, X and p conversion specifiers imply\n                 the value is unsigned;  d implies a signed value */\n\n        int arg_sign = 0;\n          /* 0 if numeric argument is zero (or if pointer is NULL for 'p'),\n            +1 if greater than zero (or nonzero for unsigned arguments),\n            -1 if negative (unsigned argument is never negative) */\n\n        int int_arg = 0;  unsigned int uint_arg = 0;\n          /* only defined for length modifier h, or for no length modifiers */\n\n        long int long_arg = 0;  unsigned long int ulong_arg = 0;\n          /* only defined for length modifier l */\n\n        void *ptr_arg = NULL;\n          /* pointer argument value -only defined for p conversion */\n\n#ifdef SNPRINTF_LONGLONG_SUPPORT\n        long long int long_long_arg = 0;\n        unsigned long long int ulong_long_arg = 0;\n          /* only defined for length modifier ll */\n#endif\n        if (fmt_spec == 'p') {\n        /* HPUX 10: An l, h, ll or L before any other conversion character\n         *   (other than d, i, u, o, x, or X) is ignored.\n         * Digital Unix:\n         *   not specified, but seems to behave as HPUX does.\n         * Solaris: If an h, l, or L appears before any other conversion\n         *   specifier (other than d, i, u, o, x, or X), the behavior\n         *   is undefined. (Actually %hp converts only 16-bits of address\n         *   and %llp treats address as 64-bit data which is incompatible\n         *   with (void *) argument on a 32-bit system).\n         */\n#ifdef SOLARIS_COMPATIBLE\n#  ifdef SOLARIS_BUG_COMPATIBLE\n          /* keep length modifiers even if it represents 'll' */\n#  else\n          if (length_modifier == '2') length_modifier = '\\0';\n#  endif\n#else\n          length_modifier = '\\0';\n#endif\n          ptr_arg = va_arg(ap, void *);\n          if (ptr_arg != NULL) arg_sign = 1;\n        } else if (fmt_spec == 'd') {  /* signed */\n          switch (length_modifier) {\n          case '\\0':\n          case 'h':\n         /* It is non-portable to specify a second argument of char or short\n          * to va_arg, because arguments seen by the called function\n          * are not char or short.  C converts char and short arguments\n          * to int before passing them to a function.\n          */\n            int_arg = va_arg(ap, int);\n            if      (int_arg > 0) arg_sign =  1;\n            else if (int_arg < 0) arg_sign = -1;\n            break;\n          case 'l':\n            long_arg = va_arg(ap, long int);\n            if      (long_arg > 0) arg_sign =  1;\n            else if (long_arg < 0) arg_sign = -1;\n            break;\n#ifdef SNPRINTF_LONGLONG_SUPPORT\n          case '2':\n            long_long_arg = va_arg(ap, long long int);\n            if      (long_long_arg > 0) arg_sign =  1;\n            else if (long_long_arg < 0) arg_sign = -1;\n            break;\n#endif\n          }\n        } else {  /* unsigned */\n          switch (length_modifier) {\n          case '\\0':\n          case 'h':\n            uint_arg = va_arg(ap, unsigned int);\n            if (uint_arg) arg_sign = 1;\n            break;\n          case 'l':\n            ulong_arg = va_arg(ap, unsigned long int);\n            if (ulong_arg) arg_sign = 1;\n            break;\n#ifdef SNPRINTF_LONGLONG_SUPPORT\n          case '2':\n            ulong_long_arg = va_arg(ap, unsigned long long int);\n            if (ulong_long_arg) arg_sign = 1;\n            break;\n#endif\n          }\n        }\n        str_arg = tmp; str_arg_l = 0;\n     /* NOTE:\n      *   For d, i, u, o, x, and X conversions, if precision is specified,\n      *   the '0' flag should be ignored. This is so with Solaris 2.6,\n      *   Digital UNIX 4.0, HPUX 10, Linux, FreeBSD, NetBSD; but not with Perl.\n      */\n#ifndef PERL_COMPATIBLE\n        if (precision_specified) zero_padding = 0;\n#endif\n        if (fmt_spec == 'd') {\n          if (force_sign && arg_sign >= 0)\n            tmp[str_arg_l++] = space_for_positive ? ' ' : '+';\n         /* leave negative numbers for sprintf to handle,\n            to avoid handling tricky cases like (short int)(-32768) */\n#ifdef LINUX_COMPATIBLE\n        } else if (fmt_spec == 'p' && force_sign && arg_sign > 0) {\n          tmp[str_arg_l++] = space_for_positive ? ' ' : '+';\n#endif\n        } else if (alternate_form) {\n          if (arg_sign != 0 && (fmt_spec == 'x' || fmt_spec == 'X') )\n            { tmp[str_arg_l++] = '0'; tmp[str_arg_l++] = fmt_spec; }\n         /* alternate form should have no effect for p conversion, but ... */\n#ifdef HPUX_COMPATIBLE\n          else if (fmt_spec == 'p'\n         /* HPUX 10: for an alternate form of p conversion,\n          *          a nonzero result is prefixed by 0x. */\n#ifndef HPUX_BUG_COMPATIBLE\n         /* Actually it uses 0x prefix even for a zero value. */\n                   && arg_sign != 0\n#endif\n                  ) { tmp[str_arg_l++] = '0'; tmp[str_arg_l++] = 'x'; }\n#endif\n        }\n        zero_padding_insertion_ind = str_arg_l;\n        if (!precision_specified) precision = 1;   /* default precision is 1 */\n        if (precision == 0 && arg_sign == 0\n#if defined(HPUX_BUG_COMPATIBLE) || defined(LINUX_COMPATIBLE)\n            && fmt_spec != 'p'\n         /* HPUX 10 man page claims: With conversion character p the result of\n          * converting a zero value with a precision of zero is a null string.\n          * Actually HP returns all zeroes, and Linux returns \"(nil)\". */\n#endif\n        ) {\n         /* converted to null string */\n         /* When zero value is formatted with an explicit precision 0,\n            the resulting formatted string is empty (d, i, u, o, x, X, p).   */\n        } else {\n          char f[5]; int f_l = 0;\n          f[f_l++] = '%';    /* construct a simple format string for sprintf */\n          if (!length_modifier) { }\n          else if (length_modifier=='2') { f[f_l++] = 'l'; f[f_l++] = 'l'; }\n          else f[f_l++] = length_modifier;\n          f[f_l++] = fmt_spec; f[f_l++] = '\\0';\n          if (fmt_spec == 'p') str_arg_l += sprintf(tmp+str_arg_l, f, ptr_arg);\n          else if (fmt_spec == 'd') {  /* signed */\n            switch (length_modifier) {\n            case '\\0':\n            case 'h': str_arg_l+=sprintf(tmp+str_arg_l, f, int_arg);  break;\n            case 'l': str_arg_l+=sprintf(tmp+str_arg_l, f, long_arg); break;\n#ifdef SNPRINTF_LONGLONG_SUPPORT\n            case '2': str_arg_l+=sprintf(tmp+str_arg_l,f,long_long_arg); break;\n#endif\n            }\n          } else {  /* unsigned */\n            switch (length_modifier) {\n            case '\\0':\n            case 'h': str_arg_l+=sprintf(tmp+str_arg_l, f, uint_arg);  break;\n            case 'l': str_arg_l+=sprintf(tmp+str_arg_l, f, ulong_arg); break;\n#ifdef SNPRINTF_LONGLONG_SUPPORT\n            case '2': str_arg_l+=sprintf(tmp+str_arg_l,f,ulong_long_arg);break;\n#endif\n            }\n          }\n         /* include the optional minus sign and possible \"0x\"\n            in the region before the zero padding insertion point */\n          if (zero_padding_insertion_ind < str_arg_l &&\n              tmp[zero_padding_insertion_ind] == '-') {\n            zero_padding_insertion_ind++;\n          }\n          if (zero_padding_insertion_ind+1 < str_arg_l &&\n              tmp[zero_padding_insertion_ind]   == '0' &&\n             (tmp[zero_padding_insertion_ind+1] == 'x' ||\n              tmp[zero_padding_insertion_ind+1] == 'X') ) {\n            zero_padding_insertion_ind += 2;\n          }\n        }\n        { size_t num_of_digits = str_arg_l - zero_padding_insertion_ind;\n          if (alternate_form && fmt_spec == 'o'\n#ifdef HPUX_COMPATIBLE                                  /* (\"%#.o\",0) -> \"\"  */\n              && (str_arg_l > 0)\n#endif\n#ifdef DIGITAL_UNIX_BUG_COMPATIBLE                      /* (\"%#o\",0) -> \"00\" */\n#else\n              /* unless zero is already the first character */\n              && !(zero_padding_insertion_ind < str_arg_l\n                   && tmp[zero_padding_insertion_ind] == '0')\n#endif\n          ) {        /* assure leading zero for alternate-form octal numbers */\n            if (!precision_specified || precision < num_of_digits+1) {\n             /* precision is increased to force the first character to be zero,\n                except if a zero value is formatted with an explicit precision\n                of zero */\n              precision = num_of_digits+1; precision_specified = 1;\n            }\n          }\n       /* zero padding to specified precision? */\n          if (num_of_digits < precision) \n            number_of_zeros_to_pad = precision - num_of_digits;\n        }\n     /* zero padding to specified minimal field width? */\n        if (!justify_left && zero_padding) {\n          int n = min_field_width - (str_arg_l+number_of_zeros_to_pad);\n          if (n > 0) number_of_zeros_to_pad += n;\n        }\n        break;\n      }\n      default: /* unrecognized conversion specifier, keep format string as-is*/\n        zero_padding = 0;  /* turn zero padding off for non-numeric convers. */\n#ifndef DIGITAL_UNIX_COMPATIBLE\n        justify_left = 1; min_field_width = 0;                /* reset flags */\n#endif\n#if defined(PERL_COMPATIBLE) || defined(LINUX_COMPATIBLE)\n     /* keep the entire format string unchanged */\n        str_arg = starting_p; str_arg_l = p - starting_p;\n     /* well, not exactly so for Linux, which does something inbetween,\n      * and I don't feel an urge to imitate it: \"%+++++hy\" -> \"%+y\"  */\n#else\n     /* discard the unrecognized conversion, just keep *\n      * the unrecognized conversion character          */\n        str_arg = p; str_arg_l = 0;\n#endif\n        if (*p) str_arg_l++;  /* include invalid conversion specifier unchanged\n                                 if not at end-of-string */\n        break;\n      }\n      if (*p) p++;      /* step over the just processed conversion specifier */\n   /* insert padding to the left as requested by min_field_width;\n      this does not include the zero padding in case of numerical conversions*/\n      if (!justify_left) {                /* left padding with blank or zero */\n        int n = min_field_width - (str_arg_l+number_of_zeros_to_pad);\n        if (n > 0) {\n          if (str_l < str_m) {\n            size_t avail = str_m-str_l;\n            fast_memset(str+str_l, (zero_padding?'0':' '), (n>avail?avail:n));\n          }\n          str_l += n;\n        }\n      }\n   /* zero padding as requested by the precision or by the minimal field width\n    * for numeric conversions required? */\n      if (number_of_zeros_to_pad <= 0) {\n     /* will not copy first part of numeric right now, *\n      * force it to be copied later in its entirety    */\n        zero_padding_insertion_ind = 0;\n      } else {\n     /* insert first part of numerics (sign or '0x') before zero padding */\n        int n = zero_padding_insertion_ind;\n        if (n > 0) {\n          if (str_l < str_m) {\n            size_t avail = str_m-str_l;\n            fast_memcpy(str+str_l, str_arg, (n>avail?avail:n));\n          }\n          str_l += n;\n        }\n     /* insert zero padding as requested by the precision or min field width */\n        n = number_of_zeros_to_pad;\n        if (n > 0) {\n          if (str_l < str_m) {\n            size_t avail = str_m-str_l;\n            fast_memset(str+str_l, '0', (n>avail?avail:n));\n          }\n          str_l += n;\n        }\n      }\n   /* insert formatted string\n    * (or as-is conversion specifier for unknown conversions) */\n      { int n = str_arg_l - zero_padding_insertion_ind;\n        if (n > 0) {\n          if (str_l < str_m) {\n            size_t avail = str_m-str_l;\n            fast_memcpy(str+str_l, str_arg+zero_padding_insertion_ind,\n                        (n>avail?avail:n));\n          }\n          str_l += n;\n        }\n      }\n   /* insert right padding */\n      if (justify_left) {          /* right blank padding to the field width */\n        int n = min_field_width - (str_arg_l+number_of_zeros_to_pad);\n        if (n > 0) {\n          if (str_l < str_m) {\n            size_t avail = str_m-str_l;\n            fast_memset(str+str_l, ' ', (n>avail?avail:n));\n          }\n          str_l += n;\n        }\n      }\n    }\n  }\n#if defined(NEED_SNPRINTF_ONLY)\n  va_end(ap);\n#endif\n  if (str_m > 0) { /* make sure the string is null-terminated\n                      even at the expense of overwriting the last character\n                      (shouldn't happen, but just in case) */\n    str[str_l <= str_m-1 ? str_l : str_m-1] = '\\0';\n  }\n  /* Return the number of characters formatted (excluding trailing null\n   * character), that is, the number of characters that would have been\n   * written to the buffer if it were large enough.\n   *\n   * The value of str_l should be returned, but str_l is of unsigned type\n   * size_t, and snprintf is int, possibly leading to an undetected\n   * integer overflow, resulting in a negative return value, which is illegal.\n   * Both XSH5 and ISO C99 (at least the draft) are silent on this issue.\n   * Should errno be set to EOVERFLOW and EOF returned in this case???\n   */\n  return (int) str_l;\n}\n#endif\n"
  },
  {
    "path": "pkg/internal/robotgo/base/str_io.h",
    "content": "#pragma once\n#ifndef STR_IO_H\n#define STR_IO_H\n\n#include \"MMBitmap.h\"\n#include \"file_io.h\"\n#include <stdint.h>\n\n\nenum _MMBMPStringError {\n\tkMMBMPStringGenericError = 0,\n\tkMMBMPStringInvalidHeaderError,\n\tkMMBMPStringDecodeError,\n\tkMMBMPStringDecompressError,\n\tkMMBMPStringSizeError, /* Size does not match header. */\n\tMMMBMPStringEncodeError,\n\tkMMBMPStringCompressError\n};\n\ntypedef MMIOError MMBMPStringError;\n\n/* Creates a 24-bit bitmap from a compressed, printable string.\n *\n * String should be in the format: \"b[width],[height],[data]\",\n * where [width] and [height] are the image width & height, and [data]\n * is the raw image data run through zlib_compress() and base64_encode().\n *\n * Returns NULL on error; follows the Create Rule (that is, the caller is\n * responsible for destroy'()ing object).\n * If |error| is non-NULL, it will be set to the error code on return.\n */\nMMBitmapRef createMMBitmapFromString(const uint8_t *buffer, size_t buflen,\n                                     MMBMPStringError *error);\n\n/* Inverse of createMMBitmapFromString().\n *\n * Creates string in the format: \"b[width],[height],[data]\", where [width] and\n * [height] are the image width & height, and [data] is the raw image data run\n * through zlib_compress() and base64_encode().\n *\n * Returns NULL on error, or new string on success (to be free'()d by caller).\n * If |error| is non-NULL, it will be set to the error code on return.\n */\nuint8_t *createStringFromMMBitmap(MMBitmapRef bitmap, MMBMPStringError *error);\n\n/* Returns description of given error code.\n * Returned string is constant and hence should not be freed. */\nconst char *MMBitmapStringErrorString(MMBMPStringError err);\n\n#endif /* STR_IO_H */\n"
  },
  {
    "path": "pkg/internal/robotgo/base/str_io_c.h",
    "content": "#include \"str_io.h\"\n#include \"zlib_util_c.h\"\n#include \"base64_c.h\"\n#include \"snprintf_c.h\" /* snprintf() */\n#include <stdio.h> /* fputs() */\n#include <ctype.h> /* isdigit() */\n#include <stdlib.h> /* atoi() */\n#include <string.h> /* strlen() */\n#include <assert.h>\n\n#if defined(_MSC_VER)\n\t#include \"ms_stdbool.h\"\n#else\n\t#include <stdbool.h>\n#endif\n\n#define STR_BITS_PER_PIXEL 24\n#define STR_BYTES_PER_PIXEL ((STR_BITS_PER_PIXEL) / 8)\n\n#define MAX_DIMENSION_LEN 5 /* Maximum length for [width] or [height]\n                             * in string. */\n\nconst char *MMBitmapStringErrorString(MMBMPStringError err)\n{\n\tswitch (err) {\n\t\tcase kMMBMPStringInvalidHeaderError:\n\t\t\treturn \"Invalid header for string\";\n\t\tcase kMMBMPStringDecodeError:\n\t\t\treturn \"Error decoding string\";\n\t\tcase kMMBMPStringDecompressError:\n\t\t\treturn \"Error decompressing string\";\n\t\tcase kMMBMPStringSizeError:\n\t\t\treturn \"String not of expected size\";\n\t\tcase MMMBMPStringEncodeError:\n\t\t\treturn \"Error encoding string\";\n\t\tcase kMMBMPStringCompressError:\n\t\t\treturn \"Error compressing string\";\n\t\tdefault:\n\t\t\treturn NULL;\n\t}\n}\n\n/* Parses beginning of string in the form of \"[width],[height],*\".\n *\n * If successful, |width| and |height| are set to the appropropriate values,\n * |len| is set to the length of [width] + the length of [height] + 2,\n * and true is returned; otherwise, false is returned.\n */\nstatic bool getSizeFromString(const uint8_t *buf, size_t buflen,\n                              size_t *width, size_t *height,\n                              size_t *len);\n\nMMBitmapRef createMMBitmapFromString(const uint8_t *buffer, size_t buflen,\n                                     MMBMPStringError *err)\n{\n\tuint8_t *decoded, *decompressed;\n\tsize_t width, height;\n\tsize_t len, bytewidth;\n\n\tif (*buffer++ != 'b' || !getSizeFromString(buffer, --buflen,\n\t                                           &width, &height, &len)) {\n\t\tif (err != NULL) *err = kMMBMPStringInvalidHeaderError;\n\t\treturn NULL;\n\t}\n\tbuffer += len;\n\tbuflen -= len;\n\n\tdecoded = base64decode(buffer, buflen, NULL);\n\tif (decoded == NULL) {\n\t\tif (err != NULL) *err = kMMBMPStringDecodeError;\n\t\treturn NULL;\n\t}\n\n\tdecompressed = zlib_decompress(decoded, &len);\n\tfree(decoded);\n\n\tif (decompressed == NULL) {\n\t\tif (err != NULL) *err = kMMBMPStringDecompressError;\n\t\treturn NULL;\n\t}\n\n\tbytewidth = width * STR_BYTES_PER_PIXEL; /* Note that bytewidth is NOT\n\t                                          * aligned to a padding. */\n\tif (height * bytewidth != len) {\n\t\tif (err != NULL) *err = kMMBMPStringSizeError;\n\t\treturn NULL;\n\t}\n\n\treturn createMMBitmap(decompressed, width, height,\n\t                      bytewidth, STR_BITS_PER_PIXEL, STR_BYTES_PER_PIXEL);\n}\n\n/* Returns bitmap data suitable for encoding to a string; that is, 24-bit BGR\n * bitmap with no padding and 3 bytes per pixel.\n *\n * Caller is responsible for free()'ing returned buffer. */\nstatic uint8_t *createRawBitmapData(MMBitmapRef bitmap);\n\nuint8_t *createStringFromMMBitmap(MMBitmapRef bitmap, MMBMPStringError *err)\n{\n\tuint8_t *raw, *compressed;\n\tuint8_t *ret, *encoded;\n\tsize_t len, retlen;\n\n\tassert(bitmap != NULL);\n\n\traw = createRawBitmapData(bitmap);\n\tif (raw == NULL) {\n\t\tif (err != NULL) *err = kMMBMPStringGenericError;\n\t\treturn NULL;\n\t}\n\n\tcompressed = zlib_compress(raw,\n\t                           bitmap->width * bitmap->height *\n\t                           STR_BYTES_PER_PIXEL,\n\t                           9, &len);\n\tfree(raw);\n\tif (compressed == NULL) {\n\t\tif (err != NULL) *err = kMMBMPStringCompressError;\n\t\treturn NULL;\n\t}\n\n\tencoded = base64encode(compressed, len - 1, &retlen);\n\tfree(compressed);\n\tif (encoded == NULL) {\n\t\tif (err != NULL) *err = MMMBMPStringEncodeError;\n\t\treturn NULL;\n\t}\n\n\tretlen += 3 + (MAX_DIMENSION_LEN * 2);\n\tret = calloc(sizeof(char), (retlen + 1));\n\tsnprintf((char *)ret, retlen, \"b%lu,%lu,%s\", (unsigned long)bitmap->width,\n\t                                             (unsigned long)bitmap->height,\n\t\t\t\t\t\t\t\t\t\t\t\t encoded);\n\tret[retlen] = '\\0';\n\tfree(encoded);\n\treturn ret;\n}\n\nstatic uint32_t parseDimension(const uint8_t *buf, size_t buflen,\n                               size_t *numlen);\n\nstatic bool getSizeFromString(const uint8_t *buf, size_t buflen,\n                              size_t *width, size_t *height,\n                              size_t *len)\n{\n\tsize_t numlen;\n\tassert(buf != NULL);\n\tassert(width != NULL);\n\tassert(height != NULL);\n\n\tif ((*width = parseDimension(buf, buflen, &numlen)) == 0) {\n\t\treturn false;\n\t}\n\t*len = numlen + 1;\n\n\tif ((*height = parseDimension(buf + *len, buflen, &numlen)) == 0) {\n\t\treturn false;\n\t}\n\t*len += numlen + 1;\n\n\treturn true;\n}\n\n/* Parses one dimension from string as described in getSizeFromString().\n * Returns dimension on success, or 0 on error. */\nstatic uint32_t parseDimension(const uint8_t *buf,\n\t\t\t\t\t\t\t   size_t buflen, size_t *numlen){\n\tchar num[MAX_DIMENSION_LEN + 1];\n\tsize_t i;\n\t// ssize_t len; \n\t// size_t len;\n\t// uint8_t *len;\n\n\tassert(buf != NULL);\n\t// assert(len != NULL);\n\tfor (i = 0; i < buflen && buf[i] != ',' && buf[i] != '\\0'; ++i) {\n\t\tif (!isdigit(buf[i]) || i > MAX_DIMENSION_LEN) return 0;\n\t\tnum[i] = buf[i];\n\t}\n\tnum[i] = '\\0';\n\t*numlen = i;\n\n\treturn (uint32_t)atoi(num);\n}\n\nstatic uint8_t *createRawBitmapData(MMBitmapRef bitmap)\n{\n\tuint8_t *raw = calloc(STR_BYTES_PER_PIXEL, bitmap->width * bitmap->height);\n\tsize_t y;\n\n\tfor (y = 0; y < bitmap->height; ++y) {\n\t\t/* No padding is added to string bitmaps. */\n\t\tconst size_t rowOffset = y * bitmap->width * STR_BYTES_PER_PIXEL;\n\t\tsize_t x;\n\t\tfor (x = 0; x < bitmap->width; ++x) {\n\t\t\t/* Copy in BGR format. */\n\t\t\tconst size_t colOffset = x * STR_BYTES_PER_PIXEL;\n\t\t\tuint8_t *dest = raw + rowOffset + colOffset;\n\t\t\tMMRGBColor *srcColor = MMRGBColorRefAtPoint(bitmap, x, y);\n\t\t\tdest[0] = srcColor->blue;\n\t\t\tdest[1] = srcColor->green;\n\t\t\tdest[2] = srcColor->red;\n\t\t}\n\t}\n\n\treturn raw;\n}\n"
  },
  {
    "path": "pkg/internal/robotgo/base/types.h",
    "content": "#pragma once\n#ifndef TYPES_H\n#define TYPES_H\n\n#include \"os.h\"\n#include \"inline_keywords.h\" /* For H_INLINE */\n#include <stddef.h>\n#include <stdint.h>\n\n/* Some generic, cross-platform types. */\n\nstruct _MMPoint {\n\tsize_t x;\n\tsize_t y;\n};\n\ntypedef struct _MMPoint MMPoint;\n\nstruct _MMPointInt32 {\n\tint32_t x;\n\tint32_t y;\n};\n\ntypedef struct _MMPointInt32 MMPointInt32;\n\nstruct _MMSize {\n\tsize_t width;\n\tsize_t height;\n};\n\ntypedef struct _MMSize MMSize;\n\nstruct _MMSizeInt32 {\n\tint32_t w;\n\tint32_t h;\n};\n\ntypedef struct _MMSizeInt32 MMSizeInt32;\n\n\nstruct _MMRect {\n\tMMPoint origin;\n\tMMSize size;\n};\n\ntypedef struct _MMRect MMRect;\n\nstruct _MMRectInt32 {\n\tMMPointInt32 origin;\n\tMMSizeInt32 size;\n};\n\ntypedef struct _MMRectInt32 MMRectInt32;\n\nH_INLINE MMPoint MMPointMake(size_t x, size_t y)\n{\n\tMMPoint point;\n\tpoint.x = x;\n\tpoint.y = y;\n\treturn point;\n}\n\nH_INLINE MMPointInt32 MMPointInt32Make(int32_t x, int32_t y)\n{\n\tMMPointInt32 point;\n\tpoint.x = x;\n\tpoint.y = y;\n\treturn point;\n}\n\nH_INLINE MMSize MMSizeMake(size_t width, size_t height)\n{\n\tMMSize size;\n\tsize.width = width;\n\tsize.height = height;\n\treturn size;\n}\n\nH_INLINE MMSizeInt32 MMSizeInt32Make(int32_t w, int32_t h)\n{\n\tMMSizeInt32 size;\n\tsize.w = w;\n\tsize.h = h;\n\treturn size;\n}\n\nH_INLINE MMRect MMRectMake(size_t x, size_t y, size_t width, size_t height)\n{\n\tMMRect rect;\n\trect.origin = MMPointMake(x, y);\n\trect.size = MMSizeMake(width, height);\n\treturn rect;\n}\n\nH_INLINE MMRectInt32 MMRectInt32Make(int32_t x, int32_t y, int32_t w, int32_t h)\n{\n\tMMRectInt32 rect;\n\trect.origin = MMPointInt32Make(x, y);\n\trect.size = MMSizeInt32Make(w, h);\n\treturn rect;\n}\n\n//\n#define MMPointZero MMPointMake(0, 0)\n\n#if defined(IS_MACOSX)\n\n#define CGPointFromMMPoint(p) CGPointMake((CGFloat)(p).x, (CGFloat)(p).y)\n#define MMPointFromCGPoint(p) MMPointMake((size_t)(p).x, (size_t)(p).y)\n\n#define CGPointFromMMPointInt32(p) CGPointMake((CGFloat)(p).x, (CGFloat)(p).y)\n#define MMPointInt32FromCGPoint(p) MMPointInt32Make((int32_t)(p).x, (int32_t)(p).y)\n\n#elif defined(IS_WINDOWS)\n\n#define MMPointFromPOINT(p) MMPointMake((size_t)p.x, (size_t)p.y)\n#define MMPointInt32FromPOINT(p) MMPointInt32Make((int32_t)p.x, (int32_t)p.y)\n\n#endif\n\n#endif /* TYPES_H */\n"
  },
  {
    "path": "pkg/internal/robotgo/base/uthash.h",
    "content": "/*\n * Copyright (c) 2003-2009, Troy D. Hanson     http://uthash.sourceforge.net\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are met:\n *\n *     * Redistributions of source code must retain the above copyright\n *       notice, this list of conditions and the following disclaimer.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS\n * IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED\n * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A\n * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER\n * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n#pragma once\n#ifndef UTHASH_H\n#define UTHASH_H\n\n#include <string.h> /* memcmp, strlen */\n#include <stddef.h> /* ptrdiff_t */\n#include <stdint.h>\n\n\n#define UTHASH_VERSION 1.8\n\n/* C++ requires extra stringent casting */\n#if defined __cplusplus\n#define TYPEOF(x) (typeof(x))\n#else\n#define TYPEOF(x)\n#endif\n\n\n#define uthash_fatal(msg) exit(-1)        /* fatal error (out of memory,etc) */\n#define uthash_malloc(sz) malloc(sz)      /* malloc fcn                      */\n#define uthash_free(ptr) free(ptr)        /* free fcn                        */\n\n#define uthash_noexpand_fyi(tbl)          /* can be defined to log noexpand  */\n#define uthash_expand_fyi(tbl)            /* can be defined to log expands   */\n\n/* initial number of buckets */\n#define HASH_INITIAL_NUM_BUCKETS 32      /* initial number of buckets        */\n#define HASH_INITIAL_NUM_BUCKETS_LOG2 5  /* lg2 of initial number of buckets */\n#define HASH_BKT_CAPACITY_THRESH 10      /* expand when bucket count reaches */\n\n/* calculate the element whose hash handle address is hhe */\n#define ELMT_FROM_HH(tbl,hhp) ((void*)(((char*)hhp) - (tbl)->hho))\n\n#define HASH_FIND(hh,head,keyptr,keylen,out)                                    \\\ndo {                                                                            \\\n  unsigned _hf_bkt,_hf_hashv;                                                   \\\n  out=TYPEOF(out)NULL;                                                          \\\n  if (head) {                                                                   \\\n     HASH_FCN(keyptr,keylen, (head)->hh.tbl->num_buckets, _hf_hashv, _hf_bkt);  \\\n     if (HASH_BLOOM_TEST((head)->hh.tbl, _hf_hashv)) {                          \\\n       HASH_FIND_IN_BKT((head)->hh.tbl, hh, (head)->hh.tbl->buckets[ _hf_bkt ], \\\n                        keyptr,keylen,out);                                     \\\n     }                                                                          \\\n  }                                                                             \\\n} while (0)\n\n#if defined(HASH_BLOOM)\n#define HASH_BLOOM_BITLEN (1ULL << HASH_BLOOM)\n#define HASH_BLOOM_BYTELEN (HASH_BLOOM_BITLEN/8) + ((HASH_BLOOM_BITLEN%8) ? 1:0)\n#define HASH_BLOOM_MAKE(tbl)                                                    \\\ndo {                                                                            \\\n  (tbl)->bloom_nbits = HASH_BLOOM;                                              \\\n  (tbl)->bloom_bv = (uint8_t*)uthash_malloc(HASH_BLOOM_BYTELEN);                \\\n  if (!((tbl)->bloom_bv))  { uthash_fatal( \"out of memory\"); }                  \\\n  memset((tbl)->bloom_bv, 0, HASH_BLOOM_BYTELEN);                               \\\n  (tbl)->bloom_sig = HASH_BLOOM_SIGNATURE;                                      \\\n} while (0);\n\n#define HASH_BLOOM_FREE(tbl)                                                    \\\ndo {                                                                            \\\n  uthash_free((tbl)->bloom_bv);                                                 \\\n} while (0);\n\n#define HASH_BLOOM_BITSET(bv,idx) (bv[(idx)/8] |= (1U << ((idx)%8)))\n#define HASH_BLOOM_BITTEST(bv,idx) (bv[(idx)/8] & (1U << ((idx)%8)))\n\n#define HASH_BLOOM_ADD(tbl,hashv)                                               \\\n  HASH_BLOOM_BITSET((tbl)->bloom_bv, (hashv & (uint32_t)((1ULL << (tbl)->bloom_nbits) - 1)))\n\n#define HASH_BLOOM_TEST(tbl,hashv)                                              \\\n  HASH_BLOOM_BITTEST((tbl)->bloom_bv, (hashv & (uint32_t)((1ULL << (tbl)->bloom_nbits) - 1)))\n\n#else\n#define HASH_BLOOM_MAKE(tbl)\n#define HASH_BLOOM_FREE(tbl)\n#define HASH_BLOOM_ADD(tbl,hashv)\n#define HASH_BLOOM_TEST(tbl,hashv) (1)\n#endif\n\n#define HASH_MAKE_TABLE(hh,head)                                                \\\ndo {                                                                            \\\n  (head)->hh.tbl = (UT_hash_table*)uthash_malloc(                               \\\n                  sizeof(UT_hash_table));                                       \\\n  if (!((head)->hh.tbl))  { uthash_fatal( \"out of memory\"); }                   \\\n  memset((head)->hh.tbl, 0, sizeof(UT_hash_table));                             \\\n  (head)->hh.tbl->tail = &((head)->hh);                                         \\\n  (head)->hh.tbl->num_buckets = HASH_INITIAL_NUM_BUCKETS;                       \\\n  (head)->hh.tbl->log2_num_buckets = HASH_INITIAL_NUM_BUCKETS_LOG2;             \\\n  (head)->hh.tbl->hho = (char*)(&(head)->hh) - (char*)(head);                   \\\n  (head)->hh.tbl->buckets = (UT_hash_bucket*)uthash_malloc(                     \\\n          HASH_INITIAL_NUM_BUCKETS*sizeof(struct UT_hash_bucket));              \\\n  if (! (head)->hh.tbl->buckets) { uthash_fatal( \"out of memory\"); }            \\\n  memset((head)->hh.tbl->buckets, 0,                                            \\\n          HASH_INITIAL_NUM_BUCKETS*sizeof(struct UT_hash_bucket));              \\\n  HASH_BLOOM_MAKE((head)->hh.tbl);                                              \\\n  (head)->hh.tbl->signature = HASH_SIGNATURE;                                   \\\n} while(0)\n\n#define HASH_ADD(hh,head,fieldname,keylen_in,add)                               \\\n        HASH_ADD_KEYPTR(hh,head,&add->fieldname,keylen_in,add)\n\n#define HASH_ADD_KEYPTR(hh,head,keyptr,keylen_in,add)                           \\\ndo {                                                                            \\\n unsigned _ha_bkt;                                                              \\\n (add)->hh.next = NULL;                                                         \\\n (add)->hh.key = (char*)keyptr;                                                 \\\n (add)->hh.keylen = keylen_in;                                                  \\\n if (!(head)) {                                                                 \\\n    head = (add);                                                               \\\n    (head)->hh.prev = NULL;                                                     \\\n    HASH_MAKE_TABLE(hh,head);                                                   \\\n } else {                                                                       \\\n    (head)->hh.tbl->tail->next = (add);                                         \\\n    (add)->hh.prev = ELMT_FROM_HH((head)->hh.tbl, (head)->hh.tbl->tail);        \\\n    (head)->hh.tbl->tail = &((add)->hh);                                        \\\n }                                                                              \\\n (head)->hh.tbl->num_items++;                                                   \\\n (add)->hh.tbl = (head)->hh.tbl;                                                \\\n HASH_FCN(keyptr,keylen_in, (head)->hh.tbl->num_buckets,                        \\\n         (add)->hh.hashv, _ha_bkt);                                             \\\n HASH_ADD_TO_BKT((head)->hh.tbl->buckets[_ha_bkt],&(add)->hh);                  \\\n HASH_BLOOM_ADD((head)->hh.tbl,(add)->hh.hashv);                                \\\n HASH_EMIT_KEY(hh,head,keyptr,keylen_in);                                       \\\n HASH_FSCK(hh,head);                                                            \\\n} while(0)\n\n#define HASH_TO_BKT( hashv, num_bkts, bkt )                                     \\\ndo {                                                                            \\\n  bkt = ((hashv) & ((num_bkts) - 1));                                           \\\n} while(0)\n\n/* delete \"delptr\" from the hash table.\n * \"the usual\" patch-up process for the app-order doubly-linked-list.\n * The use of _hd_hh_del below deserves special explanation.\n * These used to be expressed using (delptr) but that led to a bug\n * if someone used the same symbol for the head and deletee, like\n *  HASH_DELETE(hh,users,users);\n * We want that to work, but by changing the head (users) below\n * we were forfeiting our ability to further refer to the deletee (users)\n * in the patch-up process. Solution: use scratch space in the table to\n * copy the deletee pointer, then the latter references are via that\n * scratch pointer rather than through the repointed (users) symbol.\n */\n#define HASH_DELETE(hh,head,delptr)                                             \\\ndo {                                                                            \\\n    unsigned _hd_bkt;                                                           \\\n    struct UT_hash_handle *_hd_hh_del;                                          \\\n    if ( ((delptr)->hh.prev == NULL) && ((delptr)->hh.next == NULL) )  {        \\\n        uthash_free((head)->hh.tbl->buckets );                                  \\\n        HASH_BLOOM_FREE((head)->hh.tbl);                                        \\\n        uthash_free((head)->hh.tbl);                                            \\\n        head = NULL;                                                            \\\n    } else {                                                                    \\\n        _hd_hh_del = &((delptr)->hh);                                           \\\n        if ((delptr) == ELMT_FROM_HH((head)->hh.tbl,(head)->hh.tbl->tail)) {    \\\n            (head)->hh.tbl->tail =                                              \\\n                (UT_hash_handle*)((char*)((delptr)->hh.prev) +                  \\\n                (head)->hh.tbl->hho);                                           \\\n        }                                                                       \\\n        if ((delptr)->hh.prev) {                                                \\\n            ((UT_hash_handle*)((char*)((delptr)->hh.prev) +                     \\\n                    (head)->hh.tbl->hho))->next = (delptr)->hh.next;            \\\n        } else {                                                                \\\n            head = TYPEOF(head)((delptr)->hh.next);                             \\\n        }                                                                       \\\n        if (_hd_hh_del->next) {                                                 \\\n            ((UT_hash_handle*)((char*)_hd_hh_del->next +                        \\\n                    (head)->hh.tbl->hho))->prev =                               \\\n                    _hd_hh_del->prev;                                           \\\n        }                                                                       \\\n        HASH_TO_BKT( _hd_hh_del->hashv, (head)->hh.tbl->num_buckets, _hd_bkt);  \\\n        HASH_DEL_IN_BKT(hh,(head)->hh.tbl->buckets[_hd_bkt], _hd_hh_del);       \\\n        (head)->hh.tbl->num_items--;                                            \\\n    }                                                                           \\\n    HASH_FSCK(hh,head);                                                         \\\n} while (0)\n\n\n/* convenience forms of HASH_FIND/HASH_ADD/HASH_DEL */\n#define HASH_FIND_STR(head,findstr,out)                                         \\\n    HASH_FIND(hh,head,findstr,strlen(findstr),out)\n#define HASH_ADD_STR(head,strfield,add)                                         \\\n    HASH_ADD(hh,head,strfield,strlen(add->strfield),add)\n#define HASH_FIND_INT(head,findint,out)                                         \\\n    HASH_FIND(hh,head,findint,sizeof(int),out)\n#define HASH_ADD_INT(head,intfield,add)                                         \\\n    HASH_ADD(hh,head,intfield,sizeof(int),add)\n#define HASH_DEL(head,delptr)                                                   \\\n    HASH_DELETE(hh,head,delptr)\n\n/* HASH_FSCK checks hash integrity on every add/delete when HASH_DEBUG is defined.\n * This is for uthash developer only; it compiles away if HASH_DEBUG isn't defined.\n */\n#if defined(HASH_DEBUG)\n#define HASH_OOPS(...) do { fprintf(stderr,__VA_ARGS__); exit(-1); } while (0)\n#define HASH_FSCK(hh,head)                                                      \\\ndo {                                                                            \\\n    unsigned _bkt_i;                                                            \\\n    unsigned _count, _bkt_count;                                                \\\n    char *_prev;                                                                \\\n    struct UT_hash_handle *_thh;                                                \\\n    if (head) {                                                                 \\\n        _count = 0;                                                             \\\n        for( _bkt_i = 0; _bkt_i < (head)->hh.tbl->num_buckets; _bkt_i++) {      \\\n            _bkt_count = 0;                                                     \\\n            _thh = (head)->hh.tbl->buckets[_bkt_i].hh_head;                     \\\n            _prev = NULL;                                                       \\\n            while (_thh) {                                                      \\\n               if (_prev != (char*)(_thh->hh_prev)) {                           \\\n                   HASH_OOPS(\"invalid hh_prev %p, actual %p\\n\",                 \\\n                    _thh->hh_prev, _prev );                                     \\\n               }                                                                \\\n               _bkt_count++;                                                    \\\n               _prev = (char*)(_thh);                                           \\\n               _thh = _thh->hh_next;                                            \\\n            }                                                                   \\\n            _count += _bkt_count;                                               \\\n            if ((head)->hh.tbl->buckets[_bkt_i].count !=  _bkt_count) {         \\\n               HASH_OOPS(\"invalid bucket count %d, actual %d\\n\",                \\\n                (head)->hh.tbl->buckets[_bkt_i].count, _bkt_count);             \\\n            }                                                                   \\\n        }                                                                       \\\n        if (_count != (head)->hh.tbl->num_items) {                              \\\n            HASH_OOPS(\"invalid hh item count %d, actual %d\\n\",                  \\\n                (head)->hh.tbl->num_items, _count );                            \\\n        }                                                                       \\\n        /* traverse hh in app order; check next/prev integrity, count */        \\\n        _count = 0;                                                             \\\n        _prev = NULL;                                                           \\\n        _thh =  &(head)->hh;                                                    \\\n        while (_thh) {                                                          \\\n           _count++;                                                            \\\n           if (_prev !=(char*)(_thh->prev)) {                                   \\\n              HASH_OOPS(\"invalid prev %p, actual %p\\n\",                         \\\n                    _thh->prev, _prev );                                        \\\n           }                                                                    \\\n           _prev = (char*)ELMT_FROM_HH((head)->hh.tbl, _thh);                   \\\n           _thh = ( _thh->next ?  (UT_hash_handle*)((char*)(_thh->next) +       \\\n                                  (head)->hh.tbl->hho) : NULL );                \\\n        }                                                                       \\\n        if (_count != (head)->hh.tbl->num_items) {                              \\\n            HASH_OOPS(\"invalid app item count %d, actual %d\\n\",                 \\\n                (head)->hh.tbl->num_items, _count );                            \\\n        }                                                                       \\\n    }                                                                           \\\n} while (0)\n#else\n#define HASH_FSCK(hh,head)\n#endif\n\n/* When compiled with -DHASH_EMIT_KEYS, length-prefixed keys are emitted to\n * the descriptor to which this macro is defined for tuning the hash function.\n * The app can #include <unistd.h> to get the prototype for write(2). */\n#if defined(HASH_EMIT_KEYS)\n#define HASH_EMIT_KEY(hh,head,keyptr,fieldlen)                                  \\\ndo {                                                                            \\\n    unsigned _klen = fieldlen;                                                  \\\n    write(HASH_EMIT_KEYS, &_klen, sizeof(_klen));                               \\\n    write(HASH_EMIT_KEYS, keyptr, fieldlen);                                    \\\n} while (0)\n#else\n#define HASH_EMIT_KEY(hh,head,keyptr,fieldlen)\n#endif\n\n/* default to Jenkin's hash unless overridden e.g. DHASH_FUNCTION=HASH_SAX */\n#if defined(HASH_FUNCTION)\n#define HASH_FCN HASH_FUNCTION\n#else\n#define HASH_FCN HASH_JEN\n#endif\n\n/* The Bernstein hash function, used in Perl prior to v5.6 */\n#define HASH_BER(key,keylen,num_bkts,hashv,bkt)                                 \\\ndo {                                                                            \\\n  unsigned _hb_keylen=keylen;                                                   \\\n  char *_hb_key=(char*)key;                                                     \\\n  (hashv) = 0;                                                                  \\\n  while (_hb_keylen--)  { (hashv) = ((hashv) * 33) + *_hb_key++; }              \\\n  bkt = (hashv) & (num_bkts-1);                                                 \\\n} while (0)\n\n\n/* SAX/FNV/OAT/JEN hash functions are macro variants of those listed at\n * http://eternallyconfuzzled.com/tuts/algorithms/jsw_tut_hashing.aspx */\n#define HASH_SAX(key,keylen,num_bkts,hashv,bkt)                                 \\\ndo {                                                                            \\\n  unsigned _sx_i;                                                               \\\n  char *_hs_key=(char*)key;                                                     \\\n  hashv = 0;                                                                    \\\n  for(_sx_i=0; _sx_i < keylen; _sx_i++)                                         \\\n      hashv ^= (hashv << 5) + (hashv >> 2) + _hs_key[_sx_i];                    \\\n  bkt = hashv & (num_bkts-1);                                                   \\\n} while (0)\n\n#define HASH_FNV(key,keylen,num_bkts,hashv,bkt)                                 \\\ndo {                                                                            \\\n  unsigned _fn_i;                                                               \\\n  char *_hf_key=(char*)key;                                                     \\\n  hashv = 2166136261UL;                                                         \\\n  for(_fn_i=0; _fn_i < keylen; _fn_i++)                                         \\\n      hashv = (hashv * 16777619) ^ _hf_key[_fn_i];                              \\\n  bkt = hashv & (num_bkts-1);                                                   \\\n} while(0);\n\n#define HASH_OAT(key,keylen,num_bkts,hashv,bkt)                                 \\\ndo {                                                                            \\\n  unsigned _ho_i;                                                               \\\n  char *_ho_key=(char*)key;                                                     \\\n  hashv = 0;                                                                    \\\n  for(_ho_i=0; _ho_i < keylen; _ho_i++) {                                       \\\n      hashv += _ho_key[_ho_i];                                                  \\\n      hashv += (hashv << 10);                                                   \\\n      hashv ^= (hashv >> 6);                                                    \\\n  }                                                                             \\\n  hashv += (hashv << 3);                                                        \\\n  hashv ^= (hashv >> 11);                                                       \\\n  hashv += (hashv << 15);                                                       \\\n  bkt = hashv & (num_bkts-1);                                                   \\\n} while(0)\n\n#define HASH_JEN_MIX(a,b,c)                                                     \\\ndo {                                                                            \\\n  a -= b; a -= c; a ^= ( c >> 13 );                                             \\\n  b -= c; b -= a; b ^= ( a << 8 );                                              \\\n  c -= a; c -= b; c ^= ( b >> 13 );                                             \\\n  a -= b; a -= c; a ^= ( c >> 12 );                                             \\\n  b -= c; b -= a; b ^= ( a << 16 );                                             \\\n  c -= a; c -= b; c ^= ( b >> 5 );                                              \\\n  a -= b; a -= c; a ^= ( c >> 3 );                                              \\\n  b -= c; b -= a; b ^= ( a << 10 );                                             \\\n  c -= a; c -= b; c ^= ( b >> 15 );                                             \\\n} while (0)\n\n#define HASH_JEN(key,keylen,num_bkts,hashv,bkt)                                 \\\ndo {                                                                            \\\n  unsigned _hj_i,_hj_j,_hj_k;                                                   \\\n  char *_hj_key=(char*)key;                                                     \\\n  hashv = 0xfeedbeef;                                                           \\\n  _hj_i = _hj_j = 0x9e3779b9;                                                   \\\n  _hj_k = keylen;                                                               \\\n  while (_hj_k >= 12) {                                                         \\\n    _hj_i +=    (_hj_key[0] + ( (unsigned)_hj_key[1] << 8 )                     \\\n        + ( (unsigned)_hj_key[2] << 16 )                                        \\\n        + ( (unsigned)_hj_key[3] << 24 ) );                                     \\\n    _hj_j +=    (_hj_key[4] + ( (unsigned)_hj_key[5] << 8 )                     \\\n        + ( (unsigned)_hj_key[6] << 16 )                                        \\\n        + ( (unsigned)_hj_key[7] << 24 ) );                                     \\\n    hashv += (_hj_key[8] + ( (unsigned)_hj_key[9] << 8 )                        \\\n        + ( (unsigned)_hj_key[10] << 16 )                                       \\\n        + ( (unsigned)_hj_key[11] << 24 ) );                                    \\\n                                                                                \\\n     HASH_JEN_MIX(_hj_i, _hj_j, hashv);                                         \\\n                                                                                \\\n     _hj_key += 12;                                                             \\\n     _hj_k -= 12;                                                               \\\n  }                                                                             \\\n  hashv += keylen;                                                              \\\n  switch ( _hj_k ) {                                                            \\\n     case 11: hashv += ( (unsigned)_hj_key[10] << 24 );                         \\\n     case 10: hashv += ( (unsigned)_hj_key[9] << 16 );                          \\\n     case 9:  hashv += ( (unsigned)_hj_key[8] << 8 );                           \\\n     case 8:  _hj_j += ( (unsigned)_hj_key[7] << 24 );                          \\\n     case 7:  _hj_j += ( (unsigned)_hj_key[6] << 16 );                          \\\n     case 6:  _hj_j += ( (unsigned)_hj_key[5] << 8 );                           \\\n     case 5:  _hj_j += _hj_key[4];                                              \\\n     case 4:  _hj_i += ( (unsigned)_hj_key[3] << 24 );                          \\\n     case 3:  _hj_i += ( (unsigned)_hj_key[2] << 16 );                          \\\n     case 2:  _hj_i += ( (unsigned)_hj_key[1] << 8 );                           \\\n     case 1:  _hj_i += _hj_key[0];                                              \\\n  }                                                                             \\\n  HASH_JEN_MIX(_hj_i, _hj_j, hashv);                                            \\\n  bkt = hashv & (num_bkts-1);                                                   \\\n} while(0)\n\n/* The Paul Hsieh hash function */\n#undef get16bits\n#if (defined(__GNUC__) && defined(__i386__)) || defined(__WATCOMC__)            \\\n  || defined(_MSC_VER) || defined (__BORLANDC__) || defined (__TURBOC__)\n#define get16bits(d) (*((const uint16_t *) (d)))\n#endif\n\n#if !defined (get16bits)\n#define get16bits(d) ((((uint32_t)(((const uint8_t *)(d))[1])) << 8)            \\\n                       +(uint32_t)(((const uint8_t *)(d))[0]) )\n#endif\n#define HASH_SFH(key,keylen,num_bkts,hashv,bkt)                                 \\\ndo {                                                                            \\\n  char *_sfh_key=(char*)key;                                                    \\\n  uint32_t _sfh_tmp, _sfh_len = keylen;                                         \\\n                                                                                \\\n  int _sfh_rem = _sfh_len & 3;                                                  \\\n  _sfh_len >>= 2;                                                               \\\n  hashv = 0xcafebabe;                                                           \\\n                                                                                \\\n  /* Main loop */                                                               \\\n  for (;_sfh_len > 0; _sfh_len--) {                                             \\\n    hashv    += get16bits (_sfh_key);                                           \\\n    _sfh_tmp       = (get16bits (_sfh_key+2) << 11) ^ hashv;                    \\\n    hashv     = (hashv << 16) ^ _sfh_tmp;                                       \\\n    _sfh_key += 2*sizeof (uint16_t);                                            \\\n    hashv    += hashv >> 11;                                                    \\\n  }                                                                             \\\n                                                                                \\\n  /* Handle end cases */                                                        \\\n  switch (_sfh_rem) {                                                           \\\n    case 3: hashv += get16bits (_sfh_key);                                      \\\n            hashv ^= hashv << 16;                                               \\\n            hashv ^= _sfh_key[sizeof (uint16_t)] << 18;                         \\\n            hashv += hashv >> 11;                                               \\\n            break;                                                              \\\n    case 2: hashv += get16bits (_sfh_key);                                      \\\n            hashv ^= hashv << 11;                                               \\\n            hashv += hashv >> 17;                                               \\\n            break;                                                              \\\n    case 1: hashv += *_sfh_key;                                                 \\\n            hashv ^= hashv << 10;                                               \\\n            hashv += hashv >> 1;                                                \\\n  }                                                                             \\\n                                                                                \\\n    /* Force \"avalanching\" of final 127 bits */                                 \\\n    hashv ^= hashv << 3;                                                        \\\n    hashv += hashv >> 5;                                                        \\\n    hashv ^= hashv << 4;                                                        \\\n    hashv += hashv >> 17;                                                       \\\n    hashv ^= hashv << 25;                                                       \\\n    hashv += hashv >> 6;                                                        \\\n    bkt = hashv & (num_bkts-1);                                                 \\\n} while(0);\n\n#if defined(HASH_USING_NO_STRICT_ALIASING)\n/* The MurmurHash exploits some CPU's (e.g. x86) tolerance for unaligned reads.\n * For other types of CPU's (e.g. Sparc) an unaligned read causes a bus error.\n * So MurmurHash comes in two versions, the faster unaligned one and the slower\n * aligned one. We only use the faster one on CPU's where we know it's safe.\n *\n * Note the preprocessor built-in defines can be emitted using:\n *\n *   gcc -m64 -dM -E - < /dev/null                  (on gcc)\n *   cc -## a.c (where a.c is a simple test file)   (Sun Studio)\n */\n#if (defined(__i386__) || defined(__x86_64__))\n#define HASH_MUR HASH_MUR_UNALIGNED\n#else\n#define HASH_MUR HASH_MUR_ALIGNED\n#endif\n\n/* Appleby's MurmurHash fast version for unaligned-tolerant archs like i386 */\n#define HASH_MUR_UNALIGNED(key,keylen,num_bkts,hashv,bkt)                       \\\ndo {                                                                            \\\n  const unsigned int _mur_m = 0x5bd1e995;                                       \\\n  const int _mur_r = 24;                                                        \\\n  hashv = 0xcafebabe ^ keylen;                                                  \\\n  char *_mur_key = (char *)key;                                                 \\\n  uint32_t _mur_tmp, _mur_len = keylen;                                         \\\n                                                                                \\\n  for (;_mur_len >= 4; _mur_len-=4) {                                           \\\n    _mur_tmp = *(uint32_t *)_mur_key;                                           \\\n    _mur_tmp *= _mur_m;                                                         \\\n    _mur_tmp ^= _mur_tmp >> _mur_r;                                             \\\n    _mur_tmp *= _mur_m;                                                         \\\n    hashv *= _mur_m;                                                            \\\n    hashv ^= _mur_tmp;                                                          \\\n    _mur_key += 4;                                                              \\\n  }                                                                             \\\n                                                                                \\\n  switch(_mur_len)                                                              \\\n  {                                                                             \\\n    case 3: hashv ^= _mur_key[2] << 16;                                         \\\n    case 2: hashv ^= _mur_key[1] << 8;                                          \\\n    case 1: hashv ^= _mur_key[0];                                               \\\n            hashv *= _mur_m;                                                    \\\n  };                                                                            \\\n                                                                                \\\n  hashv ^= hashv >> 13;                                                         \\\n  hashv *= _mur_m;                                                              \\\n  hashv ^= hashv >> 15;                                                         \\\n                                                                                \\\n  bkt = hashv & (num_bkts-1);                                                   \\\n} while(0)\n\n/* Appleby's MurmurHash version for alignment-sensitive archs like Sparc */\n#define HASH_MUR_ALIGNED(key,keylen,num_bkts,hashv,bkt)                         \\\ndo {                                                                            \\\n  const unsigned int _mur_m = 0x5bd1e995;                                       \\\n  const int _mur_r = 24;                                                        \\\n  hashv = 0xcafebabe ^ keylen;                                                  \\\n  char *_mur_key = (char *)key;                                                 \\\n  uint32_t _mur_len = keylen;                                                   \\\n  int _mur_align = (int)_mur_key & 3;                                           \\\n                                                                                \\\n  if (_mur_align && (_mur_len >= 4)) {                                          \\\n    unsigned _mur_t = 0, _mur_d = 0;                                            \\\n    switch(_mur_align) {                                                        \\\n      case 1: _mur_t |= _mur_key[2] << 16;                                      \\\n      case 2: _mur_t |= _mur_key[1] << 8;                                       \\\n      case 3: _mur_t |= _mur_key[0];                                            \\\n    }                                                                           \\\n    _mur_t <<= (8 * _mur_align);                                                \\\n    _mur_key += 4-_mur_align;                                                   \\\n    _mur_len -= 4-_mur_align;                                                   \\\n    int _mur_sl = 8 * (4-_mur_align);                                           \\\n    int _mur_sr = 8 * _mur_align;                                               \\\n                                                                                \\\n    for (;_mur_len >= 4; _mur_len-=4) {                                         \\\n      _mur_d = *(unsigned *)_mur_key;                                           \\\n      _mur_t = (_mur_t >> _mur_sr) | (_mur_d << _mur_sl);                       \\\n      unsigned _mur_k = _mur_t;                                                 \\\n      _mur_k *= _mur_m;                                                         \\\n      _mur_k ^= _mur_k >> _mur_r;                                               \\\n      _mur_k *= _mur_m;                                                         \\\n      hashv *= _mur_m;                                                          \\\n      hashv ^= _mur_k;                                                          \\\n      _mur_t = _mur_d;                                                          \\\n      _mur_key += 4;                                                            \\\n    }                                                                           \\\n    _mur_d = 0;                                                                 \\\n    if(_mur_len >= _mur_align) {                                                \\\n      switch(_mur_align) {                                                      \\\n        case 3: _mur_d |= _mur_key[2] << 16;                                    \\\n        case 2: _mur_d |= _mur_key[1] << 8;                                     \\\n        case 1: _mur_d |= _mur_key[0];                                          \\\n      }                                                                         \\\n      unsigned _mur_k = (_mur_t >> _mur_sr) | (_mur_d << _mur_sl);              \\\n      _mur_k *= _mur_m;                                                         \\\n      _mur_k ^= _mur_k >> _mur_r;                                               \\\n      _mur_k *= _mur_m;                                                         \\\n      hashv *= _mur_m;                                                          \\\n      hashv ^= _mur_k;                                                          \\\n      _mur_k += _mur_align;                                                     \\\n      _mur_len -= _mur_align;                                                   \\\n                                                                                \\\n      switch(_mur_len)                                                          \\\n      {                                                                         \\\n        case 3: hashv ^= _mur_key[2] << 16;                                     \\\n        case 2: hashv ^= _mur_key[1] << 8;                                      \\\n        case 1: hashv ^= _mur_key[0];                                           \\\n                hashv *= _mur_m;                                                \\\n      }                                                                         \\\n    } else {                                                                    \\\n      switch(_mur_len)                                                          \\\n      {                                                                         \\\n        case 3: _mur_d ^= _mur_key[2] << 16;                                    \\\n        case 2: _mur_d ^= _mur_key[1] << 8;                                     \\\n        case 1: _mur_d ^= _mur_key[0];                                          \\\n        case 0: hashv ^= (_mur_t >> _mur_sr) | (_mur_d << _mur_sl);             \\\n        hashv *= _mur_m;                                                        \\\n      }                                                                         \\\n    }                                                                           \\\n                                                                                \\\n    hashv ^= hashv >> 13;                                                       \\\n    hashv *= _mur_m;                                                            \\\n    hashv ^= hashv >> 15;                                                       \\\n  } else {                                                                      \\\n    for (;_mur_len >= 4; _mur_len-=4) {                                         \\\n      unsigned _mur_k = *(unsigned*)_mur_key;                                   \\\n      _mur_k *= _mur_m;                                                         \\\n      _mur_k ^= _mur_k >> _mur_r;                                               \\\n      _mur_k *= _mur_m;                                                         \\\n      hashv *= _mur_m;                                                          \\\n      hashv ^= _mur_k;                                                          \\\n      _mur_key += 4;                                                            \\\n    }                                                                           \\\n    switch(_mur_len)                                                            \\\n    {                                                                           \\\n      case 3: hashv ^= _mur_key[2] << 16;                                       \\\n      case 2: hashv ^= _mur_key[1] << 8;                                        \\\n      case 1: hashv ^= _mur_key[0];                                             \\\n      hashv *= _mur_m;                                                          \\\n    }                                                                           \\\n                                                                                \\\n    hashv ^= hashv >> 13;                                                       \\\n    hashv *= _mur_m;                                                            \\\n    hashv ^= hashv >> 15;                                                       \\\n  }                                                                             \\\n  bkt = hashv & (num_bkts-1);                                                   \\\n} while(0)\n#endif  /* HASH_USING_NO_STRICT_ALIASING */\n\n/* key comparison function; return 0 if keys equal */\n#define HASH_KEYCMP(a,b,len) memcmp(a,b,len)\n\n/* iterate over items in a known bucket to find desired item */\n#define HASH_FIND_IN_BKT(tbl,hh,head,keyptr,keylen_in,out)                      \\\nout = TYPEOF(out)((head.hh_head) ? ELMT_FROM_HH(tbl,head.hh_head) : NULL);      \\\nwhile (out) {                                                                   \\\n    if (out->hh.keylen == keylen_in) {                                          \\\n        if ((HASH_KEYCMP(out->hh.key,keyptr,keylen_in)) == 0) break;            \\\n    }                                                                           \\\n    out= TYPEOF(out)((out->hh.hh_next) ?                                        \\\n                     ELMT_FROM_HH(tbl,out->hh.hh_next) : NULL);                 \\\n}\n\n/* add an item to a bucket  */\n#define HASH_ADD_TO_BKT(head,addhh)                                             \\\ndo {                                                                            \\\n head.count++;                                                                  \\\n (addhh)->hh_next = head.hh_head;                                               \\\n (addhh)->hh_prev = NULL;                                                       \\\n if (head.hh_head) { (head).hh_head->hh_prev = (addhh); }                       \\\n (head).hh_head=addhh;                                                          \\\n if (head.count >= ((head.expand_mult+1) * HASH_BKT_CAPACITY_THRESH)            \\\n     && (addhh)->tbl->noexpand != 1) {                                          \\\n       HASH_EXPAND_BUCKETS((addhh)->tbl);                                       \\\n }                                                                              \\\n} while(0)\n\n/* remove an item from a given bucket */\n#define HASH_DEL_IN_BKT(hh,head,hh_del)                                         \\\n    (head).count--;                                                             \\\n    if ((head).hh_head == hh_del) {                                             \\\n      (head).hh_head = hh_del->hh_next;                                         \\\n    }                                                                           \\\n    if (hh_del->hh_prev) {                                                      \\\n        hh_del->hh_prev->hh_next = hh_del->hh_next;                             \\\n    }                                                                           \\\n    if (hh_del->hh_next) {                                                      \\\n        hh_del->hh_next->hh_prev = hh_del->hh_prev;                             \\\n    }\n\n/* Bucket expansion has the effect of doubling the number of buckets\n * and redistributing the items into the new buckets. Ideally the\n * items will distribute more or less evenly into the new buckets\n * (the extent to which this is true is a measure of the quality of\n * the hash function as it applies to the key domain).\n *\n * With the items distributed into more buckets, the chain length\n * (item count) in each bucket is reduced. Thus by expanding buckets\n * the hash keeps a bound on the chain length. This bounded chain\n * length is the essence of how a hash provides constant time lookup.\n *\n * The calculation of tbl->ideal_chain_maxlen below deserves some\n * explanation. First, keep in mind that we're calculating the ideal\n * maximum chain length based on the *new* (doubled) bucket count.\n * In fractions this is just n/b (n=number of items,b=new num buckets).\n * Since the ideal chain length is an integer, we want to calculate\n * ceil(n/b). We don't depend on floating point arithmetic in this\n * hash, so to calculate ceil(n/b) with integers we could write\n *\n *      ceil(n/b) = (n/b) + ((n%b)?1:0)\n *\n * and in fact a previous version of this hash did just that.\n * But now we have improved things a bit by recognizing that b is\n * always a power of two. We keep its base 2 log handy (call it lb),\n * so now we can write this with a bit shift and logical AND:\n *\n *      ceil(n/b) = (n>>lb) + ( (n & (b-1)) ? 1:0)\n *\n */\n#define HASH_EXPAND_BUCKETS(tbl)                                                \\\ndo {                                                                            \\\n    unsigned _he_bkt;                                                           \\\n    unsigned _he_bkt_i;                                                         \\\n    struct UT_hash_handle *_he_thh, *_he_hh_nxt;                                \\\n    UT_hash_bucket *_he_new_buckets, *_he_newbkt;                               \\\n    _he_new_buckets = (UT_hash_bucket*)uthash_malloc(                           \\\n             2 * tbl->num_buckets * sizeof(struct UT_hash_bucket));             \\\n    if (!_he_new_buckets) { uthash_fatal( \"out of memory\"); }                   \\\n    memset(_he_new_buckets, 0,                                                  \\\n            2 * tbl->num_buckets * sizeof(struct UT_hash_bucket));              \\\n    tbl->ideal_chain_maxlen =                                                   \\\n       (tbl->num_items >> (tbl->log2_num_buckets+1)) +                          \\\n       ((tbl->num_items & ((tbl->num_buckets*2)-1)) ? 1 : 0);                   \\\n    tbl->nonideal_items = 0;                                                    \\\n    for(_he_bkt_i = 0; _he_bkt_i < tbl->num_buckets; _he_bkt_i++)               \\\n    {                                                                           \\\n        _he_thh = tbl->buckets[ _he_bkt_i ].hh_head;                            \\\n        while (_he_thh) {                                                       \\\n           _he_hh_nxt = _he_thh->hh_next;                                       \\\n           HASH_TO_BKT( _he_thh->hashv, tbl->num_buckets*2, _he_bkt);           \\\n           _he_newbkt = &(_he_new_buckets[ _he_bkt ]);                          \\\n           if (++(_he_newbkt->count) > tbl->ideal_chain_maxlen) {               \\\n             tbl->nonideal_items++;                                             \\\n             _he_newbkt->expand_mult = _he_newbkt->count /                      \\\n                                        tbl->ideal_chain_maxlen;                \\\n           }                                                                    \\\n           _he_thh->hh_prev = NULL;                                             \\\n           _he_thh->hh_next = _he_newbkt->hh_head;                              \\\n           if (_he_newbkt->hh_head) _he_newbkt->hh_head->hh_prev =              \\\n                _he_thh;                                                        \\\n           _he_newbkt->hh_head = _he_thh;                                       \\\n           _he_thh = _he_hh_nxt;                                                \\\n        }                                                                       \\\n    }                                                                           \\\n    tbl->num_buckets *= 2;                                                      \\\n    tbl->log2_num_buckets++;                                                    \\\n    uthash_free( tbl->buckets );                                                \\\n    tbl->buckets = _he_new_buckets;                                             \\\n    tbl->ineff_expands = (tbl->nonideal_items > (tbl->num_items >> 1)) ?        \\\n        (tbl->ineff_expands+1) : 0;                                             \\\n    if (tbl->ineff_expands > 1) {                                               \\\n        tbl->noexpand=1;                                                        \\\n        uthash_noexpand_fyi(tbl);                                               \\\n    }                                                                           \\\n    uthash_expand_fyi(tbl);                                                     \\\n} while(0)\n\n\n/* This is an adaptation of Simon Tatham's O(n log(n)) mergesort */\n/* Note that HASH_SORT assumes the hash handle name to be hh.\n * HASH_SRT was added to allow the hash handle name to be passed in. */\n#define HASH_SORT(head,cmpfcn) HASH_SRT(hh,head,cmpfcn)\n#define HASH_SRT(hh,head,cmpfcn)                                                \\\ndo {                                                                            \\\n  unsigned _hs_i;                                                               \\\n  unsigned _hs_looping,_hs_nmerges,_hs_insize,_hs_psize,_hs_qsize;              \\\n  struct UT_hash_handle *_hs_p, *_hs_q, *_hs_e, *_hs_list, *_hs_tail;           \\\n  if (head) {                                                                   \\\n      _hs_insize = 1;                                                           \\\n      _hs_looping = 1;                                                          \\\n      _hs_list = &((head)->hh);                                                 \\\n      while (_hs_looping) {                                                     \\\n          _hs_p = _hs_list;                                                     \\\n          _hs_list = NULL;                                                      \\\n          _hs_tail = NULL;                                                      \\\n          _hs_nmerges = 0;                                                      \\\n          while (_hs_p) {                                                       \\\n              _hs_nmerges++;                                                    \\\n              _hs_q = _hs_p;                                                    \\\n              _hs_psize = 0;                                                    \\\n              for ( _hs_i = 0; _hs_i  < _hs_insize; _hs_i++ ) {                 \\\n                  _hs_psize++;                                                  \\\n                  _hs_q = (UT_hash_handle*)((_hs_q->next) ?                     \\\n                          ((void*)((char*)(_hs_q->next) +                       \\\n                          (head)->hh.tbl->hho)) : NULL);                        \\\n                  if (! (_hs_q) ) break;                                        \\\n              }                                                                 \\\n              _hs_qsize = _hs_insize;                                           \\\n              while ((_hs_psize > 0) || ((_hs_qsize > 0) && _hs_q )) {          \\\n                  if (_hs_psize == 0) {                                         \\\n                      _hs_e = _hs_q;                                            \\\n                      _hs_q = (UT_hash_handle*)((_hs_q->next) ?                 \\\n                              ((void*)((char*)(_hs_q->next) +                   \\\n                              (head)->hh.tbl->hho)) : NULL);                    \\\n                      _hs_qsize--;                                              \\\n                  } else if ( (_hs_qsize == 0) || !(_hs_q) ) {                  \\\n                      _hs_e = _hs_p;                                            \\\n                      _hs_p = (UT_hash_handle*)((_hs_p->next) ?                 \\\n                              ((void*)((char*)(_hs_p->next) +                   \\\n                              (head)->hh.tbl->hho)) : NULL);                    \\\n                      _hs_psize--;                                              \\\n                  } else if ((                                                  \\\n                      cmpfcn(TYPEOF(head)(ELMT_FROM_HH((head)->hh.tbl,_hs_p)),  \\\n                            TYPEOF(head)(ELMT_FROM_HH((head)->hh.tbl,_hs_q)))   \\\n                             ) <= 0) {                                          \\\n                      _hs_e = _hs_p;                                            \\\n                      _hs_p = (UT_hash_handle*)((_hs_p->next) ?                 \\\n                              ((void*)((char*)(_hs_p->next) +                   \\\n                              (head)->hh.tbl->hho)) : NULL);                    \\\n                      _hs_psize--;                                              \\\n                  } else {                                                      \\\n                      _hs_e = _hs_q;                                            \\\n                      _hs_q = (UT_hash_handle*)((_hs_q->next) ?                 \\\n                              ((void*)((char*)(_hs_q->next) +                   \\\n                              (head)->hh.tbl->hho)) : NULL);                    \\\n                      _hs_qsize--;                                              \\\n                  }                                                             \\\n                  if ( _hs_tail ) {                                             \\\n                      _hs_tail->next = ((_hs_e) ?                               \\\n                            ELMT_FROM_HH((head)->hh.tbl,_hs_e) : NULL);         \\\n                  } else {                                                      \\\n                      _hs_list = _hs_e;                                         \\\n                  }                                                             \\\n                  _hs_e->prev = ((_hs_tail) ?                                   \\\n                     ELMT_FROM_HH((head)->hh.tbl,_hs_tail) : NULL);             \\\n                  _hs_tail = _hs_e;                                             \\\n              }                                                                 \\\n              _hs_p = _hs_q;                                                    \\\n          }                                                                     \\\n          _hs_tail->next = NULL;                                                \\\n          if ( _hs_nmerges <= 1 ) {                                             \\\n              _hs_looping=0;                                                    \\\n              (head)->hh.tbl->tail = _hs_tail;                                  \\\n              (head) = TYPEOF(head)ELMT_FROM_HH((head)->hh.tbl, _hs_list);      \\\n          }                                                                     \\\n          _hs_insize *= 2;                                                      \\\n      }                                                                         \\\n      HASH_FSCK(hh,head);                                                       \\\n }                                                                              \\\n} while (0)\n\n/* This function selects items from one hash into another hash.\n * The end result is that the selected items have dual presence\n * in both hashes. There is no copy of the items made; rather\n * they are added into the new hash through a secondary hash\n * hash handle that must be present in the structure. */\n#define HASH_SELECT(hh_dst, dst, hh_src, src, cond)                             \\\ndo {                                                                            \\\n  unsigned _src_bkt, _dst_bkt;                                                  \\\n  void *_last_elt=NULL, *_elt;                                                  \\\n  UT_hash_handle *_src_hh, *_dst_hh, *_last_elt_hh=NULL;                        \\\n  ptrdiff_t _dst_hho = ((char*)(&(dst)->hh_dst) - (char*)(dst));                \\\n  if (src) {                                                                    \\\n    for(_src_bkt=0; _src_bkt < (src)->hh_src.tbl->num_buckets; _src_bkt++) {    \\\n      for(_src_hh = (src)->hh_src.tbl->buckets[_src_bkt].hh_head;               \\\n          _src_hh;                                                              \\\n          _src_hh = _src_hh->hh_next) {                                         \\\n          _elt = ELMT_FROM_HH((src)->hh_src.tbl, _src_hh);                      \\\n          if (cond(_elt)) {                                                     \\\n            _dst_hh = (UT_hash_handle*)(((char*)_elt) + _dst_hho);              \\\n            _dst_hh->key = _src_hh->key;                                        \\\n            _dst_hh->keylen = _src_hh->keylen;                                  \\\n            _dst_hh->hashv = _src_hh->hashv;                                    \\\n            _dst_hh->prev = _last_elt;                                          \\\n            _dst_hh->next = NULL;                                               \\\n            if (_last_elt_hh) { _last_elt_hh->next = _elt; }                    \\\n            if (!dst) {                                                         \\\n              dst = TYPEOF(dst)_elt;                                            \\\n              HASH_MAKE_TABLE(hh_dst,dst);                                      \\\n            } else {                                                            \\\n              _dst_hh->tbl = (dst)->hh_dst.tbl;                                 \\\n            }                                                                   \\\n            HASH_TO_BKT(_dst_hh->hashv, _dst_hh->tbl->num_buckets, _dst_bkt);   \\\n            HASH_ADD_TO_BKT(_dst_hh->tbl->buckets[_dst_bkt],_dst_hh);           \\\n            (dst)->hh_dst.tbl->num_items++;                                     \\\n            _last_elt = _elt;                                                   \\\n            _last_elt_hh = _dst_hh;                                             \\\n          }                                                                     \\\n      }                                                                         \\\n    }                                                                           \\\n  }                                                                             \\\n  HASH_FSCK(hh_dst,dst);                                                        \\\n} while (0)\n\n#define HASH_CLEAR(hh,head)                                                     \\\ndo {                                                                            \\\n  if (head) {                                                                   \\\n    uthash_free((head)->hh.tbl->buckets );                                      \\\n    uthash_free((head)->hh.tbl);                                                \\\n    (head)=NULL;                                                                \\\n  }                                                                             \\\n} while(0)\n\n/* obtain a count of items in the hash */\n#define HASH_COUNT(head) HASH_CNT(hh,head)\n#define HASH_CNT(hh,head) (head?(head->hh.tbl->num_items):0)\n\ntypedef struct UT_hash_bucket {\n   struct UT_hash_handle *hh_head;\n   unsigned count;\n\n   /* expand_mult is normally set to 0. In this situation, the max chain length\n    * threshold is enforced at its default value, HASH_BKT_CAPACITY_THRESH. (If\n    * the bucket's chain exceeds this length, bucket expansion is triggered).\n    * However, setting expand_mult to a non-zero value delays bucket expansion\n    * (that would be triggered by additions to this particular bucket)\n    * until its chain length reaches a *multiple* of HASH_BKT_CAPACITY_THRESH.\n    * (The multiplier is simply expand_mult+1). The whole idea of this\n    * multiplier is to reduce bucket expansions, since they are expensive, in\n    * situations where we know that a particular bucket tends to be overused.\n    * It is better to let its chain length grow to a longer yet-still-bounded\n    * value, than to do an O(n) bucket expansion too often.\n    */\n   unsigned expand_mult;\n\n} UT_hash_bucket;\n\n/* random signature used only to find hash tables in external analysis */\n#define HASH_SIGNATURE 0xa0111fe1\n#define HASH_BLOOM_SIGNATURE 0xb12220f2\n\ntypedef struct UT_hash_table {\n   UT_hash_bucket *buckets;\n   unsigned num_buckets, log2_num_buckets;\n   unsigned num_items;\n   struct UT_hash_handle *tail; /* tail hh in app order, for fast append    */\n   ptrdiff_t hho; /* hash handle offset (byte pos of hash handle in element */\n\n   /* in an ideal situation (all buckets used equally), no bucket would have\n    * more than ceil(#items/#buckets) items. that's the ideal chain length. */\n   unsigned ideal_chain_maxlen;\n\n   /* nonideal_items is the number of items in the hash whose chain position\n    * exceeds the ideal chain maxlen. these items pay the penalty for an uneven\n    * hash distribution; reaching them in a chain traversal takes >ideal steps */\n   unsigned nonideal_items;\n\n   /* ineffective expands occur when a bucket doubling was performed, but\n    * afterward, more than half the items in the hash had nonideal chain\n    * positions. If this happens on two consecutive expansions we inhibit any\n    * further expansion, as it's not helping; this happens when the hash\n    * function isn't a good fit for the key domain. When expansion is inhibited\n    * the hash will still work, albeit no longer in constant time. */\n   unsigned ineff_expands, noexpand;\n\n   uint32_t signature; /* used only to find hash tables in external analysis */\n#if defined(HASH_BLOOM)\n   uint32_t bloom_sig; /* used only to test bloom exists in external analysis */\n   uint8_t *bloom_bv;\n   char bloom_nbits;\n#endif\n\n} UT_hash_table;\n\ntypedef struct UT_hash_handle {\n   struct UT_hash_table *tbl;\n   void *prev;                       /* prev element in app order      */\n   void *next;                       /* next element in app order      */\n   struct UT_hash_handle *hh_prev;   /* previous hh in bucket order    */\n   struct UT_hash_handle *hh_next;   /* next hh in bucket order        */\n   void *key;                        /* ptr to enclosing struct's key  */\n   unsigned keylen;                  /* enclosing struct's key len     */\n   unsigned hashv;                   /* result of hash-fcn(key)        */\n} UT_hash_handle;\n\n#endif /* UTHASH_H */\n"
  },
  {
    "path": "pkg/internal/robotgo/base/xdisplay.h",
    "content": "#pragma once\n#ifndef XDISPLAY_H\n#define XDISPLAY_H\n\n#include <X11/Xlib.h>\n\n/* Returns the main display, closed either on exit or when closeMainDisplay()\n * is invoked. This removes a bit of the overhead of calling XOpenDisplay() &\n * XCloseDisplay() everytime the main display needs to be used.\n *\n * Note that this is almost certainly not thread safe. */\nDisplay *XGetMainDisplay(void);\n\n/* Closes the main display if it is open, or does nothing if not. */\nvoid XCloseMainDisplay(void);\n\n#ifdef __cplusplus\nextern \"C\"\n{\n#endif\n\nchar *getXDisplay(void);\nvoid setXDisplay(char *name);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* XDISPLAY_H */\n"
  },
  {
    "path": "pkg/internal/robotgo/base/xdisplay_c.h",
    "content": "#include \"xdisplay.h\"\n#include <stdio.h> /* For fputs() */\n#include <stdlib.h> /* For atexit() */\n\nstatic Display *mainDisplay = NULL;\nstatic int registered = 0;\nstatic char *displayName = \":0.0\";\nstatic int hasDisplayNameChanged = 0;\n\nDisplay *XGetMainDisplay(void)\n{\n\t/* Close the display if displayName has changed */\n\tif (hasDisplayNameChanged) {\n\t\tXCloseMainDisplay();\n\t\thasDisplayNameChanged = 0;\n\t}\n\n\tif (mainDisplay == NULL) {\n\t\t/* First try the user set displayName */\n\t\tmainDisplay = XOpenDisplay(displayName);\n\n\t\t/* Then try using environment variable DISPLAY */\n\t\tif (mainDisplay == NULL) {\n\t\t\tmainDisplay = XOpenDisplay(NULL);\n\t\t}\n\n\t\tif (mainDisplay == NULL) {\n\t\t\tfputs(\"Could not open main display\\n\", stderr);\n\t\t} else if (!registered) {\n\t\t\tatexit(&XCloseMainDisplay);\n\t\t\tregistered = 1;\n\t\t}\n\t}\n\n\treturn mainDisplay;\n}\n\nvoid XCloseMainDisplay(void)\n{\n\tif (mainDisplay != NULL) {\n\t\tXCloseDisplay(mainDisplay);\n\t\tmainDisplay = NULL;\n\t}\n}\n\nvoid setXDisplay(char *name)\n{\n\tdisplayName = strdup(name);\n\thasDisplayNameChanged = 1;\n}\n\nchar *getXDisplay(void)\n{\n\treturn displayName;\n}\n\n"
  },
  {
    "path": "pkg/internal/robotgo/base/zlib_util.h",
    "content": "#pragma once\n#ifndef ZLIB_UTIL_H\n#define ZLIB_UTIL_H\n\n#include <stddef.h>\n\n#if defined(_MSC_VER)\n\t#include \"ms_stdint.h\"\n#else\n\t#include <stdint.h>\n#endif\n\n/* Attempts to decompress given deflated NUL-terminated buffer.\n *\n * If successful and |len| is not NULL, |len| will be set to the number of\n * bytes in the returned buffer.\n * Returns new string to be free()'d by caller, or NULL on error. */\nuint8_t *zlib_decompress(const uint8_t *buf, size_t *len);\n\n/* Attempt to compress given buffer.\n *\n * The compression level is passed directly to zlib: it must between 0 and 9,\n * where 1 gives best speed, 9 gives best compression, and 0 gives no\n * compression at all.\n *\n * If successful and |len| is not NULL, |len| will be set to the number of\n * bytes in the returned buffer.\n * Returns new string to be free()'d by caller, or NULL on error. */\nuint8_t *zlib_compress(const uint8_t *buf, const size_t buflen, int level,\n                       size_t *len);\n\n#endif /* ZLIB_UTIL_H */\n"
  },
  {
    "path": "pkg/internal/robotgo/base/zlib_util_c.h",
    "content": "#include \"zlib_util.h\"\n#include <zlib.h>\n#include <stdio.h> /* fprintf() */\n#include <stdlib.h> /* malloc() */\n#include <assert.h>\n\n#define ZLIB_CHUNK (16 * 1024)\n\nuint8_t *zlib_decompress(const uint8_t *buf, size_t *len){\n\tsize_t output_size = ZLIB_CHUNK;\n\tuint8_t *output = malloc(output_size);\n\tint err;\n\tz_stream zst;\n\n\t/* Sanity check */\n\tif (output == NULL) return NULL;\n\tassert(buf != NULL);\n\n\t/* Set inflate state */\n\tzst.zalloc = Z_NULL;\n\tzst.zfree = Z_NULL;\n\tzst.opaque = Z_NULL;\n\tzst.next_out = (Byte *)output;\n\tzst.next_in = (Byte *)buf;\n\tzst.avail_out = ZLIB_CHUNK;\n\n\tif (inflateInit(&zst) != Z_OK) goto error;\n\n\t/* Decompress input buffer */\n\tdo {\n\t\tif ((err = inflate(&zst, Z_NO_FLUSH)) == Z_OK) { /* Need more memory */\n\t\t\tzst.avail_out = (uInt)output_size;\n\n\t\t\t/* Double size each time to avoid calls to realloc() */\n\t\t\toutput_size <<= 1;\n\t\t\toutput = realloc(output, output_size + 1);\n\t\t\tif (output == NULL) return NULL;\n\n\t\t\tzst.next_out = (Byte *)(output + zst.avail_out);\n\t\t} else if (err != Z_STREAM_END) { /* Error decompressing */\n\t\t\tif (zst.msg != NULL) {\n\t\t\t\tfprintf(stderr, \"Could not decompress data: %s\\n\", zst.msg);\n\t\t\t}\n\t\t\tinflateEnd(&zst);\n\t\t\tgoto error;\n\t\t}\n\t} while (err != Z_STREAM_END);\n\n\tif (len != NULL) *len = zst.total_out;\n\tif (inflateEnd(&zst) != Z_OK) goto error;\n\treturn output; /* To be free()'d by caller */\n\nerror:\n\tif (output != NULL) free(output);\n\treturn NULL;\n}\n\nuint8_t *zlib_compress(const uint8_t *buf, const size_t buflen, int level,\n                       size_t *len)\n{\n\tz_stream zst;\n\tuint8_t *output = NULL;\n\n\t/* Sanity check */\n\tassert(buf != NULL);\n\tassert(len != NULL);\n\tassert(level <= 9 && level >= 0);\n\n\tzst.avail_out = (uInt)((buflen + (buflen / 10)) + 12);\n\toutput = malloc(zst.avail_out);\n\tif (output == NULL) return NULL;\n\n\t/* Set deflate state */\n\tzst.zalloc = Z_NULL;\n\tzst.zfree = Z_NULL;\n\tzst.next_out = (Byte *)output;\n\tzst.next_in = (Byte *)buf;\n\tzst.avail_in = (uInt)buflen;\n\n\tif (deflateInit(&zst, level) != Z_OK) goto error;\n\n\t/* Compress input buffer */\n\tif (deflate(&zst, Z_FINISH) != Z_STREAM_END) {\n\t\tif (zst.msg != NULL) {\n\t\t\tfprintf(stderr, \"Could not compress data: %s\\n\", zst.msg);\n\t\t}\n\t\tdeflateEnd(&zst);\n\t\tgoto error;\n\t}\n\n\tif (len != NULL) *len = zst.total_out;\n\tif (deflateEnd(&zst) != Z_OK) goto error;\n\treturn output; /* To be free()'d by caller */\n\nerror:\n\tif (output != NULL) free(output);\n\treturn NULL;\n}\n"
  },
  {
    "path": "pkg/internal/robotgo/mouse/goMouse.h",
    "content": "// Copyright 2016 The go-vgo Project Developers. See the COPYRIGHT\n// file at the top-level directory of this distribution and at\n// https://github.com/go-vgo/robotgo/blob/master/LICENSE\n//\n// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or\n// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license\n// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your\n// option. This file may not be copied, modified, or distributed\n// except according to those terms.\n\n#include \"../base/types.h\"\n#include \"mouse_c.h\"\n\n// Global delays.\nint mouseDelay = 10;\n\nint move_mouse(int32_t x, int32_t y)\n{\n\tMMPointInt32 point;\n\tpoint = MMPointInt32Make(x, y);\n\tmoveMouse(point);\n\n\treturn 0;\n}\n\nint drag_mouse(int32_t x, int32_t y, MMMouseButton button)\n{\n\tMMPointInt32 point;\n\tpoint = MMPointInt32Make(x, y);\n\tdragMouse(point, button);\n\n\treturn 0;\n}\n\nbool move_mouse_smooth(int32_t x, int32_t y, double lowSpeed,\n\t\t\t\t\t   double highSpeed, int msDelay)\n{\n\tMMPointInt32 point;\n\tpoint = MMPointInt32Make(x, y);\n\n\tbool cbool = smoothlyMoveMouse(point, lowSpeed, highSpeed);\n\tmicrosleep(msDelay);\n\n\treturn cbool;\n}\n\nMMPointInt32 get_mouse_pos()\n{\n\tMMPointInt32 pos = getMousePos();\n\n\treturn pos;\n}\n\nint mouse_click(MMMouseButton button, bool doubleC)\n{\n\tif (!doubleC)\n\t{\n\t\tclickMouse(button);\n\t}\n\telse\n\t{\n\t\tdoubleClick(button);\n\t}\n\n\tmicrosleep(mouseDelay);\n\n\treturn 0;\n}\n\nint mouse_toggle(char *d, MMMouseButton button)\n{\n\tbool down = false;\n\tif (strcmp(d, \"down\") == 0)\n\t{\n\t\tdown = true;\n\t}\n\telse if (strcmp(d, \"up\") == 0)\n\t{\n\t\tdown = false;\n\t}\n\telse\n\t{\n\t\treturn 1;\n\t}\n\n\ttoggleMouse(down, button);\n\tmicrosleep(mouseDelay);\n\n\treturn 0;\n}\n\nint set_mouse_delay(size_t val)\n{\n\tmouseDelay = val;\n\n\treturn 0;\n}\n\nint scroll(int x, int y, int msDelay)\n{\n\tscrollMouseXY(x, y);\n\tmicrosleep(msDelay);\n\n\treturn 0;\n}\n\nint scroll_mouse(size_t scrollMagnitude, char *s)\n{\n\tMMMouseWheelDirection scrollDirection;\n\n\tif (strcmp(s, \"up\") == 0)\n\t{\n\t\tscrollDirection = DIRECTION_UP;\n\t}\n\telse if (strcmp(s, \"down\") == 0)\n\t{\n\t\tscrollDirection = DIRECTION_DOWN;\n\t}\n\telse\n\t{\n\t\t// return \"Invalid scroll direction specified.\";\n\t\treturn 1;\n\t}\n\n\tscrollMouse(scrollMagnitude, scrollDirection);\n\tmicrosleep(mouseDelay);\n\n\treturn 0;\n}\n"
  },
  {
    "path": "pkg/internal/robotgo/mouse/mouse.h",
    "content": "#pragma once\n#ifndef MOUSE_H\n#define MOUSE_H\n\n#include \"../base/os.h\"\n#include \"../base/types.h\"\n\n#if defined(_MSC_VER)\n#include \"../base/ms_stdbool.h\"\n#else\n#include <stdbool.h>\n#endif\n\n#ifdef __cplusplus\n// #ifdefined(__cplusplus)||defined(c_plusplus)\nextern \"C\"\n{\n#endif\n\n#if defined(IS_MACOSX)\n\n#include <ApplicationServices/ApplicationServices.h>\n\n\ttypedef enum\n\t{\n\t\tLEFT_BUTTON = kCGMouseButtonLeft,\n\t\tRIGHT_BUTTON = kCGMouseButtonRight,\n\t\tCENTER_BUTTON = kCGMouseButtonCenter\n\t} MMMouseButton;\n\n#elif defined(USE_X11)\n\nenum _MMMouseButton\n{\n\tLEFT_BUTTON = 1,\n\tCENTER_BUTTON = 2,\n\tRIGHT_BUTTON = 3\n};\ntypedef unsigned int MMMouseButton;\n\n#elif defined(IS_WINDOWS)\n\nenum _MMMouseButton\n{\n\tLEFT_BUTTON = 1,\n\tCENTER_BUTTON = 2,\n\tRIGHT_BUTTON = 3\n};\ntypedef unsigned int MMMouseButton;\n\n#else\n#error \"No mouse button constants set for platform\"\n#endif\n\n#define MMMouseButtonIsValid(button)                    \\\n\t(button == LEFT_BUTTON || button == RIGHT_BUTTON || \\\n\t button == CENTER_BUTTON)\n\n\tenum __MMMouseWheelDirection\n\t{\n\t\tDIRECTION_DOWN = -1,\n\t\tDIRECTION_UP = 1\n\t};\n\ttypedef int MMMouseWheelDirection;\n\n\t/* Immediately moves the mouse to the given point on-screen.\n * It is up to the caller to ensure that this point is within the\n * screen boundaries. */\n\tvoid moveMouse(MMPointInt32 point);\n\n\t/* Like moveMouse, moves the mouse to the given point on-screen, but marks\n * the event as the mouse being dragged on platforms where it is supported.\n * It is up to the caller to ensure that this point is within the screen\n * boundaries. */\n\tvoid dragMouse(MMPointInt32 point, const MMMouseButton button);\n\n\t/* Smoothly moves the mouse from the current position to the given point.\n * deadbeef_srand() should be called before using this function.\n *\n * Returns false if unsuccessful (i.e. a point was hit that is outside of the\n * screen boundaries), or true if successful. */\n\tbool smoothlyMoveMouse(MMPointInt32 endPoint, double lowSpeed, double highSpeed);\n\t// bool smoothlyMoveMouse(MMPoint point);\n\n\t/* Returns the coordinates of the mouse on the current screen. */\n\tMMPointInt32 getMousePos(void);\n\n\t/* Holds down or releases the mouse with the given button in the current\n * position. */\n\tvoid toggleMouse(bool down, MMMouseButton button);\n\n\t/* Clicks the mouse with the given button in the current position. */\n\tvoid clickMouse(MMMouseButton button);\n\n\t/* Double clicks the mouse with the given button. */\n\tvoid doubleClick(MMMouseButton button);\n\n\t/* Scrolls the mouse in the stated direction.\n * TODO: Add a smoothly scroll mouse next. */\n\tvoid scrollMouse(int scrollMagnitude, MMMouseWheelDirection scrollDirection);\n\n//#ifdefined(__cplusplus)||defined(c_plusplus)\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* MOUSE_H */\n"
  },
  {
    "path": "pkg/internal/robotgo/mouse/mouse_c.h",
    "content": "#include \"mouse.h\"\n#include \"../base/deadbeef_rand_c.h\"\n#include \"../base/microsleep.h\"\n\n#include <math.h> /* For floor() */\n\n#if defined(IS_MACOSX)\n#include <ApplicationServices/ApplicationServices.h>\n#elif defined(USE_X11)\n#include <X11/Xlib.h>\n#include <X11/extensions/XTest.h>\n#include <stdlib.h>\n#endif\n\n#if !defined(M_SQRT2)\n#define M_SQRT2 1.4142135623730950488016887 /* Fix for MSVC. */\n#endif\n\n/* Some convenience macros for converting our enums to the system API types. */\n#if defined(IS_MACOSX)\n\n#define MMMouseToCGEventType(down, button) \\\n\t(down ? MMMouseDownToCGEventType(button) : MMMouseUpToCGEventType(button))\n\n#define MMMouseDownToCGEventType(button)                                            \\\n\t((button) == (LEFT_BUTTON) ? kCGEventLeftMouseDown                              \\\n\t\t\t\t\t\t\t   : ((button) == RIGHT_BUTTON ? kCGEventRightMouseDown \\\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t   : kCGEventOtherMouseDown))\n\n#define MMMouseUpToCGEventType(button)                                          \\\n\t((button) == LEFT_BUTTON ? kCGEventLeftMouseUp                              \\\n\t\t\t\t\t\t\t : ((button) == RIGHT_BUTTON ? kCGEventRightMouseUp \\\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t : kCGEventOtherMouseUp))\n\n#define MMMouseDragToCGEventType(button)                                             \\\n\t((button) == LEFT_BUTTON ? kCGEventLeftMouseDragged                              \\\n\t\t\t\t\t\t\t : ((button) == RIGHT_BUTTON ? kCGEventRightMouseDragged \\\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t : kCGEventOtherMouseDragged))\n\n#elif defined(IS_WINDOWS)\n\n#define MMMouseToMEventF(down, button) \\\n\t(down ? MMMouseDownToMEventF(button) : MMMouseUpToMEventF(button))\n\n#define MMMouseUpToMEventF(button)                                             \\\n\t((button) == LEFT_BUTTON ? MOUSEEVENTF_LEFTUP                              \\\n\t\t\t\t\t\t\t : ((button) == RIGHT_BUTTON ? MOUSEEVENTF_RIGHTUP \\\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t : MOUSEEVENTF_MIDDLEUP))\n\n#define MMMouseDownToMEventF(button)                                             \\\n\t((button) == LEFT_BUTTON ? MOUSEEVENTF_LEFTDOWN                              \\\n\t\t\t\t\t\t\t : ((button) == RIGHT_BUTTON ? MOUSEEVENTF_RIGHTDOWN \\\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t : MOUSEEVENTF_MIDDLEDOWN))\n\n#endif\n\n#if defined(IS_MACOSX)\n/**\n * Calculate the delta for a mouse move and add them to the event.\n * @param event The mouse move event (by ref).\n * @param point The new mouse x and y.\n */\nvoid calculateDeltas(CGEventRef *event, MMPointInt32 point)\n{\n\t/**\n\t * The next few lines are a workaround for games not detecting mouse moves.\n\t * See this issue for more information:\n\t * https://github.com/go-vgo/robotgo/issues/159\n\t */\n\tCGEventRef get = CGEventCreate(NULL);\n\tCGPoint mouse = CGEventGetLocation(get);\n\n\t// Calculate the deltas.\n\tint64_t deltaX = point.x - mouse.x;\n\tint64_t deltaY = point.y - mouse.y;\n\n\tCGEventSetIntegerValueField(*event, kCGMouseEventDeltaX, deltaX);\n\tCGEventSetIntegerValueField(*event, kCGMouseEventDeltaY, deltaY);\n\n\tCFRelease(get);\n}\n#endif\n\n/**\n * Move the mouse to a specific point.\n * @param point The coordinates to move the mouse to (x, y).\n */\nvoid moveMouse(MMPointInt32 point)\n{\n#if defined(IS_MACOSX)\n\tCGEventRef move = CGEventCreateMouseEvent(NULL, kCGEventMouseMoved,\n\t\t\t\t\t\t\t\t\t\t\t  CGPointFromMMPointInt32(point),\n\t\t\t\t\t\t\t\t\t\t\t  kCGMouseButtonLeft);\n\n\tcalculateDeltas(&move, point);\n\n\tCGEventPost(kCGSessionEventTap, move);\n\tCFRelease(move);\n#elif defined(USE_X11)\n\tDisplay *display = XGetMainDisplay();\n\tXWarpPointer(display, None, DefaultRootWindow(display),\n\t\t\t\t 0, 0, 0, 0, point.x, point.y);\n\n\tXSync(display, false);\n#elif defined(IS_WINDOWS)\n// Mouse motion is now done using SendInput with MOUSEINPUT.\n// We use Absolute mouse positioning\n#define MOUSE_COORD_TO_ABS(coord, width_or_height) ( \\\n\t((65536 * coord) / width_or_height) + (coord < 0 ? -1 : 1))\n\n\tpoint.x = MOUSE_COORD_TO_ABS(point.x, GetSystemMetrics(SM_CXSCREEN));\n\tpoint.y = MOUSE_COORD_TO_ABS(point.y, GetSystemMetrics(SM_CYSCREEN));\n\n\tINPUT mouseInput;\n\tmouseInput.type = INPUT_MOUSE;\n\tmouseInput.mi.dx = point.x;\n\tmouseInput.mi.dy = point.y;\n\tmouseInput.mi.dwFlags = MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE;\n\tmouseInput.mi.time = 0; // System will provide the timestamp\n\tmouseInput.mi.dwExtraInfo = 0;\n\tmouseInput.mi.mouseData = 0;\n\tSendInput(1, &mouseInput, sizeof(mouseInput));\n\n#endif\n}\n\nvoid dragMouse(MMPointInt32 point, const MMMouseButton button)\n{\n#if defined(IS_MACOSX)\n\tconst CGEventType dragType = MMMouseDragToCGEventType(button);\n\tCGEventRef drag = CGEventCreateMouseEvent(NULL, dragType,\n\t\t\t\t\t\t\t\t\t\t\t  CGPointFromMMPoint(point), (CGMouseButton)button);\n\n\tcalculateDeltas(&drag, point);\n\n\tCGEventPost(kCGSessionEventTap, drag);\n\tCFRelease(drag);\n#else\n\tmoveMouse(point);\n#endif\n}\n\nMMPointInt32 getMousePos()\n{\n#if defined(IS_MACOSX)\n\tCGEventRef event = CGEventCreate(NULL);\n\tCGPoint point = CGEventGetLocation(event);\n\tCFRelease(event);\n\n\treturn MMPointInt32FromCGPoint(point);\n#elif defined(USE_X11)\n\tint x, y;\t\t\t /* This is all we care about. Seriously. */\n\tWindow garb1, garb2; /* Why you can't specify NULL as a parameter */\n\tint garb_x, garb_y;  /* is beyond me. */\n\tunsigned int more_garbage;\n\n\tDisplay *display = XGetMainDisplay();\n\tXQueryPointer(display, XDefaultRootWindow(display), &garb1, &garb2,\n\t\t\t\t  &x, &y, &garb_x, &garb_y, &more_garbage);\n\n\treturn MMPointInt32Make(x, y);\n#elif defined(IS_WINDOWS)\n\tPOINT point;\n\tGetCursorPos(&point);\n\n\treturn MMPointInt32FromPOINT(point);\n#endif\n}\n\n/**\n * Press down a button, or release it.\n * @param down   True for down, false for up.\n * @param button The button to press down or release.\n */\nvoid toggleMouse(bool down, MMMouseButton button)\n{\n#if defined(IS_MACOSX)\n\tconst CGPoint currentPos = CGPointFromMMPoint(getMousePos());\n\tconst CGEventType mouseType = MMMouseToCGEventType(down, button);\n\tCGEventRef event = CGEventCreateMouseEvent(NULL,\n\t\t\t\t\t\t\t\t\t\t\t   mouseType, currentPos, (CGMouseButton)button);\n\n\tCGEventPost(kCGSessionEventTap, event);\n\tCFRelease(event);\n#elif defined(USE_X11)\n\tDisplay *display = XGetMainDisplay();\n\tXTestFakeButtonEvent(display, button, down ? True : False, CurrentTime);\n\tXSync(display, false);\n#elif defined(IS_WINDOWS)\n\t// mouse_event(MMMouseToMEventF(down, button), 0, 0, 0, 0);\n\n\tINPUT mouseInput;\n\n\tmouseInput.type = INPUT_MOUSE;\n\tmouseInput.mi.dx = 0;\n\tmouseInput.mi.dy = 0;\n\tmouseInput.mi.dwFlags = MMMouseToMEventF(down, button);\n\tmouseInput.mi.time = 0;\n\tmouseInput.mi.dwExtraInfo = 0;\n\tmouseInput.mi.mouseData = 0;\n\tSendInput(1, &mouseInput, sizeof(mouseInput));\n#endif\n}\n\nvoid clickMouse(MMMouseButton button)\n{\n\ttoggleMouse(true, button);\n\ttoggleMouse(false, button);\n}\n\n/**\n * Special function for sending double clicks, needed for Mac OS X.\n * @param button Button to click.\n */\nvoid doubleClick(MMMouseButton button)\n{\n#if defined(IS_MACOSX)\n\n\t/* Double click for Mac. */\n\tconst CGPoint currentPos = CGPointFromMMPoint(getMousePos());\n\tconst CGEventType mouseTypeDown = MMMouseToCGEventType(true, button);\n\tconst CGEventType mouseTypeUP = MMMouseToCGEventType(false, button);\n\n\tCGEventRef event = CGEventCreateMouseEvent(\n\t\tNULL, mouseTypeDown, currentPos, kCGMouseButtonLeft);\n\n\t/* Set event to double click. */\n\tCGEventSetIntegerValueField(event, kCGMouseEventClickState, 2);\n\n\tCGEventPost(kCGHIDEventTap, event);\n\n\tCGEventSetType(event, mouseTypeUP);\n\tCGEventPost(kCGHIDEventTap, event);\n\n\tCFRelease(event);\n\n#else\n\n\t/* Double click for everything else. */\n\tclickMouse(button);\n\tmicrosleep(200);\n\tclickMouse(button);\n\n#endif\n}\n\n/**\n * Function used to scroll the screen in the required direction.\n * This uses the magnitude to scroll the required amount in the direction.\n * TODO Requires further fine tuning based on the requirements.\n */\nvoid scrollMouse(int scrollMagnitude, MMMouseWheelDirection scrollDirection)\n{\n#if defined(IS_WINDOWS)\n\t// Fix for #97 https://github.com/go-vgo/robotgo/issues/97,\n\t// C89 needs variables declared on top of functions (mouseScrollInput)\n\tINPUT mouseScrollInput;\n#endif\n\n\t/* Direction should only be considered based on the scrollDirection. This\n\t * Should not interfere. */\n\tint cleanScrollMagnitude = abs(scrollMagnitude);\n\tif (!(scrollDirection == DIRECTION_UP || scrollDirection == DIRECTION_DOWN))\n\t{\n\t\treturn;\n\t}\n\n/* Set up the OS specific solution */\n#if defined(__APPLE__)\n\n\tCGWheelCount wheel = 1;\n\tCGEventRef event;\n\n\t/* Make scroll magnitude negative if we're scrolling down. */\n\tcleanScrollMagnitude = cleanScrollMagnitude * scrollDirection;\n\n\tevent = CGEventCreateScrollWheelEvent(NULL,\n\t\t\t\t\t\t\t\t\t\t  kCGScrollEventUnitLine, wheel, cleanScrollMagnitude, 0);\n\n\tCGEventPost(kCGHIDEventTap, event);\n\n#elif defined(USE_X11)\n\n\tint x;\n\tint dir = 4; /* Button 4 is up, 5 is down. */\n\tDisplay *display = XGetMainDisplay();\n\n\tif (scrollDirection == DIRECTION_DOWN)\n\t{\n\t\tdir = 5;\n\t}\n\n\tfor (x = 0; x < cleanScrollMagnitude; x++)\n\t{\n\t\tXTestFakeButtonEvent(display, dir, 1, CurrentTime);\n\t\tXTestFakeButtonEvent(display, dir, 0, CurrentTime);\n\t}\n\n\tXSync(display, false);\n\n#elif defined(IS_WINDOWS)\n\n\tmouseScrollInput.type = INPUT_MOUSE;\n\tmouseScrollInput.mi.dx = 0;\n\tmouseScrollInput.mi.dy = 0;\n\tmouseScrollInput.mi.dwFlags = MOUSEEVENTF_WHEEL;\n\tmouseScrollInput.mi.time = 0;\n\tmouseScrollInput.mi.dwExtraInfo = 0;\n\tmouseScrollInput.mi.mouseData = WHEEL_DELTA * scrollDirection * cleanScrollMagnitude;\n\n\tSendInput(1, &mouseScrollInput, sizeof(mouseScrollInput));\n\n#endif\n}\n\nvoid scrollMouseXY(int x, int y)\n{\n#if defined(IS_WINDOWS)\n\t// Fix for #97,\n\t// C89 needs variables declared on top of functions (mouseScrollInput)\n\tINPUT mouseScrollInputH;\n\tINPUT mouseScrollInputV;\n#endif\n\n/* Direction should only be considered based on the scrollDirection. This\n\t* Should not interfere. */\n\n/* Set up the OS specific solution */\n#if defined(__APPLE__)\n\n\tCGEventRef event;\n\n\tevent = CGEventCreateScrollWheelEvent(NULL, kCGScrollEventUnitPixel, 2, y, x);\n\tCGEventPost(kCGHIDEventTap, event);\n\n\tCFRelease(event);\n\n#elif defined(USE_X11)\n\n\tint ydir = 4; /* Button 4 is up, 5 is down. */\n\tint xdir = 6;\n\tDisplay *display = XGetMainDisplay();\n\n\tif (y < 0)\n\t{\n\t\tydir = 5;\n\t}\n\tif (x < 0)\n\t{\n\t\txdir = 7;\n\t}\n\n\tint xi;\n\tint yi;\n\tfor (xi = 0; xi < abs(x); xi++)\n\t{\n\t\tXTestFakeButtonEvent(display, xdir, 1, CurrentTime);\n\t\tXTestFakeButtonEvent(display, xdir, 0, CurrentTime);\n\t}\n\tfor (yi = 0; yi < abs(y); yi++)\n\t{\n\t\tXTestFakeButtonEvent(display, ydir, 1, CurrentTime);\n\t\tXTestFakeButtonEvent(display, ydir, 0, CurrentTime);\n\t}\n\n\tXSync(display, false);\n\n#elif defined(IS_WINDOWS)\n\n\tmouseScrollInputH.type = INPUT_MOUSE;\n\tmouseScrollInputH.mi.dx = 0;\n\tmouseScrollInputH.mi.dy = 0;\n\tmouseScrollInputH.mi.dwFlags = MOUSEEVENTF_WHEEL;\n\tmouseScrollInputH.mi.time = 0;\n\tmouseScrollInputH.mi.dwExtraInfo = 0;\n\tmouseScrollInputH.mi.mouseData = WHEEL_DELTA * x;\n\n\tmouseScrollInputV.type = INPUT_MOUSE;\n\tmouseScrollInputV.mi.dx = 0;\n\tmouseScrollInputV.mi.dy = 0;\n\tmouseScrollInputV.mi.dwFlags = MOUSEEVENTF_WHEEL;\n\tmouseScrollInputV.mi.time = 0;\n\tmouseScrollInputV.mi.dwExtraInfo = 0;\n\tmouseScrollInputV.mi.mouseData = WHEEL_DELTA * y;\n\n\tSendInput(1, &mouseScrollInputH, sizeof(mouseScrollInputH));\n\tSendInput(1, &mouseScrollInputV, sizeof(mouseScrollInputV));\n#endif\n}\n\n/*\n * A crude, fast hypot() approximation to get around the fact that hypot() is\n * not a standard ANSI C function.\n *\n * It is not particularly accurate but that does not matter for our use case.\n *\n * Taken from this StackOverflow answer:\n * http://stackoverflow.com/questions/3506404/fast-hypotenuse-algorithm-for-embedded-processor#3507882\n *\n */\nstatic double crude_hypot(double x, double y)\n{\n\tdouble big = fabs(x);   /* max(|x|, |y|) */\n\tdouble small = fabs(y); /* min(|x|, |y|) */\n\n\tif (big > small)\n\t{\n\t\tdouble temp = big;\n\t\tbig = small;\n\t\tsmall = temp;\n\t}\n\n\treturn ((M_SQRT2 - 1.0) * small) + big;\n}\n\nbool smoothlyMoveMouse(MMPointInt32 endPoint, double lowSpeed, double highSpeed)\n{\n\tMMPointInt32 pos = getMousePos();\n\tMMSizeInt32 screenSize = getMainDisplaySize();\n\tdouble velo_x = 0.0, velo_y = 0.0;\n\tdouble distance;\n\n\twhile ((distance =\n\t\t\t\tcrude_hypot((double)pos.x - endPoint.x, (double)pos.y - endPoint.y)) > 1.0)\n\t{\n\n\t\tdouble gravity = DEADBEEF_UNIFORM(5.0, 500.0);\n\t\t// double gravity = DEADBEEF_UNIFORM(lowSpeed, highSpeed);\n\t\tdouble veloDistance;\n\t\tvelo_x += (gravity * ((double)endPoint.x - pos.x)) / distance;\n\t\tvelo_y += (gravity * ((double)endPoint.y - pos.y)) / distance;\n\n\t\t/* Normalize velocity to get a unit vector of length 1. */\n\t\tveloDistance = crude_hypot(velo_x, velo_y);\n\t\tvelo_x /= veloDistance;\n\t\tvelo_y /= veloDistance;\n\n\t\tpos.x += floor(velo_x + 0.5);\n\t\tpos.y += floor(velo_y + 0.5);\n\n\t\t/* Make sure we are in the screen boundaries!\n\t\t * (Strange things will happen if we are not.) */\n\t\tif (pos.x >= screenSize.w || pos.y >= screenSize.h)\n\t\t{\n\t\t\treturn false;\n\t\t}\n\n\t\tmoveMouse(pos);\n\n\t\t/* Wait 1 - 3 milliseconds. */\n\t\tmicrosleep(DEADBEEF_UNIFORM(lowSpeed, highSpeed));\n\t\t// microsleep(DEADBEEF_UNIFORM(1.0, 3.0));\n\t}\n\n\treturn true;\n}\n"
  },
  {
    "path": "pkg/internal/robotgo/robotgo.go",
    "content": "// Copyright 2016 The go-vgo Project Developers. See the COPYRIGHT\n// file at the top-level directory of this distribution and at\n// https://github.com/go-vgo/robotgo/blob/master/LICENSE\n//\n// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or\n// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license\n// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your\n// option. This file may not be copied, modified, or distributed\n// except according to those terms.\n\n/*\n\nPackage robotgo Go native cross-platform system automation.\n\nPlease make sure Golang, GCC is installed correctly before installing RobotGo;\n\nSee Requirements:\n\thttps://github.com/go-vgo/robotgo#requirements\n\nInstallation:\n\tgo get -u github.com/go-vgo/robotgo\n*/\npackage robotgo\n\n/*\n//#if defined(IS_MACOSX)\n\t#cgo darwin CFLAGS: -x objective-c -Wno-deprecated-declarations\n\t#cgo darwin LDFLAGS: -framework Cocoa -framework OpenGL -framework IOKit\n\t#cgo darwin LDFLAGS: -framework Carbon -framework CoreFoundation\n//#elif defined(USE_X11)\n\t// Drop -std=c11\n\t#cgo linux CFLAGS: -I/usr/src\n\t#cgo linux LDFLAGS: -L/usr/src -lX11 -lXtst -lm\n//#endif\n\t#cgo windows LDFLAGS: -lgdi32 -luser32\n#include \"window/goWindow.h\"\n#include \"screen/goScreen.h\"\n#include \"mouse/goMouse.h\"\n*/\nimport \"C\"\n\nimport (\n\t\"time\"\n\t\"unsafe\"\n)\n\nconst (\n\t// Version get the robotgo version\n\tVersion = \"v0.90.0.940, Sierra Nevada!\"\n)\n\n// GetVersion get the robotgo version\nfunc GetVersion() string {\n\treturn Version\n}\n\ntype (\n\t// Map a map[string]interface{}\n\tMap map[string]interface{}\n)\n\n// Try handler(err)\nfunc Try(fun func(), handler func(interface{})) {\n\tdefer func() {\n\t\tif err := recover(); err != nil {\n\t\t\thandler(err)\n\t\t}\n\t}()\n\tfun()\n}\n\n// MilliSleep sleep tm milli second\nfunc MilliSleep(tm int) {\n\ttime.Sleep(time.Duration(tm) * time.Millisecond)\n}\n\n// Sleep time.Sleep tm second\nfunc Sleep(tm int) {\n\ttime.Sleep(time.Duration(tm) * time.Second)\n}\n\n// MicroSleep time C.microsleep(tm)\nfunc MicroSleep(tm float64) {\n\tC.microsleep(C.double(tm))\n}\n\n// GoString teans C.char to string\nfunc GoString(char *C.char) string {\n\treturn C.GoString(char)\n}\n\n// ScaleX get primary display horizontal DPI scale factor\nfunc ScaleX() int {\n\treturn int(C.scale_x())\n}\n\n// ScaleY get primary display vertical DPI scale factor\nfunc ScaleY() int {\n\treturn int(C.scale_y())\n}\n\n// GetScreenSize get the screen size\nfunc GetScreenSize() (int, int) {\n\tsize := C.get_screen_size()\n\t// fmt.Println(\"...\", size, size.width)\n\treturn int(size.w), int(size.h)\n}\n\n// Scale get the screen scale\nfunc Scale() int {\n\tdpi := map[int]int{\n\t\t0: 100,\n\t\t// DPI Scaling Level\n\t\t96:  100,\n\t\t120: 125,\n\t\t144: 150,\n\t\t168: 175,\n\t\t192: 200,\n\t\t216: 225,\n\t\t// Custom DPI\n\t\t240: 250,\n\t\t288: 300,\n\t\t384: 400,\n\t\t480: 500,\n\t}\n\n\tx := ScaleX()\n\treturn dpi[x]\n}\n\n// Mul mul the scale\nfunc Mul(x int) int {\n\ts := Scale()\n\treturn x * s / 100\n}\n\n// GetScaleSize get the screen scale size\nfunc GetScaleSize() (int, int) {\n\tx, y := GetScreenSize()\n\ts := Scale()\n\treturn x * s / 100, y * s / 100\n}\n\n// SetXDisplayName set XDisplay name (Linux)\nfunc SetXDisplayName(name string) string {\n\tcname := C.CString(name)\n\tstr := C.set_XDisplay_name(cname)\n\n\tgstr := C.GoString(str)\n\tC.free(unsafe.Pointer(cname))\n\n\treturn gstr\n}\n\n// GetXDisplayName get XDisplay name (Linux)\nfunc GetXDisplayName() string {\n\tname := C.get_XDisplay_name()\n\tgname := C.GoString(name)\n\tC.free(unsafe.Pointer(name))\n\n\treturn gname\n}\n\n/*\n.___  ___.   ______    __    __       _______. _______\n|   \\/   |  /  __  \\  |  |  |  |     /       ||   ____|\n|  \\  /  | |  |  |  | |  |  |  |    |   (----`|  |__\n|  |\\/|  | |  |  |  | |  |  |  |     \\   \\    |   __|\n|  |  |  | |  `--'  | |  `--'  | .----)   |   |  |____\n|__|  |__|  \\______/   \\______/  |_______/    |_______|\n\n*/\n\n// CheckMouse check the mouse button\nfunc CheckMouse(btn string) C.MMMouseButton {\n\t// button = args[0].(C.MMMouseButton)\n\tif btn == \"left\" {\n\t\treturn C.LEFT_BUTTON\n\t}\n\n\tif btn == \"center\" {\n\t\treturn C.CENTER_BUTTON\n\t}\n\n\tif btn == \"right\" {\n\t\treturn C.RIGHT_BUTTON\n\t}\n\n\treturn C.LEFT_BUTTON\n}\n\n// MoveMouse move the mouse\nfunc MoveMouse(x, y int) {\n\t// C.size_t  int\n\tMove(x, y)\n}\n\n// Move move the mouse\nfunc Move(x, y int) {\n\tcx := C.int32_t(x)\n\tcy := C.int32_t(y)\n\tC.move_mouse(cx, cy)\n}\n\n// DragMouse drag the mouse\nfunc DragMouse(x, y int, args ...string) {\n\tDrag(x, y, args...)\n}\n\n// Drag drag the mouse\nfunc Drag(x, y int, args ...string) {\n\tvar button C.MMMouseButton = C.LEFT_BUTTON\n\n\tcx := C.int32_t(x)\n\tcy := C.int32_t(y)\n\n\tif len(args) > 0 {\n\t\tbutton = CheckMouse(args[0])\n\t}\n\n\tC.drag_mouse(cx, cy, button)\n}\n\n// DragSmooth drag the mouse smooth\nfunc DragSmooth(x, y int, args ...interface{}) {\n\tMouseToggle(\"down\")\n\tMoveSmooth(x, y, args...)\n\tMouseToggle(\"up\")\n}\n\n// MoveMouseSmooth move the mouse smooth,\n// moves mouse to x, y human like, with the mouse button up.\nfunc MoveMouseSmooth(x, y int, args ...interface{}) bool {\n\treturn MoveSmooth(x, y, args...)\n}\n\n// MoveSmooth move the mouse smooth,\n// moves mouse to x, y human like, with the mouse button up.\n//\n// robotgo.MoveSmooth(x, y int, low, high float64, mouseDelay int)\nfunc MoveSmooth(x, y int, args ...interface{}) bool {\n\tcx := C.int32_t(x)\n\tcy := C.int32_t(y)\n\n\tvar (\n\t\tmouseDelay = 10\n\t\tlow        C.double\n\t\thigh       C.double\n\t)\n\n\tif len(args) > 2 {\n\t\tmouseDelay = args[2].(int)\n\t}\n\n\tif len(args) > 1 {\n\t\tlow = C.double(args[0].(float64))\n\t\thigh = C.double(args[1].(float64))\n\t} else {\n\t\tlow = 1.0\n\t\thigh = 3.0\n\t}\n\n\tcbool := C.move_mouse_smooth(cx, cy, low, high, C.int(mouseDelay))\n\n\treturn bool(cbool)\n}\n\n// GetMousePos get mouse's portion\nfunc GetMousePos() (int, int) {\n\tpos := C.get_mouse_pos()\n\n\tx := int(pos.x)\n\ty := int(pos.y)\n\n\treturn x, y\n}\n\n// MouseClick click the mouse\n//\n// robotgo.MouseClick(button string, double bool)\nfunc MouseClick(args ...interface{}) {\n\tClick(args...)\n}\n\n// Click click the mouse\n//\n// robotgo.Click(button string, double bool)\nfunc Click(args ...interface{}) {\n\tvar (\n\t\tbutton C.MMMouseButton = C.LEFT_BUTTON\n\t\tdouble C.bool\n\t)\n\n\tif len(args) > 0 {\n\t\tbutton = CheckMouse(args[0].(string))\n\t}\n\n\tif len(args) > 1 {\n\t\tdouble = C.bool(args[1].(bool))\n\t}\n\n\tC.mouse_click(button, double)\n}\n\n// MoveClick move and click the mouse\n//\n// robotgo.MoveClick(x, y int, button string, double bool)\nfunc MoveClick(x, y int, args ...interface{}) {\n\tMoveMouse(x, y)\n\tMouseClick(args...)\n}\n\n// MovesClick move smooth and click the mouse\nfunc MovesClick(x, y int, args ...interface{}) {\n\tMoveSmooth(x, y)\n\tMouseClick(args...)\n}\n\n// MouseToggle toggle the mouse\nfunc MouseToggle(togKey string, args ...interface{}) {\n\tvar button C.MMMouseButton = C.LEFT_BUTTON\n\n\tif len(args) > 0 {\n\t\tbutton = CheckMouse(args[0].(string))\n\t}\n\n\tdown := C.CString(togKey)\n\tC.mouse_toggle(down, button)\n\n\tC.free(unsafe.Pointer(down))\n}\n\n// SetMouseDelay set mouse delay\nfunc SetMouseDelay(delay int) {\n\tcdelay := C.size_t(delay)\n\tC.set_mouse_delay(cdelay)\n}\n\n// ScrollMouse scroll the mouse\nfunc ScrollMouse(x int, direction string) {\n\tcx := C.size_t(x)\n\tcy := C.CString(direction)\n\tC.scroll_mouse(cx, cy)\n\n\tC.free(unsafe.Pointer(cy))\n}\n\n// Scroll scroll the mouse with x, y\n//\n// robotgo.Scroll(x, y, msDelay int)\nfunc Scroll(x, y int, args ...int) {\n\tvar msDelay = 10\n\tif len(args) > 0 {\n\t\tmsDelay = args[0]\n\t}\n\n\tcx := C.int(x)\n\tcy := C.int(y)\n\tcz := C.int(msDelay)\n\n\tC.scroll(cx, cy, cz)\n}\n"
  },
  {
    "path": "pkg/internal/robotgo/screen/goScreen.h",
    "content": "// Copyright 2016 The go-vgo Project Developers. See the COPYRIGHT\n// file at the top-level directory of this distribution and at\n// https://github.com/go-vgo/robotgo/blob/master/LICENSE\n//\n// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or\n// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license\n// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your\n// option. This file may not be copied, modified, or distributed\n// except according to those terms.\n\n#include \"../base/types.h\"\n#include \"../base/rgb.h\"\n#include \"screen_c.h\"\n\nMMSizeInt32 get_screen_size()\n{\n\t// Get display size.\n\tMMSizeInt32 displaySize = getMainDisplaySize();\n\treturn displaySize;\n}\n\nchar *set_XDisplay_name(char *name)\n{\n#if defined(USE_X11)\n\tsetXDisplay(name);\n\treturn \"success\";\n#else\n\treturn \"SetXDisplayName is only supported on Linux\";\n#endif\n}\n\nchar *get_XDisplay_name()\n{\n#if defined(USE_X11)\n\tconst char *display = getXDisplay();\n\tchar *sd = (char *)calloc(100, sizeof(char *));\n\n\tif (sd)\n\t{\n\t\tstrcpy(sd, display);\n\t}\n\treturn sd;\n#else\n\treturn \"GetXDisplayName is only supported on Linux\";\n#endif\n}\n"
  },
  {
    "path": "pkg/internal/robotgo/screen/screen.h",
    "content": "#pragma once\n#ifndef SCREEN_H\n#define SCREEN_H\n\n#include \"../base/types.h\"\n\n#if defined(_MSC_VER)\n#include \"../base/ms_stdbool.h\"\n#else\n#include <stdbool.h>\n#endif\n\n#ifdef __cplusplus\nextern \"C\"\n{\n#endif\n\n\t/* Returns the size of the main display. */\n\tMMSizeInt32 getMainDisplaySize(void);\n\n\t/* Convenience function that returns whether the given point is in the bounds\n * of the main screen. */\n\tbool pointVisibleOnMainDisplay(MMPointInt32 point);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* SCREEN_H */\n"
  },
  {
    "path": "pkg/internal/robotgo/screen/screen_c.h",
    "content": "#include \"screen.h\"\n\n#if defined(IS_MACOSX)\n#include <ApplicationServices/ApplicationServices.h>\n#elif defined(USE_X11)\n#include <X11/Xlib.h>\n#include \"../base/xdisplay_c.h\"\n#endif\n\nMMSizeInt32 getMainDisplaySize(void)\n{\n#if defined(IS_MACOSX)\n\tCGDirectDisplayID displayID = CGMainDisplayID();\n\treturn MMSizeInt32Make((int32_t)CGDisplayPixelsWide(displayID),\n\t\t\t\t\t\t   (int32_t)CGDisplayPixelsHigh(displayID));\n#elif defined(USE_X11)\n\tDisplay *display = XGetMainDisplay();\n\tconst int screen = DefaultScreen(display);\n\n\treturn MMSizeInt32Make((int32_t)DisplayWidth(display, screen),\n\t\t\t\t\t\t   (int32_t)DisplayHeight(display, screen));\n#elif defined(IS_WINDOWS)\n\tif (GetSystemMetrics(SM_CMONITORS) == 1)\n\t{\n\t\treturn MMSizeInt32Make((int32_t)GetSystemMetrics(SM_CXSCREEN),\n\t\t\t\t\t\t\t   (int32_t)GetSystemMetrics(SM_CYSCREEN));\n\t}\n\telse\n\t{\n\t\treturn MMSizeInt32Make((int32_t)GetSystemMetrics(SM_CXVIRTUALSCREEN),\n\t\t\t\t\t\t\t   (int32_t)GetSystemMetrics(SM_CYVIRTUALSCREEN));\n\t}\n#endif\n}\n\nbool pointVisibleOnMainDisplay(MMPointInt32 point)\n{\n\tMMSizeInt32 displaySize = getMainDisplaySize();\n\treturn point.x < displaySize.w && point.y < displaySize.h;\n}\n"
  },
  {
    "path": "pkg/internal/robotgo/window/arr.h",
    "content": "struct Arr\n{\n    int len;\n    int cnu;\n    char **pName;\n    int *pId;\n};\n"
  },
  {
    "path": "pkg/internal/robotgo/window/goWindow.h",
    "content": "// Copyright 2016 The go-vgo Project Developers. See the COPYRIGHT\n// file at the top-level directory of this distribution and at\n// https://github.com/go-vgo/robotgo/blob/master/LICENSE\n//\n// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or\n// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license\n// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your\n// option. This file may not be copied, modified, or distributed\n// except according to those terms.\n\n#include \"window.h\"\n#include \"win_sys.h\"\n\nintptr scale_x()\n{\n\treturn scaleX();\n}\n\nintptr scale_y()\n{\n\treturn scaleY();\n}\n\nbool is_valid()\n{\n\tbool abool = IsValid();\n\treturn abool;\n}\n\nvoid min_window(uintptr pid, bool state, uintptr isHwnd)\n{\n#if defined(IS_MACOSX)\n\t// return 0;\n\tAXUIElementRef axID = AXUIElementCreateApplication(pid);\n\n\tAXUIElementSetAttributeValue(axID, kAXMinimizedAttribute,\n\t\t\t\t\t\t\t\t state ? kCFBooleanTrue : kCFBooleanFalse);\n#elif defined(USE_X11)\n\t// Ignore X errors\n\tXDismissErrors();\n\t// SetState((Window)pid, STATE_MINIMIZE, state);\n#elif defined(IS_WINDOWS)\n\tif (isHwnd == 0)\n\t{\n\t\tHWND hwnd = GetHwndByPId(pid);\n\t\twin_min(hwnd, state);\n\t}\n\telse\n\t{\n\t\twin_min((HWND)pid, state);\n\t}\n#endif\n}\n\nvoid max_window(uintptr pid, bool state, uintptr isHwnd)\n{\n#if defined(IS_MACOSX)\n\t// return 0;\n#elif defined(USE_X11)\n\tXDismissErrors();\n\t// SetState((Window)pid, STATE_MINIMIZE, false);\n\t// SetState((Window)pid, STATE_MAXIMIZE, state);\n#elif defined(IS_WINDOWS)\n\tif (isHwnd == 0)\n\t{\n\t\tHWND hwnd = GetHwndByPId(pid);\n\t\twin_max(hwnd, state);\n\t}\n\telse\n\t{\n\t\twin_max((HWND)pid, state);\n\t}\n#endif\n}\n\nvoid close_window(uintptr pid, uintptr isHwnd)\n{\n\tclose_window_by_PId(pid, isHwnd);\n}\n\nbool set_handle(uintptr handle)\n{\n\tbool hwnd = setHandle(handle);\n\treturn hwnd;\n}\n\nuintptr get_handle()\n{\n\tMData mData = GetActive();\n\n#if defined(IS_MACOSX)\n\treturn (uintptr)mData.CgID;\n#elif defined(USE_X11)\n\treturn (uintptr)mData.XWin;\n#elif defined(IS_WINDOWS)\n\treturn (uintptr)mData.HWnd;\n#endif\n}\n\nuintptr bget_handle()\n{\n\tuintptr hwnd = getHandle();\n\treturn hwnd;\n}\n\nvoid set_active(const MData win)\n{\n\tSetActive(win);\n}\n\nvoid active_PID(uintptr pid, uintptr isHwnd)\n{\n\tMData win = set_handle_pid(pid, isHwnd);\n\tSetActive(win);\n}\n\nMData get_active()\n{\n\tMData mdata = GetActive();\n\treturn mdata;\n}\n\nchar *get_title(uintptr pid, uintptr isHwnd)\n{\n\tchar *title = get_title_by_pid(pid, isHwnd);\n\t// printf(\"title::::%s\\n\", title );\n\treturn title;\n}\n\nint32 get_PID(void)\n{\n\tint pid = WGetPID();\n\treturn pid;\n}\n"
  },
  {
    "path": "pkg/internal/robotgo/window/process.h",
    "content": "// Copyright 2016 The go-vgo Project Developers. See the COPYRIGHT\n// file at the top-level directory of this distribution and at\n// https://github.com/go-vgo/robotgo/blob/master/LICENSE\n//\n// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or\n// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license\n// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your\n// option. This file may not be copied, modified, or distributed\n// except according to those terms.\n\n#include <string.h>\n#if defined(IS_MACOSX)\n#if defined(__x86_64__)\n#define RobotGo_64\n#else\n#define RobotGo_32\n#endif\n// #include <sys/utsname.h>\n// #include <mach/task.h>\n// #include <mach/mach_vm.h>\n\n// Apple process API\n#include <libproc.h>\n#include <dlfcn.h>\n#include <ApplicationServices/ApplicationServices.h>\n\n#ifdef MAC_OS_X_VERSION_10_11\n#define kAXValueCGPointType kAXValueTypeCGPoint\n#define kAXValueCGSizeType kAXValueTypeCGSize\n#endif\n\n#ifndef EXC_MASK_GUARD\n#define EXC_MASK_GUARD 0\n#endif\n#elif defined(USE_X11)\n#if defined(__x86_64__)\n#define RobotGo_64\n#else\n#define RobotGo_32\n#endif\n\n#include <X11/Xlib.h>\n#include <X11/Xatom.h>\n\n#ifndef X_HAVE_UTF8_STRING\n#error It appears that X_HAVE_UTF8_STRING is not defined - \\\n\t\t\t   please verify that your version of XLib is supported\n#endif\n#elif defined(IS_WINDOWS)\n#if defined(_WIN64)\n#define RobotGo_64\n#else\n#define RobotGo_32\n#endif\n\n#include <winuser.h>\n#include <tchar.h>\n#endif\n\ntypedef signed char int8;\t\t// Signed  8-Bit integer\ntypedef signed short int16;\t\t// Signed 16-Bit integer\ntypedef signed int int32;\t\t// Signed 32-Bit integer\ntypedef signed long long int64; // Signed 64-Bit integer\n\ntypedef unsigned char uint8;\t   // Unsigned  8-Bit integer\ntypedef unsigned short uint16;\t // Unsigned 16-Bit integer\ntypedef unsigned int uint32;\t   // Unsigned 32-Bit integer\ntypedef unsigned long long uint64; // Unsigned 64-Bit integer\n\ntypedef float real32;  // 32-Bit float value\ntypedef double real64; // 64-Bit float value\n\n#ifdef RobotGo_64\n\ntypedef int64 intptr;   //   Signed pointer integer\ntypedef uint64 uintptr; // Unsigned pointer integer\n\n#else\n\ntypedef int32 intptr;   //   Signed pointer integer\ntypedef uint32 uintptr; // Unsigned pointer integer\n\n#endif\n//\n\nstruct _PData\n{\n\tint32 ProcID; // The process ID\n\n\tchar *Name; // Name of process\n\tchar *Path; // Path of process\n\n\tbool Is64Bit; // Process is 64-Bit\n\n#if defined(IS_MACOSX)\n\n\ttask_t Handle; // The mach task\n\n#elif defined(USE_X11)\n\n\tuint32 Handle; // Unused handle\n\n#elif defined(IS_WINDOWS)\n\n\tHANDLE Handle; // Process handle\n\n#endif\n};\n\nstruct _PPData\n{\n\tint32 ProcID; // The process ID\n\n\tchar **Name; // Name of process\n\tchar **Path; // Path of process\n\n\tbool Is64Bit; // Process is 64-Bit\n\n#if defined(IS_MACOSX)\n\n\ttask_t Handle; // The mach task\n\n#elif defined(USE_X11)\n\n\tuint32 Handle; // Unused handle\n\n#elif defined(IS_WINDOWS)\n\n\tHANDLE Handle; // Process handle\n\n#endif\n};\n\ntypedef struct _PData PData;\n"
  },
  {
    "path": "pkg/internal/robotgo/window/pub.h",
    "content": "// Copyright 2016 The go-vgo Project Developers. See the COPYRIGHT\n// file at the top-level directory of this distribution and at\n// https://github.com/go-vgo/robotgo/blob/master/LICENSE\n//\n// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or\n// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license\n// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your\n// option. This file may not be copied, modified, or distributed\n// except according to those terms.\n\nstruct _MData\n{\n#if defined(IS_MACOSX)\n\tCGWindowID CgID;\t // Handle to a CGWindowID\n\tAXUIElementRef AxID; // Handle to a AXUIElementRef\n#elif defined(USE_X11)\n\tWindow XWin; // Handle to an X11 window\n#elif defined(IS_WINDOWS)\n\tHWND HWnd; // Handle to a window HWND\n\tTCHAR Title[512];\n#endif\n};\n\ntypedef struct _MData MData;\n\nMData mData;\n\nstruct _Bounds\n{\n\tint32 X; // Top left X coordinate\n\tint32 Y; // Top left Y coordinate\n\tint32 W; // Total bounds width\n\tint32 H; // Total bounds height\n};\n\ntypedef struct _Bounds Bounds;\n\n#if defined(IS_MACOSX)\n\nstatic Boolean (*gAXIsProcessTrustedWithOptions)(CFDictionaryRef);\n\nstatic CFStringRef *gkAXTrustedCheckOptionPrompt;\n\nAXError _AXUIElementGetWindow(AXUIElementRef, CGWindowID *out);\n\nstatic AXUIElementRef GetUIElement(CGWindowID win)\n{\n\tintptr pid = 0;\n\t// double_t pid = 0;\n\n\t// Create array storing window\n\tCGWindowID window[1] = {win};\n\tCFArrayRef wlist = CFArrayCreate(NULL,\n\t\t\t\t\t\t\t\t\t (const void **)window, 1, NULL);\n\n\t// Get window info\n\tCFArrayRef info = CGWindowListCreateDescriptionFromArray(wlist);\n\tCFRelease(wlist);\n\n\t// Check whether the resulting array is populated\n\tif (info != NULL && CFArrayGetCount(info) > 0)\n\t{\n\t\t// Retrieve description from info array\n\t\tCFDictionaryRef desc = (CFDictionaryRef)CFArrayGetValueAtIndex(info, 0);\n\n\t\t// Get window PID\n\t\tCFNumberRef data = (CFNumberRef)\n\t\t\tCFDictionaryGetValue(desc, kCGWindowOwnerPID);\n\n\t\tif (data != NULL)\n\t\t{\n\t\t\tCFNumberGetValue(data, kCFNumberIntType, &pid);\n\t\t}\n\n\t\t// Return result\n\t\tCFRelease(info);\n\t}\n\n\t// Check if PID was retrieved\n\tif (pid <= 0)\n\t{\n\t\treturn NULL;\n\t}\n\n\t// Create an accessibility object using retrieved PID\n\tAXUIElementRef application = AXUIElementCreateApplication(pid);\n\n\tif (application == 0)\n\t{\n\t\treturn NULL;\n\t}\n\n\tCFArrayRef windows = NULL;\n\t// Get all windows associated with the app\n\tAXUIElementCopyAttributeValues(application,\n\t\t\t\t\t\t\t\t   kAXWindowsAttribute, 0, 1024, &windows);\n\n\t// Reference to resulting value\n\tAXUIElementRef result = NULL;\n\n\tif (windows != NULL)\n\t{\n\t\tint count = CFArrayGetCount(windows);\n\t\t// Loop all windows in the process\n\t\tfor (CFIndex i = 0; i < count; ++i)\n\t\t{\n\t\t\t// Get the element at the index\n\t\t\tAXUIElementRef element = (AXUIElementRef)\n\t\t\t\tCFArrayGetValueAtIndex(windows, i);\n\n\t\t\tCGWindowID temp = 0;\n\t\t\t// Use undocumented API to get WindowID\n\t\t\t_AXUIElementGetWindow(element, &temp);\n\n\t\t\t// Check results\n\t\t\tif (temp == win)\n\t\t\t{\n\t\t\t\t// Retain element\n\t\t\t\tCFRetain(element);\n\t\t\t\tresult = element;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tCFRelease(windows);\n\t}\n\n\tCFRelease(application);\n\treturn result;\n}\n#elif defined(USE_X11)\n\n// Error Handling\n\ntypedef int (*XErrorHandler)(Display *, XErrorEvent *);\n\nstatic int XHandleError(Display *dp, XErrorEvent *e) { return 0; }\n\nXErrorHandler mOld;\n\nvoid XDismissErrors(void)\n{\n\tDisplay *rDisplay = XOpenDisplay(NULL);\n\t// Save old handler and dismiss errors\n\tmOld = XSetErrorHandler(XHandleError);\n\t// Flush output buffer\n\tXSync(rDisplay, False);\n\n\t// Reinstate old handler\n\tXSetErrorHandler(mOld);\n}\n\n// Definitions\n\nstruct Hints\n{\n\tunsigned long Flags;\n\tunsigned long Funcs;\n\tunsigned long Decorations;\n\tsigned long Mode;\n\tunsigned long Stat;\n};\n\nstatic Atom WM_STATE = None;\nstatic Atom WM_ABOVE = None;\nstatic Atom WM_HIDDEN = None;\nstatic Atom WM_HMAX = None;\nstatic Atom WM_VMAX = None;\n\nstatic Atom WM_DESKTOP = None;\nstatic Atom WM_CURDESK = None;\n\nstatic Atom WM_NAME = None;\nstatic Atom WM_UTF8 = None;\nstatic Atom WM_PID = None;\nstatic Atom WM_ACTIVE = None;\nstatic Atom WM_HINTS = None;\nstatic Atom WM_EXTENTS = None;\n\n////////////////////////////////////////////////////////////////////////////////\n\nstatic void LoadAtoms(void)\n{\n\tDisplay *rDisplay = XOpenDisplay(NULL);\n\tWM_STATE = XInternAtom(rDisplay, \"_NET_WM_STATE\", True);\n\tWM_ABOVE = XInternAtom(rDisplay, \"_NET_WM_STATE_ABOVE\", True);\n\tWM_HIDDEN = XInternAtom(rDisplay, \"_NET_WM_STATE_HIDDEN\", True);\n\tWM_HMAX = XInternAtom(rDisplay, \"_NET_WM_STATE_MAXIMIZED_HORZ\", True);\n\tWM_VMAX = XInternAtom(rDisplay, \"_NET_WM_STATE_MAXIMIZED_VERT\", True);\n\n\tWM_DESKTOP = XInternAtom(rDisplay, \"_NET_WM_DESKTOP\", True);\n\tWM_CURDESK = XInternAtom(rDisplay, \"_NET_CURRENT_DESKTOP\", True);\n\n\tWM_NAME = XInternAtom(rDisplay, \"_NET_WM_NAME\", True);\n\tWM_UTF8 = XInternAtom(rDisplay, \"UTF8_STRING\", True);\n\tWM_PID = XInternAtom(rDisplay, \"_NET_WM_PID\", True);\n\tWM_ACTIVE = XInternAtom(rDisplay, \"_NET_ACTIVE_WINDOW\", True);\n\tWM_HINTS = XInternAtom(rDisplay, \"_MOTIF_WM_HINTS\", True);\n\tWM_EXTENTS = XInternAtom(rDisplay, \"_NET_FRAME_EXTENTS\", True);\n}\n\n// Functions\nstatic void *GetWindowProperty(MData win, Atom atom, uint32 *items)\n{\n\t// Property variables\n\tAtom type;\n\tint format;\n\tunsigned long nItems;\n\tunsigned long bAfter;\n\tunsigned char *result = NULL;\n\n\tDisplay *rDisplay = XOpenDisplay(NULL);\n\t// Check the atom\n\tif (atom != None)\n\t{\n\t\t// Retrieve and validate the specified property\n\t\tif (!XGetWindowProperty(rDisplay, win.XWin, atom, 0,\n\t\t\t\t\t\t\t\tBUFSIZ, False, AnyPropertyType, &type, &format,\n\t\t\t\t\t\t\t\t&nItems, &bAfter, &result) &&\n\t\t\tresult && nItems)\n\t\t{\n\n\t\t\t// Copy items result\n\t\t\tif (items != NULL)\n\t\t\t{\n\t\t\t\t*items = (uint32)nItems;\n\t\t\t}\n\n\t\t\treturn result;\n\t\t}\n\t}\n\n\t// Reset the items result if valid\n\tif (items != NULL)\n\t{\n\t\t*items = 0;\n\t}\n\n\t// Free the result if it got allocated\n\tif (result != NULL)\n\t{\n\t\tXFree(result);\n\t}\n\n\treturn NULL;\n}\n\n//////\n\n#define STATE_TOPMOST 0\n#define STATE_MINIMIZE 1\n#define STATE_MAXIMIZE 2\n\n//////\nstatic void SetDesktopForWindow(MData win)\n{\n\tDisplay *rDisplay = XOpenDisplay(NULL);\n\t// Validate every atom that we want to use\n\tif (WM_DESKTOP != None && WM_CURDESK != None)\n\t{\n\t\t// Get desktop property\n\t\tlong *desktop = (long *)GetWindowProperty(win, WM_DESKTOP, NULL);\n\n\t\t// Check result value\n\t\tif (desktop != NULL)\n\t\t{\n\t\t\t// Retrieve the screen number\n\t\t\tXWindowAttributes attr = {0};\n\t\t\tXGetWindowAttributes(rDisplay, win.XWin, &attr);\n\t\t\tint s = XScreenNumberOfScreen(attr.screen);\n\t\t\tWindow root = XRootWindow(rDisplay, s);\n\n\t\t\t// Prepare an event\n\t\t\tXClientMessageEvent e = {0};\n\t\t\te.window = root;\n\t\t\te.format = 32;\n\t\t\te.message_type = WM_CURDESK;\n\t\t\te.display = rDisplay;\n\t\t\te.type = ClientMessage;\n\t\t\te.data.l[0] = *desktop;\n\t\t\te.data.l[1] = CurrentTime;\n\n\t\t\t// Send the message\n\t\t\tXSendEvent(rDisplay,\n\t\t\t\t\t   root, False, SubstructureNotifyMask | SubstructureRedirectMask, (XEvent *)&e);\n\n\t\t\tXFree(desktop);\n\t\t}\n\t}\n}\n\nstatic Bounds GetFrame(MData win)\n{\n\tBounds frame;\n\t// Retrieve frame bounds\n\tif (WM_EXTENTS != None)\n\t{\n\t\tlong *result;\n\t\tuint32 nItems = 0;\n\t\t// Get the window extents property\n\t\tresult = (long *)GetWindowProperty(win, WM_EXTENTS, &nItems);\n\n\t\t// Verify the results\n\t\tif (result != NULL)\n\t\t{\n\t\t\tif (nItems == 4)\n\t\t\t{\n\t\t\t\tframe.X = (int32)result[0];\n\t\t\t\tframe.Y = (int32)result[2];\n\t\t\t\tframe.W = (int32)result[0] + (int32)result[1];\n\t\t\t\tframe.H = (int32)result[2] + (int32)result[3];\n\t\t\t}\n\n\t\t\tXFree(result);\n\t\t}\n\t}\n\n\treturn frame;\n}\n\n#elif defined(IS_WINDOWS)\n//\n#endif\n"
  },
  {
    "path": "pkg/internal/robotgo/window/win32.h",
    "content": "// Copyright 2016 The go-vgo Project Developers. See the COPYRIGHT\n// file at the top-level directory of this distribution and at\n// https://github.com/go-vgo/robotgo/blob/master/LICENSE\n//\n// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or\n// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license\n// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your\n// option. This file may not be copied, modified, or distributed\n// except according to those terms.\n\n#if defined(IS_WINDOWS)\ntypedef struct\n{\n\tHWND hWnd;\n\tDWORD dwPid;\n} WNDINFO;\n\nBOOL CALLBACK EnumWindowsProc(HWND hWnd, LPARAM lParam)\n{\n\tWNDINFO *pInfo = (WNDINFO *)lParam;\n\tDWORD dwProcessId = 0;\n\tGetWindowThreadProcessId(hWnd, &dwProcessId);\n\n\tif (dwProcessId == pInfo->dwPid)\n\t{\n\t\tpInfo->hWnd = hWnd;\n\t\treturn FALSE;\n\t}\n\treturn TRUE;\n}\n\nHWND GetHwndByPId(DWORD dwProcessId)\n{\n\tWNDINFO info = {0};\n\tinfo.hWnd = NULL;\n\tinfo.dwPid = dwProcessId;\n\tEnumWindows(EnumWindowsProc, (LPARAM)&info);\n\t// printf(\"%d\\n\", info.hWnd);\n\treturn info.hWnd;\n}\n\n// window\nvoid win_min(HWND hwnd, bool state)\n{\n\tif (state)\n\t{\n\t\tShowWindow(hwnd, SW_MINIMIZE);\n\t}\n\telse\n\t{\n\t\tShowWindow(hwnd, SW_RESTORE);\n\t}\n}\n\nvoid win_max(HWND hwnd, bool state)\n{\n\tif (state)\n\t{\n\t\tShowWindow(hwnd, SW_MAXIMIZE);\n\t}\n\telse\n\t{\n\t\tShowWindow(hwnd, SW_RESTORE);\n\t}\n}\n#endif\n"
  },
  {
    "path": "pkg/internal/robotgo/window/win_sys.h",
    "content": "// Copyright 2016 The go-vgo Project Developers. See the COPYRIGHT\n// file at the top-level directory of this distribution and at\n// https://github.com/go-vgo/robotgo/blob/master/LICENSE\n//\n// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or\n// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license\n// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your\n// option. This file may not be copied, modified, or distributed\n// except according to those terms.\n\nBounds get_client(uintptr pid, uintptr isHwnd);\n\nintptr scaleX()\n{\n#if defined(IS_MACOSX)\n\treturn 0;\n#elif defined(USE_X11)\n\treturn 0;\n#elif defined(IS_WINDOWS)\n\t// Get desktop dc\n\tHDC desktopDc = GetDC(NULL);\n\t// Get native resolution\n\tintptr horizontalDPI = GetDeviceCaps(desktopDc, LOGPIXELSX);\n\t// intptr verticalDPI = GetDeviceCaps(desktopDc, LOGPIXELSY);\n\treturn horizontalDPI;\n#endif\n}\n\nintptr scaleY()\n{\n#if defined(IS_MACOSX)\n\treturn 0;\n#elif defined(USE_X11)\n\treturn 0;\n#elif defined(IS_WINDOWS)\n\t// Get desktop dc\n\tHDC desktopDc = GetDC(NULL);\n\t// Get native resolution\n\tintptr verticalDPI = GetDeviceCaps(desktopDc, LOGPIXELSY);\n\treturn verticalDPI;\n#endif\n}\n\nBounds get_bounds(uintptr pid, uintptr isHwnd)\n{\n\t// Check if the window is valid\n\tBounds bounds;\n\tif (!IsValid())\n\t{\n\t\treturn bounds;\n\t}\n\n#if defined(IS_MACOSX)\n\n\t// Bounds bounds;\n\tAXValueRef axp = NULL;\n\tAXValueRef axs = NULL;\n\tAXUIElementRef AxID = AXUIElementCreateApplication(pid);\n\n\t// Determine the current point of the window\n\tif (AXUIElementCopyAttributeValue(\n\t\t\tAxID, kAXPositionAttribute, (CFTypeRef *)&axp) != kAXErrorSuccess ||\n\t\taxp == NULL)\n\t{\n\t\tgoto exit;\n\t}\n\n\t// Determine the current size of the window\n\tif (AXUIElementCopyAttributeValue(\n\t\t\tAxID, kAXSizeAttribute, (CFTypeRef *)&axs) != kAXErrorSuccess ||\n\t\taxs == NULL)\n\t{\n\t\tgoto exit;\n\t}\n\n\tCGPoint p;\n\tCGSize s;\n\t// Attempt to convert both values into atomic types\n\tif (AXValueGetValue(axp, kAXValueCGPointType, &p) &&\n\t\tAXValueGetValue(axs, kAXValueCGSizeType, &s))\n\t{\n\t\tbounds.X = p.x;\n\t\tbounds.Y = p.y;\n\t\tbounds.W = s.width;\n\t\tbounds.H = s.height;\n\t}\n\n\t// return bounds;\nexit:\n\tif (axp != NULL)\n\t{\n\t\tCFRelease(axp);\n\t}\n\tif (axs != NULL)\n\t{\n\t\tCFRelease(axs);\n\t}\n\n\treturn bounds;\n\n#elif defined(USE_X11)\n\n\t// Ignore X errors\n\tXDismissErrors();\n\tMData win;\n\twin.XWin = (Window)pid;\n\n\tBounds client = get_client(pid, isHwnd);\n\tBounds frame = GetFrame(win);\n\n\tbounds.X = client.X - frame.X;\n\tbounds.Y = client.Y - frame.Y;\n\tbounds.W = client.W + frame.W;\n\tbounds.H = client.H + frame.H;\n\n\treturn bounds;\n\n#elif defined(IS_WINDOWS)\n\tHWND hwnd;\n\tif (isHwnd == 0)\n\t{\n\t\thwnd = GetHwndByPId(pid);\n\t}\n\telse\n\t{\n\t\thwnd = (HWND)pid;\n\t}\n\n\tRECT rect = {0};\n\tGetWindowRect(hwnd, &rect);\n\n\tbounds.X = rect.left;\n\tbounds.Y = rect.top;\n\tbounds.W = rect.right - rect.left;\n\tbounds.H = rect.bottom - rect.top;\n\n\treturn bounds;\n\n#endif\n}\n\nBounds get_client(uintptr pid, uintptr isHwnd)\n{\n\t// Check if the window is valid\n\tBounds bounds;\n\tif (!IsValid())\n\t{\n\t\treturn bounds;\n\t}\n\n#if defined(IS_MACOSX)\n\n\treturn get_bounds(pid, isHwnd);\n\n#elif defined(USE_X11)\n\n\tDisplay *rDisplay = XOpenDisplay(NULL);\n\n\t// Ignore X errors\n\tXDismissErrors();\n\tMData win;\n\twin.XWin = (Window)pid;\n\n\t// Property variables\n\tWindow root, parent;\n\tWindow *children;\n\tunsigned int count;\n\tint32 x = 0, y = 0;\n\n\t// Check if the window is the root\n\tXQueryTree(rDisplay, win.XWin,\n\t\t\t   &root, &parent, &children, &count);\n\tif (children)\n\t{\n\t\tXFree(children);\n\t}\n\n\t// Retrieve window attributes\n\tXWindowAttributes attr = {0};\n\tXGetWindowAttributes(rDisplay, win.XWin, &attr);\n\n\t// Coordinates must be translated\n\tif (parent != attr.root)\n\t{\n\t\tXTranslateCoordinates(rDisplay, win.XWin, attr.root, attr.x,\n\t\t\t\t\t\t\t  attr.y, &x, &y, &parent);\n\t}\n\t// Coordinates can be left alone\n\telse\n\t{\n\t\tx = attr.x;\n\t\ty = attr.y;\n\t}\n\n\t// Return resulting window bounds\n\tbounds.X = x;\n\tbounds.Y = y;\n\tbounds.W = attr.width;\n\tbounds.H = attr.height;\n\treturn bounds;\n\n#elif defined(IS_WINDOWS)\n\tHWND hwnd;\n\tif (isHwnd == 0)\n\t{\n\t\thwnd = GetHwndByPId(pid);\n\t}\n\telse\n\t{\n\t\thwnd = (HWND)pid;\n\t}\n\n\tRECT rect = {0};\n\tGetClientRect(hwnd, &rect);\n\n\tPOINT point;\n\tpoint.x = rect.left;\n\tpoint.y = rect.top;\n\n\t// Convert the client point to screen\n\tClientToScreen(hwnd, &point);\n\n\tbounds.X = point.x;\n\tbounds.Y = point.y;\n\tbounds.W = rect.right - rect.left;\n\tbounds.H = rect.bottom - rect.top;\n\n\treturn bounds;\n\n#endif\n}\n"
  },
  {
    "path": "pkg/internal/robotgo/window/window.h",
    "content": "// Copyright 2016 The go-vgo Project Developers. See the COPYRIGHT\n// file at the top-level directory of this distribution and at\n// https://github.com/go-vgo/robotgo/blob/master/LICENSE\n//\n// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or\n// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license\n// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your\n// option. This file may not be copied, modified, or distributed\n// except according to those terms.\n#if defined(_MSC_VER)\n#include \"ms_stdbool.h\"\n#else\n#include <stdbool.h>\n#endif\n#include <stdio.h>\n#include \"process.h\"\n#include \"pub.h\"\n#include \"win32.h\"\n\nbool setHandle(uintptr handle);\nbool IsValid();\nbool IsAxEnabled(bool options);\nMData GetActive(void);\nvoid initWindow();\nchar *get_title_by_hand(MData m_data);\nvoid close_window_by_Id(MData m_data);\n\nuintptr initHandle = 0;\n\nvoid initWindow(uintptr handle)\n{\n#if defined(IS_MACOSX)\n\n\tmData.CgID = 0;\n\tmData.AxID = 0;\n\n#elif defined(USE_X11)\n\tDisplay *rDisplay = XOpenDisplay(NULL);\n\t// If atoms loaded\n\tif (WM_PID == None)\n\t{\n\t\t// Load all necessary atom properties\n\t\tif (rDisplay != NULL)\n\t\t{\n\t\t\tLoadAtoms();\n\t\t}\n\t}\n\n\tmData.XWin = 0;\n\n#elif defined(IS_WINDOWS)\n\tmData.HWnd = 0;\n#endif\n\n\tsetHandle(handle);\n}\n\nbool Is64Bit()\n{\n#ifdef RobotGo_64\n\treturn true;\n#endif\n\n\treturn false;\n}\n\nMData set_handle_pid(uintptr pid, uintptr isHwnd)\n{\n\tMData win;\n\n#if defined(IS_MACOSX)\n\t// Handle to a AXUIElementRef\n\twin.AxID = AXUIElementCreateApplication(pid);\n#elif defined(USE_X11)\n\twin.XWin = (Window)pid; // Handle to an X11 window\n#elif defined(IS_WINDOWS)\n\t// win.HWnd = (HWND)pid;\t\t// Handle to a window HWND\n\tif (isHwnd == 0)\n\t{\n\t\twin.HWnd = GetHwndByPId(pid);\n\t}\n\telse\n\t{\n\t\twin.HWnd = (HWND)pid;\n\t}\n#endif\n\n\treturn win;\n}\n\nvoid set_handle_pid_mData(uintptr pid, uintptr isHwnd)\n{\n\tMData win = set_handle_pid(pid, isHwnd);\n\tmData = win;\n}\n\nbool IsValid()\n{\n\tinitWindow(initHandle);\n\tif (!IsAxEnabled(true))\n\t{\n\t\tprintf(\"%s\\n\", \"Window:Accessibility API is disabled!\\n\"\n\t\t\t\t\t   \"Failed to enable access for assistive devices.\");\n\t}\n\tMData actdata = GetActive();\n\n#if defined(IS_MACOSX)\n\n\tmData.CgID = actdata.CgID;\n\tmData.AxID = actdata.AxID;\n\n\tif (mData.CgID == 0 || mData.AxID == 0)\n\t\treturn false;\n\n\tCFTypeRef r = NULL;\n\n\t// Attempt to get the window role\n\tif (AXUIElementCopyAttributeValue(mData.AxID,\n\t\t\t\t\t\t\t\t\t  kAXRoleAttribute, &r) == kAXErrorSuccess &&\n\t\tr)\n\t{\n\t\tCFRelease(r);\n\t\treturn true;\n\t}\n\n\treturn false;\n\n#elif defined(USE_X11)\n\tmData.XWin = actdata.XWin;\n\tif (mData.XWin == 0)\n\t{\n\t\treturn false;\n\t}\n\n\tDisplay *rDisplay = XOpenDisplay(NULL);\n\t// Check for a valid X-Window display\n\tif (rDisplay == NULL)\n\t{\n\t\treturn false;\n\t}\n\n\t// Ignore X errors\n\tXDismissErrors();\n\n\t// Get the window PID property\n\tvoid *result = GetWindowProperty(mData, WM_PID, NULL);\n\tif (result == NULL)\n\t{\n\t\treturn false;\n\t}\n\n\t// Free result and return true\n\tXFree(result);\n\treturn true;\n\n#elif defined(IS_WINDOWS)\n\tmData.HWnd = actdata.HWnd;\n\n\tif (mData.HWnd == 0)\n\t{\n\t\treturn false;\n\t}\n\n\treturn IsWindow(mData.HWnd) != 0;\n\n#endif\n}\n\nbool IsAxEnabled(bool options)\n{\n#if defined(IS_MACOSX)\n\n\t// Statically load all required functions one time\n\tstatic dispatch_once_t once;\n\tdispatch_once(&once,\n\t\t\t\t  ^{\n\t\t\t\t\t// Open the framework\n\t\t\t\t\tvoid *handle = dlopen(\"/System/Library/Frameworks/Application\"\n\t\t\t\t\t\t\t\t\t\t  \"Services.framework/ApplicationServices\",\n\t\t\t\t\t\t\t\t\t\t  RTLD_LAZY);\n\n\t\t\t\t\t// Validate the handle\n\t\t\t\t\tif (handle != NULL)\n\t\t\t\t\t{\n\t\t\t\t\t\t*(void **)(&gAXIsProcessTrustedWithOptions) =\n\t\t\t\t\t\t\tdlsym(handle, \"AXIsProcessTrustedWithOptions\");\n\n\t\t\t\t\t\tgkAXTrustedCheckOptionPrompt = (CFStringRef *)\n\t\t\t\t\t\t\tdlsym(handle, \"kAXTrustedCheckOptionPrompt\");\n\t\t\t\t\t}\n\t\t\t\t  });\n\n\t// Check for new OSX 10.9 function\n\tif (gAXIsProcessTrustedWithOptions)\n\t{\n\t\t// Check whether to show prompt\n\t\tCFBooleanRef displayPrompt = options ? kCFBooleanTrue : kCFBooleanFalse;\n\n\t\t// Convert display prompt value into a dictionary\n\t\tconst void *k[] = {*gkAXTrustedCheckOptionPrompt};\n\t\tconst void *v[] = {displayPrompt};\n\t\tCFDictionaryRef o = CFDictionaryCreate(NULL, k, v, 1, NULL, NULL);\n\n\t\t// Determine whether the process is actually trusted\n\t\tbool result = (*gAXIsProcessTrustedWithOptions)(o);\n\n\t\t// Free memory\n\t\tCFRelease(o);\n\t\treturn result;\n\t}\n\telse\n\t{\n// Ignore deprecated warnings\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Wdeprecated-declarations\"\n\n\t\t// Check whether we have accessibility access\n\t\treturn AXAPIEnabled() || AXIsProcessTrusted();\n#pragma clang diagnostic pop\n\t}\n\n#elif defined(USE_X11)\n\treturn true;\n#elif defined(IS_WINDOWS)\n\treturn true;\n#endif\n}\n\n// int\nbool setHandle(uintptr handle)\n{\n#if defined(IS_MACOSX)\n\t// Release the AX element\n\tif (mData.AxID != NULL)\n\t{\n\t\tCFRelease(mData.AxID);\n\t}\n\n\t// Reset both values\n\tmData.CgID = 0;\n\tmData.AxID = 0;\n\n\tif (handle == 0)\n\t{\n\t\t// return 0;\n\t\treturn true;\n\t}\n\n\t// Retrieve the window element\n\tCGWindowID cgID = (CGWindowID)handle;\n\tAXUIElementRef axID = GetUIElement(cgID);\n\n\tif (axID != NULL)\n\t{\n\t\tmData.CgID = cgID;\n\t\tmData.AxID = axID;\n\t\t// return 0;\n\t\treturn true;\n\t}\n\n\t// return 1;\n\treturn false;\n\n#elif defined(USE_X11)\n\n\tmData.XWin = (Window)handle;\n\n\tif (handle == 0)\n\t{\n\t\treturn true;\n\t}\n\n\tif (IsValid())\n\t{\n\t\treturn true;\n\t}\n\n\tmData.XWin = 0;\n\treturn false;\n#elif defined(IS_WINDOWS)\n\n\tmData.HWnd = (HWND)handle;\n\n\tif (handle == 0)\n\t{\n\t\treturn true;\n\t}\n\n\tif (IsValid())\n\t{\n\t\treturn true;\n\t}\n\n\tmData.HWnd = 0;\n\treturn false;\n\n#endif\n}\n\n// uint32 uintptr\nuintptr getHandle()\n{\n#if defined(IS_MACOSX)\n\treturn (uintptr)mData.CgID;\n#elif defined(USE_X11)\n\treturn (uintptr)mData.XWin;\n#elif defined(IS_WINDOWS)\n\treturn (uintptr)mData.HWnd;\n#endif\n}\n\nbool IsTopMost(void)\n{\n\t// Check the window validity\n\tif (!IsValid())\n\t{\n\t\treturn false;\n\t}\n#if defined(IS_MACOSX)\n\n\treturn false; // WARNING: Unavailable\n\n#elif defined(USE_X11)\n\n\t// Ignore X errors\n\t// XDismissErrors ();\n\t// return GetState (mData.XWin, STATE_TOPMOST);\n\n#elif defined(IS_WINDOWS)\n\n\treturn (GetWindowLongPtr(mData.HWnd, GWL_EXSTYLE) & WS_EX_TOPMOST) != 0;\n\n#endif\n}\n\nbool IsMinimized(void)\n{\n\t// Check the window validity\n\tif (!IsValid())\n\t{\n\t\treturn false;\n\t}\n#if defined(IS_MACOSX)\n\n\tCFBooleanRef data = NULL;\n\n\t// Determine whether the window is minimized\n\tif (AXUIElementCopyAttributeValue(mData.AxID,\n\t\t\t\t\t\t\t\t\t  kAXMinimizedAttribute, (CFTypeRef *)&data) == kAXErrorSuccess &&\n\t\tdata != NULL)\n\t{\n\t\t// Convert resulting data into a bool\n\t\tbool result = CFBooleanGetValue(data);\n\t\tCFRelease(data);\n\t\treturn result;\n\t}\n\n\treturn false;\n\n#elif defined(USE_X11)\n\n\t// Ignore X errors\n\t// XDismissErrors();\n\t// return GetState(mData.XWin, STATE_MINIMIZE);\n\n#elif defined(IS_WINDOWS)\n\n\treturn (GetWindowLongPtr(mData.HWnd, GWL_STYLE) & WS_MINIMIZE) != 0;\n\n#endif\n}\n\n//////\n\nbool IsMaximized(void)\n{\n\t// Check the window validity\n\tif (!IsValid())\n\t{\n\t\treturn false;\n\t}\n#if defined(IS_MACOSX)\n\n\treturn false; // WARNING: Unavailable\n\n#elif defined(USE_X11)\n\n\t// Ignore X errors\n\t// XDismissErrors();\n\t// return GetState(mData.XWin, STATE_MAXIMIZE);\n\n#elif defined(IS_WINDOWS)\n\n\treturn (GetWindowLongPtr(mData.HWnd, GWL_STYLE) & WS_MAXIMIZE) != 0;\n\n#endif\n}\n\nvoid SetActive(const MData win)\n{\n\t// Check if the window is valid\n\tif (!IsValid())\n\t{\n\t\treturn;\n\t}\n#if defined(IS_MACOSX)\n\n\t// Attempt to raise the specified window object\n\tif (AXUIElementPerformAction(win.AxID, kAXRaiseAction) != kAXErrorSuccess)\n\t{\n\t\tpid_t pid = 0;\n\t\t// Attempt to retrieve the PID of the window\n\t\tif (AXUIElementGetPid(win.AxID, &pid) != kAXErrorSuccess || !pid)\n\t\t{\n\t\t\treturn;\n\t\t}\n\n// Ignore deprecated warnings\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Wdeprecated-declarations\"\n\n\t\t// NOTE: Until Apple actually removes\n\t\t// these functions, there's no real\n\t\t// reason to switch to the NS* flavor\n\n\t\tProcessSerialNumber psn;\n\t\t// Attempt to retrieve the process psn\n\t\tif (GetProcessForPID(pid, &psn) == 0)\n\t\t{\n\t\t\t// Gracefully activate process\n\t\t\tSetFrontProcessWithOptions(&psn, kSetFrontProcessFrontWindowOnly);\n\t\t}\n\n#pragma clang diagnostic pop\n\t}\n\n#elif defined(USE_X11)\n\n\t// Ignore X errors\n\tXDismissErrors();\n\n\t// Go to the specified window's desktop\n\tSetDesktopForWindow(win);\n\tDisplay *rDisplay = XOpenDisplay(NULL);\n\t// Check the atom value\n\tif (WM_ACTIVE != None)\n\t{\n\t\t// Retrieve the screen number\n\t\tXWindowAttributes attr = {0};\n\t\tXGetWindowAttributes(rDisplay, win.XWin, &attr);\n\t\tint s = XScreenNumberOfScreen(attr.screen);\n\n\t\t// Prepare an event\n\t\tXClientMessageEvent e = {0};\n\t\te.window = win.XWin;\n\t\te.format = 32;\n\t\te.message_type = WM_ACTIVE;\n\t\te.display = rDisplay;\n\t\te.type = ClientMessage;\n\t\te.data.l[0] = 2;\n\t\te.data.l[1] = CurrentTime;\n\n\t\t// Send the message\n\t\tXSendEvent(rDisplay, XRootWindow(rDisplay, s), False,\n\t\t\t\t   SubstructureNotifyMask | SubstructureRedirectMask,\n\t\t\t\t   (XEvent *)&e);\n\t}\n\telse\n\t{\n\t\t// Attempt to raise the specified window\n\t\tXRaiseWindow(rDisplay, win.XWin);\n\n\t\t// Set the specified window's input focus\n\t\tXSetInputFocus(rDisplay, win.XWin,\n\t\t\t\t\t   RevertToParent, CurrentTime);\n\t}\n\n#elif defined(IS_WINDOWS)\n\n\tif (IsMinimized())\n\t{\n\t\tShowWindow(win.HWnd, SW_RESTORE);\n\t}\n\n\tSetForegroundWindow(win.HWnd);\n\n#endif\n}\n\nMData GetActive(void)\n{\n#if defined(IS_MACOSX)\n\n\tMData result;\n// Ignore deprecated warnings\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Wdeprecated-declarations\"\n\n\tProcessSerialNumber psn;\n\tpid_t pid;\n\t// Attempt to retrieve the front process\n\tif (GetFrontProcess(&psn) != 0 ||\n\t\tGetProcessPID(&psn, &pid) != 0)\n\t{\n\t\treturn result;\n\t}\n\n#pragma clang diagnostic pop\n\n\t// Create accessibility object using focused PID\n\tAXUIElementRef focused = AXUIElementCreateApplication(pid);\n\tif (focused == NULL)\n\t{\n\t\treturn result;\n\t} // Verify\n\n\tAXUIElementRef element;\n\t// Retrieve the currently focused window\n\tif (AXUIElementCopyAttributeValue(focused,\n\t\t\t\t\t\t\t\t\t  kAXFocusedWindowAttribute, (CFTypeRef *)&element) == kAXErrorSuccess &&\n\t\telement)\n\t{\n\n\t\tCGWindowID win = 0;\n\t\t// Use undocumented API to get WID\n\t\tif (_AXUIElementGetWindow(element, &win) == kAXErrorSuccess && win)\n\t\t{\n\t\t\t// Manually set internals\n\t\t\tresult.CgID = win;\n\t\t\tresult.AxID = element;\n\t\t}\n\t\t// Something went wrong\n\t\telse\n\t\t{\n\t\t\tCFRelease(element);\n\t\t}\n\t}\n\n\tCFRelease(focused);\n\n\treturn result;\n\n#elif defined(USE_X11)\n\n\tMData result;\n\tDisplay *rDisplay = XOpenDisplay(NULL);\n\t// Check X-Window display\n\tif (WM_ACTIVE == None || rDisplay == NULL)\n\t{\n\t\treturn result;\n\t}\n\n\t// Ignore X errors\n\tXDismissErrors();\n\n\t// Get the current active window\n\tresult.XWin = XDefaultRootWindow(rDisplay);\n\tvoid *active = GetWindowProperty(result, WM_ACTIVE, NULL);\n\n\t// Check result value\n\tif (active != NULL)\n\t{\n\t\t// Extract window from the result\n\t\tlong window = *((long *)active);\n\t\tXFree(active);\n\n\t\tif (window != 0)\n\t\t{\n\t\t\t// Set and return the foreground window\n\t\t\tresult.XWin = (Window)window;\n\t\t\treturn result;\n\t\t}\n\t}\n\n\t// Use input focus instead\n\tWindow window = None;\n\tint revert = RevertToNone;\n\tXGetInputFocus(rDisplay, &window, &revert);\n\n\t// Return foreground window\n\tresult.XWin = window;\n\treturn result;\n\n#elif defined(IS_WINDOWS)\n\n\t// Attempt to get the foreground window multiple times in case\n\tMData result;\n\n\tuint8 times = 0;\n\twhile (++times < 20)\n\t{\n\t\tHWND handle;\n\t\thandle = GetForegroundWindow();\n\t\tif (handle != NULL)\n\t\t{\n\t\t\t// mData.HWnd = (uintptr) handle;\n\t\t\tresult.HWnd = (HWND)handle;\n\t\t\treturn result;\n\t\t}\n\t\tSleep(20);\n\t}\n\n\treturn result;\n\n#endif\n}\n\nvoid SetTopMost(bool state)\n{\n\t// Check window validity\n\tif (!IsValid())\n\t{\n\t\treturn;\n\t}\n#if defined(IS_MACOSX)\n\n\t// WARNING: Unavailable\n\n#elif defined(USE_X11)\n\n\t// Ignore X errors\n\t// XDismissErrors();\n\t// SetState(mData.XWin, STATE_TOPMOST, state);\n\n#elif defined(IS_WINDOWS)\n\n\tSetWindowPos(mData.HWnd,\n\t\t\t\t state ? HWND_TOPMOST : HWND_NOTOPMOST,\n\t\t\t\t 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);\n\n#endif\n}\n\nvoid close_main_window()\n{\n\t// Check if the window is valid\n\tif (!IsValid())\n\t{\n\t\treturn;\n\t}\n\n\tclose_window_by_Id(mData);\n}\n\nvoid close_window_by_PId(uintptr pid, uintptr isHwnd)\n{\n\tMData win = set_handle_pid(pid, isHwnd);\n\tclose_window_by_Id(win);\n}\n\n// CloseWindow\nvoid close_window_by_Id(MData m_data)\n{\n\t// Check window validity\n\tif (!IsValid())\n\t{\n\t\treturn;\n\t}\n#if defined(IS_MACOSX)\n\tAXUIElementRef b = NULL;\n\n\t// Retrieve the close button of this window\n\tif (AXUIElementCopyAttributeValue(m_data.AxID,\n\t\t\t\t\t\t\t\t\t  kAXCloseButtonAttribute, (CFTypeRef *)&b) == kAXErrorSuccess &&\n\t\tb != NULL)\n\t{\n\t\t// Simulate button press on the close button\n\t\tAXUIElementPerformAction(b, kAXPressAction);\n\t\tCFRelease(b);\n\t}\n\n#elif defined(USE_X11)\n\n\tDisplay *rDisplay = XOpenDisplay(NULL);\n\n\t// Ignore X errors\n\tXDismissErrors();\n\n\t// Close the window\n\tXDestroyWindow(rDisplay, m_data.XWin);\n\n#elif defined(IS_WINDOWS)\n\n\tPostMessage(m_data.HWnd, WM_CLOSE, 0, 0);\n#endif\n}\n\nchar *get_main_title()\n{\n\t// Check if the window is valid\n\tif (!IsValid())\n\t{\n\t\treturn \"IsValid failed.\";\n\t}\n\n\treturn get_title_by_hand(mData);\n}\n\nchar *get_title_by_pid(uintptr pid, uintptr isHwnd)\n{\n\tMData win = set_handle_pid(pid, isHwnd);\n\treturn get_title_by_hand(win);\n}\n\nchar *get_title_by_hand(MData m_data)\n{\n\t// Check if the window is valid\n\tif (!IsValid())\n\t{\n\t\treturn \"IsValid failed.\";\n\t}\n\n#if defined(IS_MACOSX)\n\n\tCFStringRef data = NULL;\n\n\t// Determine the current title of the window\n\tif (AXUIElementCopyAttributeValue(m_data.AxID,\n\t\t\t\t\t\t\t\t\t  kAXTitleAttribute, (CFTypeRef *)&data) == kAXErrorSuccess &&\n\t\tdata != NULL)\n\t{\n\t\tchar conv[512];\n\t\t// Convert result to a C-String\n\t\tCFStringGetCString(data, conv, 512, kCFStringEncodingUTF8);\n\t\tCFRelease(data);\n\n\t\tchar *s = (char *)calloc(100, sizeof(char *));\n\t\tif (s)\n\t\t{\n\t\t\tstrcpy(s, conv);\n\t\t}\n\t\t// return (char *)&conv;\n\t\treturn s;\n\t}\n\n\treturn \"\";\n\n#elif defined(USE_X11)\n\n\tvoid *result;\n\t// Ignore X errors\n\tXDismissErrors();\n\n\t// Get window title (UTF-8)\n\tresult = GetWindowProperty(m_data, WM_NAME, NULL);\n\n\t// Check result value\n\tif (result != NULL)\n\t{\n\t\t// Convert result to a string\n\t\tchar *name = (char *)result;\n\t\tXFree(result);\n\n\t\tif (name != NULL)\n\t\t{\n\t\t\treturn name;\n\t\t}\n\t}\n\n\t// Get window title (ASCII)\n\tresult = GetWindowProperty(m_data, XA_WM_NAME, NULL);\n\n\t// Check result value\n\tif (result != NULL)\n\t{\n\t\t// Convert result to a string\n\t\tchar *name = (char *)result;\n\t\tXFree(result);\n\t\treturn name;\n\t}\n\n\treturn \"\";\n\n#elif defined(IS_WINDOWS)\n\n\tif (GetWindowText(m_data.HWnd, m_data.Title, 512) > 0)\n\t{\n\t\tchar *name = m_data.Title;\n\n\t\tchar *str = (char *)calloc(100, sizeof(char *));\n\t\tif (str)\n\t\t{\n\t\t\tstrcpy(str, name);\n\t\t}\n\t\treturn str;\n\t}\n\n\treturn \"\";\n\n#endif\n}\n\nint32 WGetPID(void)\n{\n\t// Check window validity\n\tif (!IsValid())\n\t{\n\t\treturn 0;\n\t}\n\n#if defined(IS_MACOSX)\n\n\tpid_t pid = 0;\n\t// Attempt to retrieve the window pid\n\tif (AXUIElementGetPid(mData.AxID, &pid) == kAXErrorSuccess)\n\t{\n\t\treturn pid;\n\t}\n\n\treturn 0;\n\n#elif defined(USE_X11)\n\n\t// Ignore X errors\n\tXDismissErrors();\n\n\t// Get the window PID\n\tlong *result = (long *)GetWindowProperty(mData, WM_PID, NULL);\n\n\t// Check result and convert it\n\tif (result == NULL)\n\t{\n\t\treturn 0;\n\t}\n\tint32 pid = (int32)*result;\n\tXFree(result);\n\treturn pid;\n\n#elif defined(IS_WINDOWS)\n\n\tDWORD id = 0;\n\tGetWindowThreadProcessId(mData.HWnd, &id);\n\treturn id;\n\n#endif\n}\n"
  },
  {
    "path": "pkg/mock_driver_test.go",
    "content": "// Code generated by MockGen. DO NOT EDIT.\n// Source: github.com/kevinconway/remouseable/pkg (interfaces: Driver)\n\n// Package remouseable is a generated GoMock package.\npackage remouseable\n\nimport (\n\treflect \"reflect\"\n\n\tgomock \"github.com/golang/mock/gomock\"\n)\n\n// MockDriver is a mock of Driver interface.\ntype MockDriver struct {\n\tctrl     *gomock.Controller\n\trecorder *MockDriverMockRecorder\n}\n\n// MockDriverMockRecorder is the mock recorder for MockDriver.\ntype MockDriverMockRecorder struct {\n\tmock *MockDriver\n}\n\n// NewMockDriver creates a new mock instance.\nfunc NewMockDriver(ctrl *gomock.Controller) *MockDriver {\n\tmock := &MockDriver{ctrl: ctrl}\n\tmock.recorder = &MockDriverMockRecorder{mock}\n\treturn mock\n}\n\n// EXPECT returns an object that allows the caller to indicate expected use.\nfunc (m *MockDriver) EXPECT() *MockDriverMockRecorder {\n\treturn m.recorder\n}\n\n// Click mocks base method.\nfunc (m *MockDriver) Click() error {\n\tm.ctrl.T.Helper()\n\tret := m.ctrl.Call(m, \"Click\")\n\tret0, _ := ret[0].(error)\n\treturn ret0\n}\n\n// Click indicates an expected call of Click.\nfunc (mr *MockDriverMockRecorder) Click() *gomock.Call {\n\tmr.mock.ctrl.T.Helper()\n\treturn mr.mock.ctrl.RecordCallWithMethodType(mr.mock, \"Click\", reflect.TypeOf((*MockDriver)(nil).Click))\n}\n\n// DragMouse mocks base method.\nfunc (m *MockDriver) DragMouse(arg0, arg1 int) error {\n\tm.ctrl.T.Helper()\n\tret := m.ctrl.Call(m, \"DragMouse\", arg0, arg1)\n\tret0, _ := ret[0].(error)\n\treturn ret0\n}\n\n// DragMouse indicates an expected call of DragMouse.\nfunc (mr *MockDriverMockRecorder) DragMouse(arg0, arg1 interface{}) *gomock.Call {\n\tmr.mock.ctrl.T.Helper()\n\treturn mr.mock.ctrl.RecordCallWithMethodType(mr.mock, \"DragMouse\", reflect.TypeOf((*MockDriver)(nil).DragMouse), arg0, arg1)\n}\n\n// GetSize mocks base method.\nfunc (m *MockDriver) GetSize() (int, int, error) {\n\tm.ctrl.T.Helper()\n\tret := m.ctrl.Call(m, \"GetSize\")\n\tret0, _ := ret[0].(int)\n\tret1, _ := ret[1].(int)\n\tret2, _ := ret[2].(error)\n\treturn ret0, ret1, ret2\n}\n\n// GetSize indicates an expected call of GetSize.\nfunc (mr *MockDriverMockRecorder) GetSize() *gomock.Call {\n\tmr.mock.ctrl.T.Helper()\n\treturn mr.mock.ctrl.RecordCallWithMethodType(mr.mock, \"GetSize\", reflect.TypeOf((*MockDriver)(nil).GetSize))\n}\n\n// MoveMouse mocks base method.\nfunc (m *MockDriver) MoveMouse(arg0, arg1 int) error {\n\tm.ctrl.T.Helper()\n\tret := m.ctrl.Call(m, \"MoveMouse\", arg0, arg1)\n\tret0, _ := ret[0].(error)\n\treturn ret0\n}\n\n// MoveMouse indicates an expected call of MoveMouse.\nfunc (mr *MockDriverMockRecorder) MoveMouse(arg0, arg1 interface{}) *gomock.Call {\n\tmr.mock.ctrl.T.Helper()\n\treturn mr.mock.ctrl.RecordCallWithMethodType(mr.mock, \"MoveMouse\", reflect.TypeOf((*MockDriver)(nil).MoveMouse), arg0, arg1)\n}\n\n// Unclick mocks base method.\nfunc (m *MockDriver) Unclick() error {\n\tm.ctrl.T.Helper()\n\tret := m.ctrl.Call(m, \"Unclick\")\n\tret0, _ := ret[0].(error)\n\treturn ret0\n}\n\n// Unclick indicates an expected call of Unclick.\nfunc (mr *MockDriverMockRecorder) Unclick() *gomock.Call {\n\tmr.mock.ctrl.T.Helper()\n\treturn mr.mock.ctrl.RecordCallWithMethodType(mr.mock, \"Unclick\", reflect.TypeOf((*MockDriver)(nil).Unclick))\n}\n"
  },
  {
    "path": "pkg/mock_evdeviterator_test.go",
    "content": "// Code generated by MockGen. DO NOT EDIT.\n// Source: github.com/kevinconway/remouseable/pkg (interfaces: EvdevIterator)\n\n// Package remouseable is a generated GoMock package.\npackage remouseable\n\nimport (\n\treflect \"reflect\"\n\n\tgomock \"github.com/golang/mock/gomock\"\n)\n\n// MockEvdevIterator is a mock of EvdevIterator interface\ntype MockEvdevIterator struct {\n\tctrl     *gomock.Controller\n\trecorder *MockEvdevIteratorMockRecorder\n}\n\n// MockEvdevIteratorMockRecorder is the mock recorder for MockEvdevIterator\ntype MockEvdevIteratorMockRecorder struct {\n\tmock *MockEvdevIterator\n}\n\n// NewMockEvdevIterator creates a new mock instance\nfunc NewMockEvdevIterator(ctrl *gomock.Controller) *MockEvdevIterator {\n\tmock := &MockEvdevIterator{ctrl: ctrl}\n\tmock.recorder = &MockEvdevIteratorMockRecorder{mock}\n\treturn mock\n}\n\n// EXPECT returns an object that allows the caller to indicate expected use\nfunc (m *MockEvdevIterator) EXPECT() *MockEvdevIteratorMockRecorder {\n\treturn m.recorder\n}\n\n// Close mocks base method\nfunc (m *MockEvdevIterator) Close() error {\n\tm.ctrl.T.Helper()\n\tret := m.ctrl.Call(m, \"Close\")\n\tret0, _ := ret[0].(error)\n\treturn ret0\n}\n\n// Close indicates an expected call of Close\nfunc (mr *MockEvdevIteratorMockRecorder) Close() *gomock.Call {\n\tmr.mock.ctrl.T.Helper()\n\treturn mr.mock.ctrl.RecordCallWithMethodType(mr.mock, \"Close\", reflect.TypeOf((*MockEvdevIterator)(nil).Close))\n}\n\n// Current mocks base method\nfunc (m *MockEvdevIterator) Current() EvdevEvent {\n\tm.ctrl.T.Helper()\n\tret := m.ctrl.Call(m, \"Current\")\n\tret0, _ := ret[0].(EvdevEvent)\n\treturn ret0\n}\n\n// Current indicates an expected call of Current\nfunc (mr *MockEvdevIteratorMockRecorder) Current() *gomock.Call {\n\tmr.mock.ctrl.T.Helper()\n\treturn mr.mock.ctrl.RecordCallWithMethodType(mr.mock, \"Current\", reflect.TypeOf((*MockEvdevIterator)(nil).Current))\n}\n\n// Next mocks base method\nfunc (m *MockEvdevIterator) Next() bool {\n\tm.ctrl.T.Helper()\n\tret := m.ctrl.Call(m, \"Next\")\n\tret0, _ := ret[0].(bool)\n\treturn ret0\n}\n\n// Next indicates an expected call of Next\nfunc (mr *MockEvdevIteratorMockRecorder) Next() *gomock.Call {\n\tmr.mock.ctrl.T.Helper()\n\treturn mr.mock.ctrl.RecordCallWithMethodType(mr.mock, \"Next\", reflect.TypeOf((*MockEvdevIterator)(nil).Next))\n}\n"
  },
  {
    "path": "pkg/mock_positionscaler_test.go",
    "content": "// Code generated by MockGen. DO NOT EDIT.\n// Source: github.com/kevinconway/remouseable/pkg (interfaces: PositionScaler)\n\n// Package remouseable is a generated GoMock package.\npackage remouseable\n\nimport (\n\treflect \"reflect\"\n\n\tgomock \"github.com/golang/mock/gomock\"\n)\n\n// MockPositionScaler is a mock of PositionScaler interface\ntype MockPositionScaler struct {\n\tctrl     *gomock.Controller\n\trecorder *MockPositionScalerMockRecorder\n}\n\n// MockPositionScalerMockRecorder is the mock recorder for MockPositionScaler\ntype MockPositionScalerMockRecorder struct {\n\tmock *MockPositionScaler\n}\n\n// NewMockPositionScaler creates a new mock instance\nfunc NewMockPositionScaler(ctrl *gomock.Controller) *MockPositionScaler {\n\tmock := &MockPositionScaler{ctrl: ctrl}\n\tmock.recorder = &MockPositionScalerMockRecorder{mock}\n\treturn mock\n}\n\n// EXPECT returns an object that allows the caller to indicate expected use\nfunc (m *MockPositionScaler) EXPECT() *MockPositionScalerMockRecorder {\n\treturn m.recorder\n}\n\n// ScalePosition mocks base method\nfunc (m *MockPositionScaler) ScalePosition(arg0, arg1 int) (int, int) {\n\tm.ctrl.T.Helper()\n\tret := m.ctrl.Call(m, \"ScalePosition\", arg0, arg1)\n\tret0, _ := ret[0].(int)\n\tret1, _ := ret[1].(int)\n\treturn ret0, ret1\n}\n\n// ScalePosition indicates an expected call of ScalePosition\nfunc (mr *MockPositionScalerMockRecorder) ScalePosition(arg0, arg1 interface{}) *gomock.Call {\n\tmr.mock.ctrl.T.Helper()\n\treturn mr.mock.ctrl.RecordCallWithMethodType(mr.mock, \"ScalePosition\", reflect.TypeOf((*MockPositionScaler)(nil).ScalePosition), arg0, arg1)\n}\n"
  },
  {
    "path": "pkg/mock_readcloser_test.go",
    "content": "// Code generated by MockGen. DO NOT EDIT.\n// Source: io (interfaces: ReadCloser)\n\n// Package remouseable is a generated GoMock package.\npackage remouseable\n\nimport (\n\treflect \"reflect\"\n\n\tgomock \"github.com/golang/mock/gomock\"\n)\n\n// MockReadCloser is a mock of ReadCloser interface\ntype MockReadCloser struct {\n\tctrl     *gomock.Controller\n\trecorder *MockReadCloserMockRecorder\n}\n\n// MockReadCloserMockRecorder is the mock recorder for MockReadCloser\ntype MockReadCloserMockRecorder struct {\n\tmock *MockReadCloser\n}\n\n// NewMockReadCloser creates a new mock instance\nfunc NewMockReadCloser(ctrl *gomock.Controller) *MockReadCloser {\n\tmock := &MockReadCloser{ctrl: ctrl}\n\tmock.recorder = &MockReadCloserMockRecorder{mock}\n\treturn mock\n}\n\n// EXPECT returns an object that allows the caller to indicate expected use\nfunc (m *MockReadCloser) EXPECT() *MockReadCloserMockRecorder {\n\treturn m.recorder\n}\n\n// Close mocks base method\nfunc (m *MockReadCloser) Close() error {\n\tm.ctrl.T.Helper()\n\tret := m.ctrl.Call(m, \"Close\")\n\tret0, _ := ret[0].(error)\n\treturn ret0\n}\n\n// Close indicates an expected call of Close\nfunc (mr *MockReadCloserMockRecorder) Close() *gomock.Call {\n\tmr.mock.ctrl.T.Helper()\n\treturn mr.mock.ctrl.RecordCallWithMethodType(mr.mock, \"Close\", reflect.TypeOf((*MockReadCloser)(nil).Close))\n}\n\n// Read mocks base method\nfunc (m *MockReadCloser) Read(arg0 []byte) (int, error) {\n\tm.ctrl.T.Helper()\n\tret := m.ctrl.Call(m, \"Read\", arg0)\n\tret0, _ := ret[0].(int)\n\tret1, _ := ret[1].(error)\n\treturn ret0, ret1\n}\n\n// Read indicates an expected call of Read\nfunc (mr *MockReadCloserMockRecorder) Read(arg0 interface{}) *gomock.Call {\n\tmr.mock.ctrl.T.Helper()\n\treturn mr.mock.ctrl.RecordCallWithMethodType(mr.mock, \"Read\", reflect.TypeOf((*MockReadCloser)(nil).Read), arg0)\n}\n"
  },
  {
    "path": "pkg/mock_statemachine_test.go",
    "content": "// Code generated by MockGen. DO NOT EDIT.\n// Source: github.com/kevinconway/remouseable/pkg (interfaces: StateMachine)\n\n// Package remouseable is a generated GoMock package.\npackage remouseable\n\nimport (\n\treflect \"reflect\"\n\n\tgomock \"github.com/golang/mock/gomock\"\n)\n\n// MockStateMachine is a mock of StateMachine interface\ntype MockStateMachine struct {\n\tctrl     *gomock.Controller\n\trecorder *MockStateMachineMockRecorder\n}\n\n// MockStateMachineMockRecorder is the mock recorder for MockStateMachine\ntype MockStateMachineMockRecorder struct {\n\tmock *MockStateMachine\n}\n\n// NewMockStateMachine creates a new mock instance\nfunc NewMockStateMachine(ctrl *gomock.Controller) *MockStateMachine {\n\tmock := &MockStateMachine{ctrl: ctrl}\n\tmock.recorder = &MockStateMachineMockRecorder{mock}\n\treturn mock\n}\n\n// EXPECT returns an object that allows the caller to indicate expected use\nfunc (m *MockStateMachine) EXPECT() *MockStateMachineMockRecorder {\n\treturn m.recorder\n}\n\n// Close mocks base method\nfunc (m *MockStateMachine) Close() error {\n\tm.ctrl.T.Helper()\n\tret := m.ctrl.Call(m, \"Close\")\n\tret0, _ := ret[0].(error)\n\treturn ret0\n}\n\n// Close indicates an expected call of Close\nfunc (mr *MockStateMachineMockRecorder) Close() *gomock.Call {\n\tmr.mock.ctrl.T.Helper()\n\treturn mr.mock.ctrl.RecordCallWithMethodType(mr.mock, \"Close\", reflect.TypeOf((*MockStateMachine)(nil).Close))\n}\n\n// Current mocks base method\nfunc (m *MockStateMachine) Current() StateChange {\n\tm.ctrl.T.Helper()\n\tret := m.ctrl.Call(m, \"Current\")\n\tret0, _ := ret[0].(StateChange)\n\treturn ret0\n}\n\n// Current indicates an expected call of Current\nfunc (mr *MockStateMachineMockRecorder) Current() *gomock.Call {\n\tmr.mock.ctrl.T.Helper()\n\treturn mr.mock.ctrl.RecordCallWithMethodType(mr.mock, \"Current\", reflect.TypeOf((*MockStateMachine)(nil).Current))\n}\n\n// Next mocks base method\nfunc (m *MockStateMachine) Next() bool {\n\tm.ctrl.T.Helper()\n\tret := m.ctrl.Call(m, \"Next\")\n\tret0, _ := ret[0].(bool)\n\treturn ret0\n}\n\n// Next indicates an expected call of Next\nfunc (mr *MockStateMachineMockRecorder) Next() *gomock.Call {\n\tmr.mock.ctrl.T.Helper()\n\treturn mr.mock.ctrl.RecordCallWithMethodType(mr.mock, \"Next\", reflect.TypeOf((*MockStateMachine)(nil).Next))\n}\n"
  },
  {
    "path": "pkg/positionscaler.go",
    "content": "// This file is part of remouseable.\n//\n// remouseable is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License version 3 as published\n// by the Free Software Foundation.\n//\n// remouseable is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with remouseable.  If not, see <https://www.gnu.org/licenses/>.\n\npackage remouseable\n\nconst (\n\t// DefaultTabletHeight is the standard max height value that can be measured\n\t// on a remarkable tablet. Height is the measure of the maximum x coordinate\n\t// value of the tablet screen. The tablet screen is actually oriented\n\t// horizontally with the origin in the upper left corner when the top of the\n\t// device (power button) is on the right. Note that this magic number value\n\t// is not documented anywhere but was discovered by printing out the X value\n\t// events from evdev and using the stylus to draw a line to the edge of the\n\t// device screen.\n\tDefaultTabletHeight = 15725\n\t// DefaultTabletWidth is the standard max width value that can be measured\n\t// on a remarkable tablet. Width is the measure of the maximum y coordinate\n\t// value of the tablet screen. The tablet screen is actually oriented\n\t// horizontally with the origin in the upper left corner when the top of the\n\t// device (power button) is on the right. Note that this magic number value\n\t// is not documented anywhere but was discovered by printing out the X value\n\t// events from evdev and using the stylus to draw a line to the edge of the\n\t// device screen.\n\tDefaultTabletWidth = 20967\n)\n\n// RightPositionScaler converts points from a right-horizontally positioned\n// tablet to a differently sized screen.\ntype RightPositionScaler struct {\n\tTabletWidth  int\n\tTabletHeight int\n\tScreenWidth  int\n\tScreenHeight int\n}\n\n// ScalePosition resolves based on a hoizontal position of the tablet.\nfunc (s *RightPositionScaler) ScalePosition(x int, y int) (int, int) {\n\t// A horizontal orientation of the tablet with the top on the right is\n\t// actually the natural orientation of the screen on the device. This\n\t// orientation places the origin at the upper left corner which matches the\n\t// origin of the host screen. Because this orientation is the most \"natural\"\n\t// it has the simplest scaling policy of directly translating x and y values\n\t// using the proportional screen size as a scaling factor.\n\tscaleX := float64(s.ScreenWidth) / float64(s.TabletWidth)\n\tscaleY := float64(s.ScreenHeight) / float64(s.TabletHeight)\n\t// Apply the scaling factor to the points.\n\treturn int(scaleX * float64(x)), int(scaleY * float64(y))\n}\n\n// LeftPositionScaler converts points from a left-horizontally positioned\n// tablet to a differently sized screen.\ntype LeftPositionScaler struct {\n\tTabletWidth  int\n\tTabletHeight int\n\tScreenWidth  int\n\tScreenHeight int\n}\n\n// ScalePosition resolves based on a hoizontal position of the tablet.\nfunc (s *LeftPositionScaler) ScalePosition(x int, y int) (int, int) {\n\t// Because the tablet is oriented opposite a typical screen we need\n\t// to adjust the x and y values by translating them. For example, the tablet\n\t// coordinate (0,0) is the bottom right corner of the tablet when oriented\n\t// left. However, the equivalent screen coordinate would be\n\t// (ScreenHeight, ScreenWidth). To resolve this conflice we subtract the\n\t// x and y values of the tablet from the maximum values so that (0,0)\n\t// becomes (max, max) and (max, max) becomes (0, 0).\n\tx, y = s.TabletWidth-x, s.TabletHeight-y\n\tscaleX := float64(s.ScreenWidth) / float64(s.TabletWidth)\n\tscaleY := float64(s.ScreenHeight) / float64(s.TabletHeight)\n\t// Apply the scaling factor to the points.\n\treturn int(scaleX * float64(x)), int(scaleY * float64(y))\n}\n\n// VerticalPositionScaler converts points from a vertically positioned\n// tablet to a differently sized screen.\ntype VerticalPositionScaler struct {\n\tTabletWidth  int\n\tTabletHeight int\n\tScreenWidth  int\n\tScreenHeight int\n}\n\n// ScalePosition resolves based on a vertical position of the tablet.\nfunc (s *VerticalPositionScaler) ScalePosition(x int, y int) (int, int) {\n\t// A vertical position of the tablet is the \"natural\" position of the device\n\t// with the buttons on bottom and power button on top. However, this is not\n\t// the natural orientation of the tablet screen which is actually oriented\n\t// horizontally with buttons on the left and power button on the right.\n\t//\n\t// Because of this, x traversal on the tablet becomes y traversal on the\n\t// screen and vice versa. Additionally, the 90 degree rotation requires that\n\t// we translate coordinate values to account for the different origin\n\t// positions. To translate we subtract the x value from the tablet width\n\t// so that the tablet (0,0) which is the bottom right corner becomes the\n\t// screen (max, 0) which is also the bottom right corner. Likewise the tablet\n\t// (max, 0) value becomes the screen (0,0) value which represents the upper\n\t// left corner. The tablet y values are not adjusted as they are directly equal to\n\t// the corresponding screen x values without additional translation.\n\tx, y = y, s.TabletWidth-x\n\tscaleX := float64(s.ScreenWidth) / float64(s.TabletHeight)\n\tscaleY := float64(s.ScreenHeight) / float64(s.TabletWidth)\n\treturn int(scaleX * float64(x)), int(scaleY * float64(y))\n}\n"
  },
  {
    "path": "pkg/positionscaler_test.go",
    "content": "// This file is part of remouseable.\n//\n// remouseable is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License version 3 as published\n// by the Free Software Foundation.\n//\n// remouseable is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with remouseable.  If not, see <https://www.gnu.org/licenses/>.\n\npackage remouseable\n\nimport (\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc TestRightPositionScaler_ScalePosition(t *testing.T) {\n\ttype fields struct {\n\t\tTabletWidth  int\n\t\tTabletHeight int\n\t\tScreenWidth  int\n\t\tScreenHeight int\n\t}\n\ttype args struct {\n\t\tx int\n\t\ty int\n\t}\n\ttests := []struct {\n\t\tname   string\n\t\tfields fields\n\t\targs   args\n\t\twantX  int\n\t\twantY  int\n\t}{\n\t\t{\n\t\t\tname: \"square scale factor 1\",\n\t\t\tfields: fields{\n\t\t\t\tTabletWidth:  100,\n\t\t\t\tTabletHeight: 100,\n\t\t\t\tScreenWidth:  100,\n\t\t\t\tScreenHeight: 100,\n\t\t\t},\n\t\t\targs: args{\n\t\t\t\tx: 50,\n\t\t\t\ty: 50,\n\t\t\t},\n\t\t\twantX: 50,\n\t\t\twantY: 50,\n\t\t},\n\t\t{\n\t\t\tname: \"square scale factor 2\",\n\t\t\tfields: fields{\n\t\t\t\tTabletWidth:  100,\n\t\t\t\tTabletHeight: 100,\n\t\t\t\tScreenWidth:  200,\n\t\t\t\tScreenHeight: 200,\n\t\t\t},\n\t\t\targs: args{\n\t\t\t\tx: 50,\n\t\t\t\ty: 50,\n\t\t\t},\n\t\t\twantX: 100,\n\t\t\twantY: 100,\n\t\t},\n\t\t{\n\t\t\tname: \"non-square\",\n\t\t\tfields: fields{\n\t\t\t\tTabletWidth:  100,\n\t\t\t\tTabletHeight: 200,\n\t\t\t\tScreenWidth:  400,\n\t\t\t\tScreenHeight: 200,\n\t\t\t},\n\t\t\targs: args{\n\t\t\t\tx: 50,\n\t\t\t\ty: 100,\n\t\t\t},\n\t\t\twantX: 200,\n\t\t\twantY: 100,\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\ts := &RightPositionScaler{\n\t\t\t\tTabletWidth:  tt.fields.TabletWidth,\n\t\t\t\tTabletHeight: tt.fields.TabletHeight,\n\t\t\t\tScreenWidth:  tt.fields.ScreenWidth,\n\t\t\t\tScreenHeight: tt.fields.ScreenHeight,\n\t\t\t}\n\t\t\tgotX, gotY := s.ScalePosition(tt.args.x, tt.args.y)\n\t\t\trequire.Equal(t, tt.wantX, gotX)\n\t\t\trequire.Equal(t, tt.wantY, gotY)\n\t\t})\n\t}\n}\n\nfunc TestLeftPositionScaler_ScalePosition(t *testing.T) {\n\ttype fields struct {\n\t\tTabletWidth  int\n\t\tTabletHeight int\n\t\tScreenWidth  int\n\t\tScreenHeight int\n\t}\n\ttype args struct {\n\t\tx int\n\t\ty int\n\t}\n\ttests := []struct {\n\t\tname   string\n\t\tfields fields\n\t\targs   args\n\t\twantX  int\n\t\twantY  int\n\t}{\n\t\t{\n\t\t\tname: \"square scale factor 1\",\n\t\t\tfields: fields{\n\t\t\t\tTabletWidth:  100,\n\t\t\t\tTabletHeight: 100,\n\t\t\t\tScreenWidth:  100,\n\t\t\t\tScreenHeight: 100,\n\t\t\t},\n\t\t\targs: args{\n\t\t\t\tx: 50,\n\t\t\t\ty: 50,\n\t\t\t},\n\t\t\twantX: 50,\n\t\t\twantY: 50,\n\t\t},\n\t\t{\n\t\t\tname: \"square scale factor 2\",\n\t\t\tfields: fields{\n\t\t\t\tTabletWidth:  100,\n\t\t\t\tTabletHeight: 100,\n\t\t\t\tScreenWidth:  200,\n\t\t\t\tScreenHeight: 200,\n\t\t\t},\n\t\t\targs: args{\n\t\t\t\tx: 50,\n\t\t\t\ty: 50,\n\t\t\t},\n\t\t\twantX: 100,\n\t\t\twantY: 100,\n\t\t},\n\t\t{\n\t\t\tname: \"non-square\",\n\t\t\tfields: fields{\n\t\t\t\tTabletWidth:  100,\n\t\t\t\tTabletHeight: 200,\n\t\t\t\tScreenWidth:  400,\n\t\t\t\tScreenHeight: 200,\n\t\t\t},\n\t\t\targs: args{\n\t\t\t\tx: 50,\n\t\t\t\ty: 100,\n\t\t\t},\n\t\t\twantX: 200,\n\t\t\twantY: 100,\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\ts := &LeftPositionScaler{\n\t\t\t\tTabletWidth:  tt.fields.TabletWidth,\n\t\t\t\tTabletHeight: tt.fields.TabletHeight,\n\t\t\t\tScreenWidth:  tt.fields.ScreenWidth,\n\t\t\t\tScreenHeight: tt.fields.ScreenHeight,\n\t\t\t}\n\t\t\tgotX, gotY := s.ScalePosition(tt.args.x, tt.args.y)\n\t\t\trequire.Equal(t, tt.wantX, gotX)\n\t\t\trequire.Equal(t, tt.wantY, gotY)\n\t\t})\n\t}\n}\n\nfunc TestVerticalPositionScaler_ScalePosition(t *testing.T) {\n\ttype fields struct {\n\t\tTabletWidth  int\n\t\tTabletHeight int\n\t\tScreenWidth  int\n\t\tScreenHeight int\n\t}\n\ttype args struct {\n\t\tx int\n\t\ty int\n\t}\n\ttests := []struct {\n\t\tname   string\n\t\tfields fields\n\t\targs   args\n\t\twantX  int\n\t\twantY  int\n\t}{\n\t\t{\n\t\t\tname: \"square scale factor 1\",\n\t\t\tfields: fields{\n\t\t\t\tTabletWidth:  100,\n\t\t\t\tTabletHeight: 100,\n\t\t\t\tScreenWidth:  100,\n\t\t\t\tScreenHeight: 100,\n\t\t\t},\n\t\t\targs: args{\n\t\t\t\tx: 50,\n\t\t\t\ty: 50,\n\t\t\t},\n\t\t\twantX: 50,\n\t\t\twantY: 50,\n\t\t},\n\t\t{\n\t\t\tname: \"square scale factor 2\",\n\t\t\tfields: fields{\n\t\t\t\tTabletWidth:  100,\n\t\t\t\tTabletHeight: 100,\n\t\t\t\tScreenWidth:  200,\n\t\t\t\tScreenHeight: 200,\n\t\t\t},\n\t\t\targs: args{\n\t\t\t\tx: 50,\n\t\t\t\ty: 50,\n\t\t\t},\n\t\t\twantX: 100,\n\t\t\twantY: 100,\n\t\t},\n\t\t{\n\t\t\tname: \"non-square\",\n\t\t\tfields: fields{\n\t\t\t\tTabletWidth:  100,\n\t\t\t\tTabletHeight: 200,\n\t\t\t\tScreenWidth:  400,\n\t\t\t\tScreenHeight: 200,\n\t\t\t},\n\t\t\targs: args{\n\t\t\t\tx: 50,\n\t\t\t\ty: 100,\n\t\t\t},\n\t\t\twantX: 200,\n\t\t\twantY: 100,\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\ts := &VerticalPositionScaler{\n\t\t\t\tTabletWidth:  tt.fields.TabletWidth,\n\t\t\t\tTabletHeight: tt.fields.TabletHeight,\n\t\t\t\tScreenWidth:  tt.fields.ScreenWidth,\n\t\t\t\tScreenHeight: tt.fields.ScreenHeight,\n\t\t\t}\n\t\t\tgotX, gotY := s.ScalePosition(tt.args.x, tt.args.y)\n\t\t\trequire.Equal(t, tt.wantX, gotX)\n\t\t\trequire.Equal(t, tt.wantY, gotY)\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "pkg/runtime.go",
    "content": "// This file is part of remouseable.\n//\n// remouseable is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License version 3 as published\n// by the Free Software Foundation.\n//\n// remouseable is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with remouseable.  If not, see <https://www.gnu.org/licenses/>.\n\npackage remouseable\n\nimport \"fmt\"\n\n// Runtime binds the various domain elements into an application.\ntype Runtime struct {\n\tStateMachine   StateMachine\n\tPositionScaler PositionScaler\n\tDriver         Driver\n\terr            error\n}\n\n// Next executes one step of the runtime loop.\nfunc (r *Runtime) Next() bool {\n\tif r.err != nil {\n\t\t// Attempt to prevent re-entry after an error is encountered.\n\t\treturn false\n\t}\n\tif !r.StateMachine.Next() {\n\t\t// Stop iteration if the state machine has completed all iterations.\n\t\treturn false\n\t}\n\tchange := r.StateMachine.Current()\n\tswitch change.Type() {\n\tcase ChangeTypeMove:\n\t\tevt := change.(*StateChangeMove)\n\t\tif err := r.Driver.MoveMouse(r.PositionScaler.ScalePosition(evt.X, evt.Y)); err != nil {\n\t\t\tr.err = err\n\t\t\treturn false\n\t\t}\n\t\treturn true\n\tcase ChangeTypeDrag:\n\t\tevt := change.(*StateChangeDrag)\n\t\tif err := r.Driver.DragMouse(r.PositionScaler.ScalePosition(evt.X, evt.Y)); err != nil {\n\t\t\tr.err = err\n\t\t\treturn false\n\t\t}\n\t\treturn true\n\tcase ChangeTypeClick:\n\t\tif err := r.Driver.Click(); err != nil {\n\t\t\tr.err = err\n\t\t\treturn false\n\t\t}\n\t\treturn true\n\tcase ChangeTypeUnclick:\n\t\tif err := r.Driver.Unclick(); err != nil {\n\t\t\tr.err = err\n\t\t\treturn false\n\t\t}\n\t\treturn true\n\tdefault:\n\t\tr.err = fmt.Errorf(\"encountered unhandled state machine event %s\", change.Type())\n\t\treturn false\n\t}\n}\n\n// Close the runtime and any internal resources.\nfunc (r *Runtime) Close() error {\n\terr := r.StateMachine.Close()\n\tif r.err != nil {\n\t\treturn r.err\n\t}\n\treturn err\n}\n"
  },
  {
    "path": "pkg/runtime_test.go",
    "content": "// This file is part of remouseable.\n//\n// remouseable is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License version 3 as published\n// by the Free Software Foundation.\n//\n// remouseable is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with remouseable.  If not, see <https://www.gnu.org/licenses/>.\n\npackage remouseable\n\nimport (\n\t\"fmt\"\n\t\"testing\"\n\n\tgomock \"github.com/golang/mock/gomock\"\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc TestRuntimeEmptyStateMachine(t *testing.T) {\n\tctrl := gomock.NewController(t)\n\tdefer ctrl.Finish()\n\n\td := NewMockDriver(ctrl)\n\tp := NewMockPositionScaler(ctrl)\n\ts := NewMockStateMachine(ctrl)\n\trt := &Runtime{\n\t\tDriver:         d,\n\t\tPositionScaler: p,\n\t\tStateMachine:   s,\n\t}\n\ts.EXPECT().Next().Return(false).AnyTimes()\n\ts.EXPECT().Close().Return(nil)\n\trequire.False(t, rt.Next())\n\trequire.False(t, rt.Next())\n\trequire.Nil(t, rt.Close())\n}\n\nfunc TestRuntimeStopsInErrorState(t *testing.T) {\n\tctrl := gomock.NewController(t)\n\tdefer ctrl.Finish()\n\n\td := NewMockDriver(ctrl)\n\tp := NewMockPositionScaler(ctrl)\n\ts := NewMockStateMachine(ctrl)\n\trt := &Runtime{\n\t\tDriver:         d,\n\t\tPositionScaler: p,\n\t\tStateMachine:   s,\n\t\terr:            fmt.Errorf(\"test\"),\n\t}\n\ts.EXPECT().Close().Return(nil)\n\trequire.False(t, rt.Next())\n\trequire.False(t, rt.Next())\n\trequire.NotNil(t, rt.Close())\n}\n\ntype badStateChange struct{}\n\nfunc (*badStateChange) Type() string { return \"unknown\" }\n\nfunc TestRuntimeErrorsOnUnknownStateChanges(t *testing.T) {\n\tctrl := gomock.NewController(t)\n\tdefer ctrl.Finish()\n\n\td := NewMockDriver(ctrl)\n\tp := NewMockPositionScaler(ctrl)\n\ts := NewMockStateMachine(ctrl)\n\trt := &Runtime{\n\t\tDriver:         d,\n\t\tPositionScaler: p,\n\t\tStateMachine:   s,\n\t}\n\ts.EXPECT().Next().Return(true)\n\ts.EXPECT().Current().Return(&badStateChange{})\n\ts.EXPECT().Close().Return(nil)\n\trequire.False(t, rt.Next())\n\trequire.NotNil(t, rt.Close())\n}\n\nfunc TestRuntimeHandlesMove(t *testing.T) {\n\tctrl := gomock.NewController(t)\n\tdefer ctrl.Finish()\n\n\td := NewMockDriver(ctrl)\n\tp := NewMockPositionScaler(ctrl)\n\ts := NewMockStateMachine(ctrl)\n\trt := &Runtime{\n\t\tDriver:         d,\n\t\tPositionScaler: p,\n\t\tStateMachine:   s,\n\t}\n\tevt := &StateChangeMove{X: 1, Y: 2}\n\ts.EXPECT().Next().Return(true)\n\ts.EXPECT().Current().Return(evt)\n\tp.EXPECT().ScalePosition(evt.X, evt.Y).Return(2, 3)\n\td.EXPECT().MoveMouse(2, 3).Return(nil)\n\ts.EXPECT().Next().Return(true)\n\ts.EXPECT().Current().Return(evt)\n\tp.EXPECT().ScalePosition(evt.X, evt.Y).Return(2, 3)\n\td.EXPECT().MoveMouse(2, 3).Return(fmt.Errorf(\"move failed\"))\n\ts.EXPECT().Close().Return(nil)\n\n\trequire.True(t, rt.Next())\n\trequire.False(t, rt.Next())\n\trequire.NotNil(t, rt.Close())\n}\n\nfunc TestRuntimeHandlesDrag(t *testing.T) {\n\tctrl := gomock.NewController(t)\n\tdefer ctrl.Finish()\n\n\td := NewMockDriver(ctrl)\n\tp := NewMockPositionScaler(ctrl)\n\ts := NewMockStateMachine(ctrl)\n\trt := &Runtime{\n\t\tDriver:         d,\n\t\tPositionScaler: p,\n\t\tStateMachine:   s,\n\t}\n\tevt := &StateChangeDrag{X: 1, Y: 2}\n\ts.EXPECT().Next().Return(true)\n\ts.EXPECT().Current().Return(evt)\n\tp.EXPECT().ScalePosition(evt.X, evt.Y).Return(2, 3)\n\td.EXPECT().DragMouse(2, 3).Return(nil)\n\ts.EXPECT().Next().Return(true)\n\ts.EXPECT().Current().Return(evt)\n\tp.EXPECT().ScalePosition(evt.X, evt.Y).Return(2, 3)\n\td.EXPECT().DragMouse(2, 3).Return(fmt.Errorf(\"drag failed\"))\n\ts.EXPECT().Close().Return(nil)\n\n\trequire.True(t, rt.Next())\n\trequire.False(t, rt.Next())\n\trequire.NotNil(t, rt.Close())\n}\n\nfunc TestRuntimeHandlesClick(t *testing.T) {\n\tctrl := gomock.NewController(t)\n\tdefer ctrl.Finish()\n\n\td := NewMockDriver(ctrl)\n\tp := NewMockPositionScaler(ctrl)\n\ts := NewMockStateMachine(ctrl)\n\trt := &Runtime{\n\t\tDriver:         d,\n\t\tPositionScaler: p,\n\t\tStateMachine:   s,\n\t}\n\tevt := &StateChangeClick{}\n\ts.EXPECT().Next().Return(true)\n\ts.EXPECT().Current().Return(evt)\n\td.EXPECT().Click().Return(nil)\n\ts.EXPECT().Next().Return(true)\n\ts.EXPECT().Current().Return(evt)\n\td.EXPECT().Click().Return(fmt.Errorf(\"click failed\"))\n\ts.EXPECT().Close().Return(nil)\n\n\trequire.True(t, rt.Next())\n\trequire.False(t, rt.Next())\n\trequire.NotNil(t, rt.Close())\n}\n\nfunc TestRuntimeHandlesUnclick(t *testing.T) {\n\tctrl := gomock.NewController(t)\n\tdefer ctrl.Finish()\n\n\td := NewMockDriver(ctrl)\n\tp := NewMockPositionScaler(ctrl)\n\ts := NewMockStateMachine(ctrl)\n\trt := &Runtime{\n\t\tDriver:         d,\n\t\tPositionScaler: p,\n\t\tStateMachine:   s,\n\t}\n\tevt := &StateChangeUnclick{}\n\ts.EXPECT().Next().Return(true)\n\ts.EXPECT().Current().Return(evt)\n\td.EXPECT().Unclick().Return(nil)\n\ts.EXPECT().Next().Return(true)\n\ts.EXPECT().Current().Return(evt)\n\td.EXPECT().Unclick().Return(fmt.Errorf(\"unclick failed\"))\n\ts.EXPECT().Close().Return(nil)\n\n\trequire.True(t, rt.Next())\n\trequire.False(t, rt.Next())\n\trequire.NotNil(t, rt.Close())\n}\n"
  },
  {
    "path": "pkg/statemachine.go",
    "content": "// This file is part of remouseable.\n//\n// remouseable is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License version 3 as published\n// by the Free Software Foundation.\n//\n// remouseable is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with remouseable.  If not, see <https://www.gnu.org/licenses/>.\n\npackage remouseable\n\n// EvdevStateMachine converts and EvdevIterator into significant state events.\ntype EvdevStateMachine struct {\n\tIterator          EvdevIterator\n\tPressureThreshold int\n\tx                 int\n\txChanged          bool\n\ty                 int\n\tyChanged          bool\n\tclicked           bool\n\tcurrent           StateChange\n}\n\n// next pushes the state machine one step. The return value is whether or not\n// a new state was achieved in the step.\nfunc (it *EvdevStateMachine) next(raw EvdevEvent) bool {\n\tif raw.Type != EV_ABS {\n\t\treturn false\n\t}\n\tswitch raw.Code {\n\tcase ABS_X:\n\t\tit.x = int(raw.Value)\n\t\tit.xChanged = true\n\tcase ABS_Y:\n\t\tit.y = int(raw.Value)\n\t\tit.yChanged = true\n\tcase ABS_PRESSURE:\n\t\tif int(raw.Value) > it.PressureThreshold && !it.clicked {\n\t\t\tit.clicked = true\n\t\t\tit.current = &StateChangeClick{}\n\t\t\treturn true\n\t\t}\n\t\tif int(raw.Value) < it.PressureThreshold && it.clicked {\n\t\t\tit.clicked = false\n\t\t\tit.current = &StateChangeUnclick{}\n\t\t\treturn true\n\t\t}\n\tdefault:\n\t}\n\tif it.xChanged && it.yChanged {\n\t\tit.xChanged = false\n\t\tit.yChanged = false\n\t\tit.current = &StateChangeMove{X: it.x, Y: it.y}\n\t\treturn true\n\t}\n\treturn false\n}\n\n// Next consumes from the raw event iterator until a new state is achieved.\nfunc (it *EvdevStateMachine) Next() bool {\n\tfor it.Iterator.Next() {\n\t\traw := it.Iterator.Current()\n\t\tif it.next(raw) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\n// Current returns the iterator value.\nfunc (it *EvdevStateMachine) Current() StateChange {\n\treturn it.current\n}\n\n// Close the underlying source and return any errors.\nfunc (it *EvdevStateMachine) Close() error {\n\treturn it.Iterator.Close()\n}\n\ntype DraggingEvdevStateMachine struct {\n\t*EvdevStateMachine\n}\n\n// next pushes the state machine one step. The return value is whether or not\n// a new state was achieved in the step.\nfunc (it *DraggingEvdevStateMachine) next(raw EvdevEvent) bool {\n\tif ok := it.EvdevStateMachine.next(raw); !ok {\n\t\treturn false\n\t}\n\tswitch ev := it.current.(type) {\n\tcase *StateChangeMove:\n\t\tif it.clicked {\n\t\t\tit.current = &StateChangeDrag{X: ev.X, Y: ev.Y}\n\t\t}\n\tdefault:\n\t\tbreak\n\t}\n\treturn true\n}\n\n// Next consumes from the raw event iterator until a new state is achieved.\nfunc (it *DraggingEvdevStateMachine) Next() bool {\n\tfor it.Iterator.Next() {\n\t\traw := it.Iterator.Current()\n\t\tif it.next(raw) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n"
  },
  {
    "path": "pkg/statemachine_test.go",
    "content": "// This file is part of remouseable.\n//\n// remouseable is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License version 3 as published\n// by the Free Software Foundation.\n//\n// remouseable is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with remouseable.  If not, see <https://www.gnu.org/licenses/>.\n\npackage remouseable\n\nimport (\n\t\"testing\"\n\n\tgomock \"github.com/golang/mock/gomock\"\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc TestStateMachineEmptyIterator(t *testing.T) {\n\tctrl := gomock.NewController(t)\n\tdefer ctrl.Finish()\n\n\tit := NewMockEvdevIterator(ctrl)\n\tsm := &EvdevStateMachine{\n\t\tIterator: it,\n\t}\n\n\tit.EXPECT().Next().Return(false).AnyTimes()\n\tit.EXPECT().Close().Return(nil)\n\n\trequire.False(t, sm.Next())\n\trequire.False(t, sm.Next())\n\trequire.Nil(t, sm.Close())\n}\n\nfunc TestEvdevStateMachine_next(t *testing.T) {\n\ttype fields struct {\n\t\tIterator          EvdevIterator\n\t\tPressureThreshold int\n\t\tx                 int\n\t\txChanged          bool\n\t\ty                 int\n\t\tyChanged          bool\n\t\tclicked           bool\n\t\tcurrent           StateChange\n\t}\n\ttype args struct {\n\t\traw EvdevEvent\n\t}\n\ttests := []struct {\n\t\tname        string\n\t\tfields      fields\n\t\targs        args\n\t\twant        bool\n\t\twantMachine *EvdevStateMachine\n\t}{\n\t\t{\n\t\t\tname: \"skips non-ABS event\",\n\t\t\tfields: fields{\n\t\t\t\tIterator:          nil,\n\t\t\t\tPressureThreshold: 1000,\n\t\t\t\tx:                 0,\n\t\t\t\txChanged:          false,\n\t\t\t\ty:                 0,\n\t\t\t\tyChanged:          false,\n\t\t\t\tclicked:           false,\n\t\t\t\tcurrent:           nil,\n\t\t\t},\n\t\t\targs: args{\n\t\t\t\traw: EvdevEvent{Type: EV_LED},\n\t\t\t},\n\t\t\twant: false,\n\t\t\twantMachine: &EvdevStateMachine{\n\t\t\t\tIterator:          nil,\n\t\t\t\tPressureThreshold: 1000,\n\t\t\t\tx:                 0,\n\t\t\t\txChanged:          false,\n\t\t\t\ty:                 0,\n\t\t\t\tyChanged:          false,\n\t\t\t\tclicked:           false,\n\t\t\t\tcurrent:           nil,\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"x event without y\",\n\t\t\tfields: fields{\n\t\t\t\tIterator:          nil,\n\t\t\t\tPressureThreshold: 1000,\n\t\t\t\tx:                 0,\n\t\t\t\txChanged:          false,\n\t\t\t\ty:                 0,\n\t\t\t\tyChanged:          false,\n\t\t\t\tclicked:           false,\n\t\t\t\tcurrent:           nil,\n\t\t\t},\n\t\t\targs: args{\n\t\t\t\traw: EvdevEvent{\n\t\t\t\t\tType:  EV_ABS,\n\t\t\t\t\tCode:  ABS_X,\n\t\t\t\t\tValue: 1,\n\t\t\t\t},\n\t\t\t},\n\t\t\twant: false,\n\t\t\twantMachine: &EvdevStateMachine{\n\t\t\t\tIterator:          nil,\n\t\t\t\tPressureThreshold: 1000,\n\t\t\t\tx:                 1,\n\t\t\t\txChanged:          true,\n\t\t\t\ty:                 0,\n\t\t\t\tyChanged:          false,\n\t\t\t\tclicked:           false,\n\t\t\t\tcurrent:           nil,\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"y event without x\",\n\t\t\tfields: fields{\n\t\t\t\tIterator:          nil,\n\t\t\t\tPressureThreshold: 1000,\n\t\t\t\tx:                 0,\n\t\t\t\txChanged:          false,\n\t\t\t\ty:                 0,\n\t\t\t\tyChanged:          false,\n\t\t\t\tclicked:           false,\n\t\t\t\tcurrent:           nil,\n\t\t\t},\n\t\t\targs: args{\n\t\t\t\traw: EvdevEvent{\n\t\t\t\t\tType:  EV_ABS,\n\t\t\t\t\tCode:  ABS_Y,\n\t\t\t\t\tValue: 1,\n\t\t\t\t},\n\t\t\t},\n\t\t\twant: false,\n\t\t\twantMachine: &EvdevStateMachine{\n\t\t\t\tIterator:          nil,\n\t\t\t\tPressureThreshold: 1000,\n\t\t\t\tx:                 0,\n\t\t\t\txChanged:          false,\n\t\t\t\ty:                 1,\n\t\t\t\tyChanged:          true,\n\t\t\t\tclicked:           false,\n\t\t\t\tcurrent:           nil,\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"x to y\",\n\t\t\tfields: fields{\n\t\t\t\tIterator:          nil,\n\t\t\t\tPressureThreshold: 1000,\n\t\t\t\tx:                 1,\n\t\t\t\txChanged:          true,\n\t\t\t\ty:                 0,\n\t\t\t\tyChanged:          false,\n\t\t\t\tclicked:           false,\n\t\t\t\tcurrent:           nil,\n\t\t\t},\n\t\t\targs: args{\n\t\t\t\traw: EvdevEvent{\n\t\t\t\t\tType:  EV_ABS,\n\t\t\t\t\tCode:  ABS_Y,\n\t\t\t\t\tValue: 1,\n\t\t\t\t},\n\t\t\t},\n\t\t\twant: true,\n\t\t\twantMachine: &EvdevStateMachine{\n\t\t\t\tIterator:          nil,\n\t\t\t\tPressureThreshold: 1000,\n\t\t\t\tx:                 1,\n\t\t\t\txChanged:          false,\n\t\t\t\ty:                 1,\n\t\t\t\tyChanged:          false,\n\t\t\t\tclicked:           false,\n\t\t\t\tcurrent:           &StateChangeMove{X: 1, Y: 1},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"y to x\",\n\t\t\tfields: fields{\n\t\t\t\tIterator:          nil,\n\t\t\t\tPressureThreshold: 1000,\n\t\t\t\tx:                 0,\n\t\t\t\txChanged:          false,\n\t\t\t\ty:                 1,\n\t\t\t\tyChanged:          true,\n\t\t\t\tclicked:           false,\n\t\t\t\tcurrent:           nil,\n\t\t\t},\n\t\t\targs: args{\n\t\t\t\traw: EvdevEvent{\n\t\t\t\t\tType:  EV_ABS,\n\t\t\t\t\tCode:  ABS_X,\n\t\t\t\t\tValue: 1,\n\t\t\t\t},\n\t\t\t},\n\t\t\twant: true,\n\t\t\twantMachine: &EvdevStateMachine{\n\t\t\t\tIterator:          nil,\n\t\t\t\tPressureThreshold: 1000,\n\t\t\t\tx:                 1,\n\t\t\t\txChanged:          false,\n\t\t\t\ty:                 1,\n\t\t\t\tyChanged:          false,\n\t\t\t\tclicked:           false,\n\t\t\t\tcurrent:           &StateChangeMove{X: 1, Y: 1},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"click\",\n\t\t\tfields: fields{\n\t\t\t\tIterator:          nil,\n\t\t\t\tPressureThreshold: 1000,\n\t\t\t\tx:                 0,\n\t\t\t\txChanged:          false,\n\t\t\t\ty:                 0,\n\t\t\t\tyChanged:          false,\n\t\t\t\tclicked:           false,\n\t\t\t\tcurrent:           nil,\n\t\t\t},\n\t\t\targs: args{\n\t\t\t\traw: EvdevEvent{\n\t\t\t\t\tType:  EV_ABS,\n\t\t\t\t\tCode:  ABS_PRESSURE,\n\t\t\t\t\tValue: 2000,\n\t\t\t\t},\n\t\t\t},\n\t\t\twant: true,\n\t\t\twantMachine: &EvdevStateMachine{\n\t\t\t\tIterator:          nil,\n\t\t\t\tPressureThreshold: 1000,\n\t\t\t\tx:                 0,\n\t\t\t\txChanged:          false,\n\t\t\t\ty:                 0,\n\t\t\t\tyChanged:          false,\n\t\t\t\tclicked:           true,\n\t\t\t\tcurrent:           &StateChangeClick{},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"click while clicked\",\n\t\t\tfields: fields{\n\t\t\t\tIterator:          nil,\n\t\t\t\tPressureThreshold: 1000,\n\t\t\t\tx:                 0,\n\t\t\t\txChanged:          false,\n\t\t\t\ty:                 0,\n\t\t\t\tyChanged:          false,\n\t\t\t\tclicked:           true,\n\t\t\t\tcurrent:           nil,\n\t\t\t},\n\t\t\targs: args{\n\t\t\t\traw: EvdevEvent{\n\t\t\t\t\tType:  EV_ABS,\n\t\t\t\t\tCode:  ABS_PRESSURE,\n\t\t\t\t\tValue: 2000,\n\t\t\t\t},\n\t\t\t},\n\t\t\twant: false,\n\t\t\twantMachine: &EvdevStateMachine{\n\t\t\t\tIterator:          nil,\n\t\t\t\tPressureThreshold: 1000,\n\t\t\t\tx:                 0,\n\t\t\t\txChanged:          false,\n\t\t\t\ty:                 0,\n\t\t\t\tyChanged:          false,\n\t\t\t\tclicked:           true,\n\t\t\t\tcurrent:           nil,\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"unclick\",\n\t\t\tfields: fields{\n\t\t\t\tIterator:          nil,\n\t\t\t\tPressureThreshold: 1000,\n\t\t\t\tx:                 0,\n\t\t\t\txChanged:          false,\n\t\t\t\ty:                 0,\n\t\t\t\tyChanged:          false,\n\t\t\t\tclicked:           true,\n\t\t\t\tcurrent:           nil,\n\t\t\t},\n\t\t\targs: args{\n\t\t\t\traw: EvdevEvent{\n\t\t\t\t\tType:  EV_ABS,\n\t\t\t\t\tCode:  ABS_PRESSURE,\n\t\t\t\t\tValue: 500,\n\t\t\t\t},\n\t\t\t},\n\t\t\twant: true,\n\t\t\twantMachine: &EvdevStateMachine{\n\t\t\t\tIterator:          nil,\n\t\t\t\tPressureThreshold: 1000,\n\t\t\t\tx:                 0,\n\t\t\t\txChanged:          false,\n\t\t\t\ty:                 0,\n\t\t\t\tyChanged:          false,\n\t\t\t\tclicked:           false,\n\t\t\t\tcurrent:           &StateChangeUnclick{},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"unclick while unclicked\",\n\t\t\tfields: fields{\n\t\t\t\tIterator:          nil,\n\t\t\t\tPressureThreshold: 1000,\n\t\t\t\tx:                 0,\n\t\t\t\txChanged:          false,\n\t\t\t\ty:                 0,\n\t\t\t\tyChanged:          false,\n\t\t\t\tclicked:           false,\n\t\t\t\tcurrent:           nil,\n\t\t\t},\n\t\t\targs: args{\n\t\t\t\traw: EvdevEvent{\n\t\t\t\t\tType:  EV_ABS,\n\t\t\t\t\tCode:  ABS_PRESSURE,\n\t\t\t\t\tValue: 500,\n\t\t\t\t},\n\t\t\t},\n\t\t\twant: false,\n\t\t\twantMachine: &EvdevStateMachine{\n\t\t\t\tIterator:          nil,\n\t\t\t\tPressureThreshold: 1000,\n\t\t\t\tx:                 0,\n\t\t\t\txChanged:          false,\n\t\t\t\ty:                 0,\n\t\t\t\tyChanged:          false,\n\t\t\t\tclicked:           false,\n\t\t\t\tcurrent:           nil,\n\t\t\t},\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tit := &EvdevStateMachine{\n\t\t\t\tIterator:          tt.fields.Iterator,\n\t\t\t\tPressureThreshold: tt.fields.PressureThreshold,\n\t\t\t\tx:                 tt.fields.x,\n\t\t\t\txChanged:          tt.fields.xChanged,\n\t\t\t\ty:                 tt.fields.y,\n\t\t\t\tyChanged:          tt.fields.yChanged,\n\t\t\t\tclicked:           tt.fields.clicked,\n\t\t\t\tcurrent:           tt.fields.current,\n\t\t\t}\n\t\t\trequire.Equal(t, tt.want, it.next(tt.args.raw))\n\t\t\trequire.Equal(t, *tt.wantMachine, *it)\n\t\t})\n\t}\n}\n\nfunc TestDraggingEvdevStateMachine_next(t *testing.T) {\n\ttype fields struct {\n\t\tIterator          EvdevIterator\n\t\tPressureThreshold int\n\t\tx                 int\n\t\txChanged          bool\n\t\ty                 int\n\t\tyChanged          bool\n\t\tclicked           bool\n\t\tcurrent           StateChange\n\t}\n\ttype args struct {\n\t\traw EvdevEvent\n\t}\n\ttests := []struct {\n\t\tname        string\n\t\tfields      fields\n\t\targs        args\n\t\twant        bool\n\t\twantMachine *DraggingEvdevStateMachine\n\t}{\n\t\t{\n\t\t\tname: \"skips non-ABS event\",\n\t\t\tfields: fields{\n\t\t\t\tIterator:          nil,\n\t\t\t\tPressureThreshold: 1000,\n\t\t\t\tx:                 0,\n\t\t\t\txChanged:          false,\n\t\t\t\ty:                 0,\n\t\t\t\tyChanged:          false,\n\t\t\t\tclicked:           false,\n\t\t\t\tcurrent:           nil,\n\t\t\t},\n\t\t\targs: args{\n\t\t\t\traw: EvdevEvent{Type: EV_LED},\n\t\t\t},\n\t\t\twant: false,\n\t\t\twantMachine: &DraggingEvdevStateMachine{&EvdevStateMachine{\n\t\t\t\tIterator:          nil,\n\t\t\t\tPressureThreshold: 1000,\n\t\t\t\tx:                 0,\n\t\t\t\txChanged:          false,\n\t\t\t\ty:                 0,\n\t\t\t\tyChanged:          false,\n\t\t\t\tclicked:           false,\n\t\t\t\tcurrent:           nil,\n\t\t\t}},\n\t\t},\n\t\t{\n\t\t\tname: \"x event without y\",\n\t\t\tfields: fields{\n\t\t\t\tIterator:          nil,\n\t\t\t\tPressureThreshold: 1000,\n\t\t\t\tx:                 0,\n\t\t\t\txChanged:          false,\n\t\t\t\ty:                 0,\n\t\t\t\tyChanged:          false,\n\t\t\t\tclicked:           false,\n\t\t\t\tcurrent:           nil,\n\t\t\t},\n\t\t\targs: args{\n\t\t\t\traw: EvdevEvent{\n\t\t\t\t\tType:  EV_ABS,\n\t\t\t\t\tCode:  ABS_X,\n\t\t\t\t\tValue: 1,\n\t\t\t\t},\n\t\t\t},\n\t\t\twant: false,\n\t\t\twantMachine: &DraggingEvdevStateMachine{&EvdevStateMachine{\n\t\t\t\tIterator:          nil,\n\t\t\t\tPressureThreshold: 1000,\n\t\t\t\tx:                 1,\n\t\t\t\txChanged:          true,\n\t\t\t\ty:                 0,\n\t\t\t\tyChanged:          false,\n\t\t\t\tclicked:           false,\n\t\t\t\tcurrent:           nil,\n\t\t\t}},\n\t\t},\n\t\t{\n\t\t\tname: \"y event without x\",\n\t\t\tfields: fields{\n\t\t\t\tIterator:          nil,\n\t\t\t\tPressureThreshold: 1000,\n\t\t\t\tx:                 0,\n\t\t\t\txChanged:          false,\n\t\t\t\ty:                 0,\n\t\t\t\tyChanged:          false,\n\t\t\t\tclicked:           false,\n\t\t\t\tcurrent:           nil,\n\t\t\t},\n\t\t\targs: args{\n\t\t\t\traw: EvdevEvent{\n\t\t\t\t\tType:  EV_ABS,\n\t\t\t\t\tCode:  ABS_Y,\n\t\t\t\t\tValue: 1,\n\t\t\t\t},\n\t\t\t},\n\t\t\twant: false,\n\t\t\twantMachine: &DraggingEvdevStateMachine{&EvdevStateMachine{\n\t\t\t\tIterator:          nil,\n\t\t\t\tPressureThreshold: 1000,\n\t\t\t\tx:                 0,\n\t\t\t\txChanged:          false,\n\t\t\t\ty:                 1,\n\t\t\t\tyChanged:          true,\n\t\t\t\tclicked:           false,\n\t\t\t\tcurrent:           nil,\n\t\t\t}},\n\t\t},\n\t\t{\n\t\t\tname: \"x to y\",\n\t\t\tfields: fields{\n\t\t\t\tIterator:          nil,\n\t\t\t\tPressureThreshold: 1000,\n\t\t\t\tx:                 1,\n\t\t\t\txChanged:          true,\n\t\t\t\ty:                 0,\n\t\t\t\tyChanged:          false,\n\t\t\t\tclicked:           false,\n\t\t\t\tcurrent:           nil,\n\t\t\t},\n\t\t\targs: args{\n\t\t\t\traw: EvdevEvent{\n\t\t\t\t\tType:  EV_ABS,\n\t\t\t\t\tCode:  ABS_Y,\n\t\t\t\t\tValue: 1,\n\t\t\t\t},\n\t\t\t},\n\t\t\twant: true,\n\t\t\twantMachine: &DraggingEvdevStateMachine{&EvdevStateMachine{\n\t\t\t\tIterator:          nil,\n\t\t\t\tPressureThreshold: 1000,\n\t\t\t\tx:                 1,\n\t\t\t\txChanged:          false,\n\t\t\t\ty:                 1,\n\t\t\t\tyChanged:          false,\n\t\t\t\tclicked:           false,\n\t\t\t\tcurrent:           &StateChangeMove{X: 1, Y: 1},\n\t\t\t}},\n\t\t},\n\t\t{\n\t\t\tname: \"y to x\",\n\t\t\tfields: fields{\n\t\t\t\tIterator:          nil,\n\t\t\t\tPressureThreshold: 1000,\n\t\t\t\tx:                 0,\n\t\t\t\txChanged:          false,\n\t\t\t\ty:                 1,\n\t\t\t\tyChanged:          true,\n\t\t\t\tclicked:           false,\n\t\t\t\tcurrent:           nil,\n\t\t\t},\n\t\t\targs: args{\n\t\t\t\traw: EvdevEvent{\n\t\t\t\t\tType:  EV_ABS,\n\t\t\t\t\tCode:  ABS_X,\n\t\t\t\t\tValue: 1,\n\t\t\t\t},\n\t\t\t},\n\t\t\twant: true,\n\t\t\twantMachine: &DraggingEvdevStateMachine{&EvdevStateMachine{\n\t\t\t\tIterator:          nil,\n\t\t\t\tPressureThreshold: 1000,\n\t\t\t\tx:                 1,\n\t\t\t\txChanged:          false,\n\t\t\t\ty:                 1,\n\t\t\t\tyChanged:          false,\n\t\t\t\tclicked:           false,\n\t\t\t\tcurrent:           &StateChangeMove{X: 1, Y: 1},\n\t\t\t}},\n\t\t},\n\t\t{\n\t\t\tname: \"move while clicked\",\n\t\t\tfields: fields{\n\t\t\t\tIterator:          nil,\n\t\t\t\tPressureThreshold: 1000,\n\t\t\t\tx:                 0,\n\t\t\t\txChanged:          false,\n\t\t\t\ty:                 1,\n\t\t\t\tyChanged:          true,\n\t\t\t\tclicked:           true,\n\t\t\t\tcurrent:           nil,\n\t\t\t},\n\t\t\targs: args{\n\t\t\t\traw: EvdevEvent{\n\t\t\t\t\tType:  EV_ABS,\n\t\t\t\t\tCode:  ABS_X,\n\t\t\t\t\tValue: 1,\n\t\t\t\t},\n\t\t\t},\n\t\t\twant: true,\n\t\t\twantMachine: &DraggingEvdevStateMachine{&EvdevStateMachine{\n\t\t\t\tIterator:          nil,\n\t\t\t\tPressureThreshold: 1000,\n\t\t\t\tx:                 1,\n\t\t\t\txChanged:          false,\n\t\t\t\ty:                 1,\n\t\t\t\tyChanged:          false,\n\t\t\t\tclicked:           true,\n\t\t\t\tcurrent:           &StateChangeDrag{X: 1, Y: 1},\n\t\t\t}},\n\t\t},\n\t\t{\n\t\t\tname: \"click\",\n\t\t\tfields: fields{\n\t\t\t\tIterator:          nil,\n\t\t\t\tPressureThreshold: 1000,\n\t\t\t\tx:                 0,\n\t\t\t\txChanged:          false,\n\t\t\t\ty:                 0,\n\t\t\t\tyChanged:          false,\n\t\t\t\tclicked:           false,\n\t\t\t\tcurrent:           nil,\n\t\t\t},\n\t\t\targs: args{\n\t\t\t\traw: EvdevEvent{\n\t\t\t\t\tType:  EV_ABS,\n\t\t\t\t\tCode:  ABS_PRESSURE,\n\t\t\t\t\tValue: 2000,\n\t\t\t\t},\n\t\t\t},\n\t\t\twant: true,\n\t\t\twantMachine: &DraggingEvdevStateMachine{&EvdevStateMachine{\n\t\t\t\tIterator:          nil,\n\t\t\t\tPressureThreshold: 1000,\n\t\t\t\tx:                 0,\n\t\t\t\txChanged:          false,\n\t\t\t\ty:                 0,\n\t\t\t\tyChanged:          false,\n\t\t\t\tclicked:           true,\n\t\t\t\tcurrent:           &StateChangeClick{},\n\t\t\t}},\n\t\t},\n\t\t{\n\t\t\tname: \"click while clicked\",\n\t\t\tfields: fields{\n\t\t\t\tIterator:          nil,\n\t\t\t\tPressureThreshold: 1000,\n\t\t\t\tx:                 0,\n\t\t\t\txChanged:          false,\n\t\t\t\ty:                 0,\n\t\t\t\tyChanged:          false,\n\t\t\t\tclicked:           true,\n\t\t\t\tcurrent:           nil,\n\t\t\t},\n\t\t\targs: args{\n\t\t\t\traw: EvdevEvent{\n\t\t\t\t\tType:  EV_ABS,\n\t\t\t\t\tCode:  ABS_PRESSURE,\n\t\t\t\t\tValue: 2000,\n\t\t\t\t},\n\t\t\t},\n\t\t\twant: false,\n\t\t\twantMachine: &DraggingEvdevStateMachine{&EvdevStateMachine{\n\t\t\t\tIterator:          nil,\n\t\t\t\tPressureThreshold: 1000,\n\t\t\t\tx:                 0,\n\t\t\t\txChanged:          false,\n\t\t\t\ty:                 0,\n\t\t\t\tyChanged:          false,\n\t\t\t\tclicked:           true,\n\t\t\t\tcurrent:           nil,\n\t\t\t}},\n\t\t},\n\t\t{\n\t\t\tname: \"unclick\",\n\t\t\tfields: fields{\n\t\t\t\tIterator:          nil,\n\t\t\t\tPressureThreshold: 1000,\n\t\t\t\tx:                 0,\n\t\t\t\txChanged:          false,\n\t\t\t\ty:                 0,\n\t\t\t\tyChanged:          false,\n\t\t\t\tclicked:           true,\n\t\t\t\tcurrent:           nil,\n\t\t\t},\n\t\t\targs: args{\n\t\t\t\traw: EvdevEvent{\n\t\t\t\t\tType:  EV_ABS,\n\t\t\t\t\tCode:  ABS_PRESSURE,\n\t\t\t\t\tValue: 500,\n\t\t\t\t},\n\t\t\t},\n\t\t\twant: true,\n\t\t\twantMachine: &DraggingEvdevStateMachine{&EvdevStateMachine{\n\t\t\t\tIterator:          nil,\n\t\t\t\tPressureThreshold: 1000,\n\t\t\t\tx:                 0,\n\t\t\t\txChanged:          false,\n\t\t\t\ty:                 0,\n\t\t\t\tyChanged:          false,\n\t\t\t\tclicked:           false,\n\t\t\t\tcurrent:           &StateChangeUnclick{},\n\t\t\t}},\n\t\t},\n\t\t{\n\t\t\tname: \"unclick while unclicked\",\n\t\t\tfields: fields{\n\t\t\t\tIterator:          nil,\n\t\t\t\tPressureThreshold: 1000,\n\t\t\t\tx:                 0,\n\t\t\t\txChanged:          false,\n\t\t\t\ty:                 0,\n\t\t\t\tyChanged:          false,\n\t\t\t\tclicked:           false,\n\t\t\t\tcurrent:           nil,\n\t\t\t},\n\t\t\targs: args{\n\t\t\t\traw: EvdevEvent{\n\t\t\t\t\tType:  EV_ABS,\n\t\t\t\t\tCode:  ABS_PRESSURE,\n\t\t\t\t\tValue: 500,\n\t\t\t\t},\n\t\t\t},\n\t\t\twant: false,\n\t\t\twantMachine: &DraggingEvdevStateMachine{&EvdevStateMachine{\n\t\t\t\tIterator:          nil,\n\t\t\t\tPressureThreshold: 1000,\n\t\t\t\tx:                 0,\n\t\t\t\txChanged:          false,\n\t\t\t\ty:                 0,\n\t\t\t\tyChanged:          false,\n\t\t\t\tclicked:           false,\n\t\t\t\tcurrent:           nil,\n\t\t\t}},\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tit := &DraggingEvdevStateMachine{&EvdevStateMachine{\n\t\t\t\tIterator:          tt.fields.Iterator,\n\t\t\t\tPressureThreshold: tt.fields.PressureThreshold,\n\t\t\t\tx:                 tt.fields.x,\n\t\t\t\txChanged:          tt.fields.xChanged,\n\t\t\t\ty:                 tt.fields.y,\n\t\t\t\tyChanged:          tt.fields.yChanged,\n\t\t\t\tclicked:           tt.fields.clicked,\n\t\t\t\tcurrent:           tt.fields.current,\n\t\t\t}}\n\t\t\trequire.Equal(t, tt.want, it.next(tt.args.raw))\n\t\t\trequire.Equal(t, *tt.wantMachine, *it)\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "technical-documentation/README.md",
    "content": "# reMouseable Design Documentation\n\nThis document details how reMouseable works, the rationale for the software\ndesign choices, and suggestions for folks looking to make modifications.\n\n- [reMouseable Design Documentation](#remouseable-design-documentation)\n\t- [Overview](#overview)\n\t- [The Tablet](#the-tablet)\n\t- [The Iterator](#the-iterator)\n\t\t- [Iterator Interface](#iterator-interface)\n\t\t- [EvDev](#evdev)\n\t\t- [Bulk Event Filtering](#bulk-event-filtering)\n\t- [The State Machine](#the-state-machine)\n\t\t- [State Machine Interface](#state-machine-interface)\n\t\t- [Interpreting Hardware Events](#interpreting-hardware-events)\n\t- [The Position Scaler](#the-position-scaler)\n\t\t- [Default Height And Width Of A Tablet](#default-height-and-width-of-a-tablet)\n\t\t- [Matching Orientation Example](#matching-orientation-example)\n\t- [The Driver](#the-driver)\n\t\t- [The Driver Interface](#the-driver-interface)\n\t\t- [RobotGo And Mouse Controls](#robotgo-and-mouse-controls)\n\t- [The Runtime](#the-runtime)\n\t- [Ideas For Modifications](#ideas-for-modifications)\n\t\t- [Modifying SSH Access To Tablet](#modifying-ssh-access-to-tablet)\n\t\t- [Loading Hardware Events From Non-Tablet Sources](#loading-hardware-events-from-non-tablet-sources)\n\t\t- [Monitor Selection](#monitor-selection)\n\t\t- [Supporting More Than Left Click](#supporting-more-than-left-click)\n\t\t- [Supporting Non-Mouse Key Presses](#supporting-non-mouse-key-presses)\n\t\t- [Adding New Pen Buttons Or Features](#adding-new-pen-buttons-or-features)\n\t\t- [Full Wacom Support](#full-wacom-support)\n\n## Overview\n\n![reference static-assets/diagrams.puml section \"remouseable_overview\" for diagram source](static-assets/remouseable_overview.png \"reMouseable Overview\")\n\nreMouseable uses SSH to connect to a tablet and copy over hardware events. The\nhardware events are then translated into operating system specific commands that\nmove and operate the mouse.\n\n![reference static-assets/diagrams.puml section \"remouseable_internal\" for diagram source](static-assets/remouseable_internal.png \"reMousable Internals\")\n\nWithin the reMouseable code are several components: the iterator, the state\nmachine, the position scaler, the driver, and the runtime. Each has a\nspecialized purpose and design that is detailed below. Each can be modified or\nre-implemented to get new or different behaviours from reMouseable.\n\n## The Tablet\n\n(As of 2021-12-01) There are two versions of the reMarkable tablet available:\nthe reMarkable v1 and reMarkable v2. The hardware configurations are slightly\ndifferent between versions but the underlying software that is relevant to\nreMouseable is virtually identical across versions.\n\nDespite the specialized purpose for which reMarkable tablets are built and used,\neach tablet is a general purpose computing device running a Linux operating\nsystem which makes them quite \"hackable\". The tablets run a custom Linux\ndistribution called \"Codex\" and the source code is available at\n<https://github.com/reMarkable/linux>. Each tablet ships with SSH support and\nthe root password is available in the \"about\" section of the tablet interface.\n\nreMouseable works by connecting to the tablet over SSH and copying over the\ncontents of a special kind of file that produces hardware events. This means\nthat reMousable does not need to modify any part of the tablet system and only\ncopies data from the tablet to the target machine in order to then process the\nhardware data.\n\n## The Iterator\n\nThe first and \"lowest level\" component in the reMouseable design is the EvDev\nIterator. This component is responsible for sourcing hardware events and\npresenting them as an infinite stream that can be processed by the rest of the\nreMouseable system. When running reMouseable from the pre-compiled binaries, the\nEvDev iterator is the only component that directly interacts with the reMarkable\ntablet (or other Linux device).\n\n### Iterator Interface\n\n```golang\ntype EvdevIterator interface {\n\t// Next progresses the iterator. It returns false when there are no more\n\t// elements to iterate or when the iterator encountered an error.\n\tNext() bool\n\t// Current returns the active element of the iterator. This should only be\n\t// called if Next() returned a true.\n\tCurrent() EvdevEvent\n\t// Close must be called before discarding the iterator. If the iterator\n\t// exited cleanly then the error is nil. The error is non-nil if either the\n\t// iterator encountered an internal error and stopped early or if it failed\n\t// to close.\n\tClose() error\n}\n```\n\nImplementations of this interface provide the system with an infinite stream\nof Linux hardware events. These hardware events are common across all Linux\nsystems and not specific to the reMarkable tablet. The events produced by the\niterator match this structure:\n\n```golang\ntype EvdevEvent struct {\n\t// Time of the event\n\tTime time.Time\n\t// Type identifies the category of event.\n\tType uint16\n\t// Code identifies a specific kind of event within a category.\n\tCode uint16\n\t// Numeric value of the event. Dependent on the event type.\n\tValue int32\n}\n```\n\nThe default implementation of this, available in `pkg/evdeviterator.go`,\nconsumes raw binary data from a readable stream and parses the binary into the\nevent structure. The input stream is always set to an EvDev character device\nwhen running the pre-compiled binaries.\n\n### EvDev\n\n[EvDev](https://en.wikipedia.org/wiki/Evdev) stands for \"event device\" and is\na Linux feature that allows userspace applications to read and write input\nevents that are typically generated by hardware input devices such as a keyboard\nor mouse.\n\nThe `Type` and `Code` values of the `EvdevEvent` from the previous section must\nmap to values from the EvDev symbol tables. These tables are maintained in `C`\ncode files that are accessible on Linux systems. In addition to a running Linux\nmachine, the\n[input.h](https://github.com/torvalds/linux/blob/master/include/uapi/linux/input.h)\nand\n[input-event-codes.h](https://github.com/torvalds/linux/blob/master/include/uapi/linux/input-event-codes.h)\nthat contain the symbol tables are also available in the Linux source tree.\n\nThe reMouseable project generates Go representations of all EvDev symbols by\nreading and parsing the Linux header files. The `pkg/internal/gencodes/main.go`\nimplements the header file parsing and Go code generation. The process generates\na file at `pkg/evdevcodes.go` which contains a full copy of all the EvDev types\nand codes but as Go constant values that can be imported and referenced by other\nGo code.\n\n### Bulk Event Filtering\n\nThere are a lot of EvDev events that come through when monitoring the pen's\ncharacter device files (usually at `/dev/input/event0` or `/dev/input/event1`).\nMost of those events are irrelevant and can cause latency between the tablet\nand computer if emitted from the iterator. To help cut down on noise and latency\nthere is an included wrapper for EvDev iterator implementations in `pkg/evdeviterator.go`\ncalled `SelectingEvdevIterator`. It can wrap any implementation and filter out\nirrelevant event categories. The pre-compiled binaries use this feature to drop\nall events other than those in the `EV_ABS` category which is discussed in more\ndetail with the state machine component.\n\n## The State Machine\n\nThe second component in the reMouseable design is a state machine that consumes\nthe hardware event stream and converts those events into system state changes.\nThis component abstracts the raw, hardware events from the rest of the system\nby converting sequences of hardware events into higher level system events.\n\n### State Machine Interface\n\n```golang\ntype StateMachine interface {\n\t// Next progresses the iterator. It returns false when there are no more\n\t// elements to iterate or when the iterator encountered an error.\n\tNext() bool\n\t// Current returns the active element of the iterator. This should only be\n\t// called if Next() returned a true.\n\tCurrent() StateChange\n\t// Close must be called before discarding the iterator. If the iterator\n\t// exited cleanly then the error is nil. The error is non-nil if either the\n\t// iterator encountered an internal error and stopped early or if it failed\n\t// to close.\n\tClose() error\n}\n```\n\nImplementations of this interface provide the system with an infinite stream\nof system state changes. These state changes are not specific to any given\noperating system or hardware configuration. State change records emitted by\nthe state machine iterator match this interface:\n\n```golang\ntype StateChange interface {\n\tType() string\n}\n```\n\nEach implementation of the `StateChange` interface represents a single state\nand can contain additional metadata beyond the name. For example, a change in\nthe mouse position is signaled by emitting and instance of:\n\n```golang\n// StateChangeMove contains mouse movement data.\ntype StateChangeMove struct {\n\tX int\n\tY int\n}\n\n// Type returns the specific change type.\nfunc (*StateChangeMove) Type() string {\n\treturn ChangeTypeMove\n}\n```\n\nConsumers are expected to switch on the event type, unwrap the relevant struct\nfrom the interface, and interpret the state and metadata. For example:\n\n```golang\ns := state.Current()\nswitch s.Type() {\ncase remouseable.ChangetypeMove:\n    change := s.(*remouseable.StateChangeMove)\n    fmt.Println(change.X, change.Y)\n// ...\n}\n```\n\n### Interpreting Hardware Events\n\nThe default implementation of the state machine interface that is used in the\npre-compiled binaries consumes and interprets the output of an EvDev iterator.\n\nThere are hundreds of EvDev event codes and dozens of event categories. Only a\nsubset of these are relevant to reMouseable. Specifically, the system only needs\nto process events related to pen position in order to mirror that behavior in a\nmouse. From an EvDev perspective, reMouseable processes events related to\nabsolute values which are in the category of `EV_ABS`. Within that category,\nthere are three significant codes: `ABS_X`, `ABS_Y`, and `ABS_PRESSURE`. The\nX and Y values indicate the X and Y coordinates of the pen with `(0,0)` being\nthe bottom left-hand corner of the tablet when held vertically with the buttons\nat the bottom. The pressure value indicates how close the pen is to the surface.\n\nPressure is a bit of a misnamed code because it can have a positive value\n_before_ the pen touches the tablet. This allows the state machine to emit\n\"move\" events even if the pen is not actively touching the tablet which allows\nfor a user to preview the mouse position before drawing. A pressure value of\n`1000` is considered to indicate the pen is touching the tablet. Any value\ngreater means the pen is pressing into the tablet harder. Any value lesser means\nthe pen is hovering above the surface of the tablet. Damaged pens or tips may\nreport unpredictable values for pressure. A clear sign of this is a pen that\ndraws marks on the tablet without touching the surface.\n\n## The Position Scaler\n\nThe position scaler maps coordinates from the tablet screen to coordinates on\nthe target screen.\n\nThe default state machine processes the `ABS_X` and `ABS_Y` hardware events\nwhich provide the pen position a relative to the `(0,0)` origin. Coordinate\npositions on a tablet, though, don't necessarily translate to coordinate\npositions on the target screen because they usually have different physical\nsizes, resolutions, and potentially different orientations. A position scaler\ncomputes new coordinates for a target screen based on the tablet coordinates.\n\nThe default set of position scalers are in `pkg/positionscaler.go`. The\ninterface they implement is:\n\n```golang\ntype PositionScaler interface {\n\tScalePosition(x int, y int) (int, int)\n}\n```\n\nThe default scalers implement the interface by calculating the proportional\nsize difference of the screens and then applying that proportion to the\nabsolute `(X,Y)` coordinates from the tablet. From there, some scalers\noptionally apply a translation to account for the difference in orientation\nof the screens.\n\n### Default Height And Width Of A Tablet\n\nTarget monitors report their own maximum X and Y values that are discovered\nwhen starting reMouseable. The tablet, however, is not probed for size to keep\nthe interaction with the tablet OS as simple as possible. Instead, I found the\napproximate maximum X and Y values for the tablet by printing EvDev `ABS_X` and\n`ABS_Y` events out while drawing a line diagonally from the origin to the\nopposite corner. I did this several times and captured the maximum values. The\napproximate values are:\n\n```\nmax_x = 15725\nmax_y = 20967\n```\n\nThese values are likely not the _true_ maximum but are close enough that the\nsystem operates as expected when scaled to a new screen.\n\n### Matching Orientation Example\n\nTo illustrate scaling, let's consider two rectangular screens that are oriented\nsuch that they are wider than they are tall. This is the most common screen\norientation for personal computers (wide screen) and is often the most common\norientation of the tablet because it matches the target screen.\n\n![illustration of two screens with the same orientation](static-assets/tablet-monitor-combined-grid.png)\n\nThe `(0,0)` origin of both screens is at the upper left-hand corner. However,\nthe two screens have different resolutions which means they can address a\ndifferent number of coordinates within their range. For this example, let's\nassume the tablet is 100x200 and the monitor is 1000x2000. These are not the\ntrue resolutions of either device but it makes the math a little easier to\nfollow.\n\nA position scaler first determines the proportional height and width difference\nbetween the screens:\n\n```\nheight_tablet = 100\nwidth_tablet = 200\nheight_monitor = 1000\nwidth_monitor = 2000\n\nscale_x = height_monitor / height_tablet = 10\nscale_y = width_monitor / width_tablet = 10\n```\n\nThis proportion, or ratio, is used to convert X and Y coordinates from the\ntablet to X and Y coordinates on the monitor by multiplying tablet coordinates\nwith the scale. That is, a tablet coordinate of `(15,20)` is multiplied by\n`(10,10)` to compute `(150,200)` as the appropriate position on the monitor. At\nthis scale, the mouse moves 10 times the number of points in any direction on\nthe monitor compared to the tablet.\n\nThis same scaling algorithm works when the tablet is at a higher resolution than\nthe monitor. See the `pgk/positionscaler.go` for documented variations of this\nscaling algorithm that account for different orientations of the tablet.\n\n## The Driver\n\nThe driver component manipulates the mouse of the host system. It is called\nby the runtime when the state machine emits a change.\n\n### The Driver Interface\n\n```golang\ntype Driver interface {\n\tMoveMouse(x int, y int) error\n\tDragMouse(x int, y int) error\n\tClick() error\n\tUnclick() error\n\tGetSize() (width int, height int, err error)\n}\n```\n\nThe driver interface is intended to abstract the operating system methods needed\nto run `remouseable`. It is currently limited to operating a mouse and detecting\nthe size of the host display.\n\n### RobotGo And Mouse Controls\n\nThe current implementation of the driver is based on another project called\n[robotgo](https://github.com/go-vgo/robotgo). `robotgo` is a collection of `C`\ncode that interfaces with operating system specific libraries for controlling\nthings like a mouse, keyboard, and display. The `C` code is wrapped in `Go` code\nso that the operating system can be called by classes and methods in `Go`.\n\nIn order to limit the system and `C` dependencies required to build\n`remouseable` I've embedded a portion of `robotgo` in the `pkg/internal/robotgo`\ndirectory. In there, I've copied just enough to detect screen size and operate\na mouse. The `robotgo` project supports many more operating system features but\nthey require additional dependencies to build.\n\n## The Runtime\n\nThe runtime component is the logic that brings together the state machine,\nposition scaler, and driver to create the `remouseable` experience. The main\nimplementation is available in `pkg/runtime.go`. It implements a similar\ncall pattern to the EvDev and state machine iterators. It is configured and\niterated over in the `main.go` at the root of the repository.\n\n## Ideas For Modifications\n\nModifying `remouseable` behavior comes with varying levels of difficulty\ndepending on which of the behaviors you want to change. \n\n### Modifying SSH Access To Tablet\n\nLines 53 - 103 in `main.go` handle the SSH configuration and actual connection\nto the tablet. If a password is given then it configures SSH using password\nauthentication. If no password is given then it attempts to call an SSH agent\nrunning on the host. The assumption is that the SSH agent is configured with any\nprivate keys that can be used to connect to the tablet.\n\nThere is no built-in support for using SSH keys without an SSH agent. However,\nsupport for connecting using arbitrary keys could be added by modifying\n`main.go`. My recommended approach for this is to first add a new CLI flag to\nthe set on lines 36 - 51 in `main.go` that will identify your key, such as\n`--ssh-key`. Then add a new branch in the 53 - 103 range of lines that detects a\nvalue for your new flag and will reconfigured the SSH client. Then use the\nexample from <https://pkg.go.dev/golang.org/x/crypto/ssh#example-PublicKeys> to\nimplement loading and using your private key.\n\nOther SSH related changes can be made similarly.\n\n### Loading Hardware Events From Non-Tablet Sources\n\nOne of the mistakes I made in the app is that generating the `io.Reader` of\nhardware events that the [EvDev iterator](#evdev) needs is done in `main.go`\nand without any kind of interface or factory that could be easily replaced.\nIt's locked into generating the `io.Reader` from the `STDOUT` of an SSH\nconnection that is running `cat` on the EvDev file.\n\nOne way to add support for alternative EvDev sources is to add more branches to\nthe `main.go` code that override the SSH connection behavior. Lines 86 - 103\nare the ones that establish the SSH connection and generate the `io.Reader` as\na variable called `pipe`:\n\n```golang\nclient, err := ssh.Dial(\"tcp\", *sshIP, sshConfig)\nif err != nil {\n\tpanic(err)\n}\n\nsesh, err := client.NewSession()\nif err != nil {\n\tpanic(err)\n}\ndefer sesh.Close()\n\npipe, err := sesh.StdoutPipe()\nif err != nil {\n\tpanic(err)\n}\nif err = sesh.Start(fmt.Sprintf(\"cat %s\", *evtFile)); err != nil {\n\tpanic(err)\n}\n```\n\nThese lines execute on every run of the app because they are not in a branch.\nIf you want to add alternative hardware event sources, such as a static file,\nthen you must wrap these lines in a branch of some kind that allows your\nalternative source to override them. For example:\n\n```golang\nvar eventSource io.ReadCloser\nif *evdevFile != \"\" {\n\t// assuming evdevFile is a flag containing the path to the static file\n\tf, err := os.Open(*evdevFile)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer f.Close()\n\teventSource = f\n}\nif eventSource == nil {\n\t// default to SSH\n}\nit := &remouseable.SelectingEvdevIterator{\n\tWrapped: &remouseable.FileEvdevIterator{\n\t\tSource: eventSource,\n\t},\n\tSelection: []uint16{remouseable.EV_ABS},\n}\ndefer it.Close()\n```\n\nIf you want to support multiple, new sources of EvDev data then I'd recommend\ncreating some kind of interface for the constructor, or factory, of the\n`io.Reader` so that the logic can be better tested rather than existing only\nin the `main.go` file which has no real tests of its own.\n\n### Monitor Selection\n\nThe monitor related portions of `robotgo` embedded in the project query the\noperating system for the size of the screen. Operating systems all respond to\nthat query with a single size that represents _all_ connected monitors combined.\nThe result is that multi-monitor users must manually specify the size of their\nmain monitor using the `--screen-height` and `--screen-width` flags. Even using\nthose flags, though, multi-monitor users cannot specify which monitor to use\nbecause the system is locked into using whatever the operating system considers\nmonitor 0 as the origin point.\n\nThe <https://github.com/Evidlo/remarkable_mouse> project has a strong advantage\nhere because the Python bindings for those same operating system calls are more\nmature and offer more features. Specifically, the Python project uses\n<https://github.com/rr-/screeninfo> to detect and select specific screens\ninstead of using one, large, combined screen. The most complete way to support\nmulti-monitor setups is to port the Python code that [generates lists of\nmonitors](https://github.com/rr-/screeninfo/blob/master/screeninfo/enumerators/windows.py)\nto C so that this project can use it.\n\nA possible alternative to this, [suggested by a\ncontributor](https://github.com/kevinconway/remouseable/issues/23), is to\nprovide manual selection of monitors by having the user input the correct\ncoordinate offsets so that `(0,0)` can be adjusted to the appropriate point in\nthe selected monitor. This could be done with a custom `PositionScaler` such as:\n\n```golang\ntype OffsetPositionScaler struct {\n\tWrapped PositionScaler\n\tOffsetX int\n\tOffsetY int\n}\nfunc (s *OffsetPositionScaler)  ScalePosition(x int, y int) (int, int) {\n  x, y = s.Wrapped.ScalePosition(x, y)\n  return x+s.OffsetX, y+s.OffsetY\n}\n```\n\nThis, in conjunction with the `--screen-height` and `--screen-width` options,\nshould correctly calculate the point position within the target monitor and then\nshift it so that the new point is relative to the origin in the target monitor\nrather than the combined monitors.\n\n### Supporting More Than Left Click\n\nOne of the mistakes I made in designing the driver and the `Click`/`Unclick`\nstate machine events is that they both assume that only the primary, or left,\nmouse button may be pressed. The underlying `robotgo` code supports left, right,\nand center mouse buttons but those features are not exposed anywhere in the\n`remouseable` code. If I were to rebuild `remouseable` then I'd most likely\nrefactor the code like:\n\n```golang\n// InputKey is an identifier for a system input. This is usually a hardware\n// button of some kind.\ntype InputKey string\n\nconst (\n\tMouseLeft InputKey = \"left\"\n\tMouseRight InputKey = \"right\"\n\tMouseCenter InputKey = \"center\"\n)\n\n// StateChangePress replaces StateChangeClick so that it can identify\n// more than just left click.\ntype StateChangePress struct{\n\tKey InputKey\n}\n\n// StateChangeRelease replaces StateChangeUnclick.\ntype StateChangeRelease struct{\n\tKey InputKey\n}\n\ntype Driver interface {\n\tMoveMouse(x int, y int) error\n\tDragMouse(x int, y int) error\n\tPress(InputKey) error\n\tRelease(InputKey) error\n\tGetSize() (width int, height int, err error)\n}\n```\n\nThis would add support for pressing more mouse buttons and add the space to\nexpand into non-mouse keys.\n\n### Supporting Non-Mouse Key Presses\n\nAssuming you implement something like the above to expand the available buttons\nthat can be pressed then there's an option to add non-mouse keys such as\nkeyboard keys. Unfortunately, this requires more effort than just mouse events\nbecause it requires copying over and potentially modifying the [keyboard support\nfrom robotgo](https://github.com/go-vgo/robotgo/tree/master/key).\n\nThe bulk of the work is in porting the `robotgo` feature. Beyond that, new keys\nwould become new entries in the `InputKey` enumeration:\n\n```golang\ntype InputKey string\n\nconst (\n\tMouseLeft InputKey = \"left\"\n\tMouseRight InputKey = \"right\"\n\tMouseCenter InputKey = \"center\"\n\tKeyboardE InputKey = \"e\"\n\tKeyboardRightShift InputKey = \"right_shift\"\n)\n```\n\nand the driver would be responsible for switching between the mouse and keyboard\ndevices on the host:\n\n```golang\nfunc (*RobotgoDriver) Press(k InputKey) error {\n\tswitch k {\n\tcase MouseLeft, MouseRight, MouseCenter:\n\t\trobotgo.MouseToggle(\"down\", string(k))\n\tdefault:\n\t\trobotgo.KeyToggle(string(k), \"down\")\n\t}\n\treturn nil\n}\n\nfunc (*RobotgoDriver) Release(k InputKey) error {\n\tswitch k {\n\tcase MouseLeft, MouseRight, MouseCenter:\n\t\trobotgo.MouseToggle(\"up\", string(k))\n\tdefault:\n\t\trobotgo.KeyToggle(string(k), \"up\")\n\t}\n\treturn nil\n}\n```\n\n### Adding New Pen Buttons Or Features\n\nThe Remarkable 2 shipped with an optional pen that includes an eraser button.\nLikewise, there are several 3rd party pens that offer erasers or other extra\nbuttons. As is, `remouseable` does not support any buttons other than the\nwriting tip of the pen. However, [a contributor figured out how the eraser\nhardware events work and outlined how to add support in a\nPR](https://github.com/kevinconway/remouseable/pull/26/files).\n\nThe general process of adding a new pen feature is:\n\n- Identify the associated hardware code\n- Determine if pressure is significant to the feature\n- Add handling of the new hardware codes to the state machine\n\nFor example, [tominator1pl](https://github.com/tominator1pl) found that the\nhardware event code for the eraser button being pressed on the official\nRemarkable 2 markers is `BTN_TOOL_RUBBER`, or `0x141`, and that another key code\n`BTN_TOOL_PEN`, or `0x140` is emitted when the eraser is lifted. Assuming that\npressure is not important and that a similar set of changes as suggested above have been made to the\ndriver and state machine then the new codes would be used like:\n\n```golang\nfunc (it *EvdevStateMachine) next(raw EvdevEvent) bool {\n\tif raw.Type == EV_KEY {\n\t\tswitch raw.Code {\n\t\tcase BTN_TOOL_RUBBER:\n\t\t\tit.clicked = true\n\t\t\tit.current = &StateChangePress{Key: MouseRight}\n\t\t\treturn true\n\t\tcase BTN_TOOL_PEN:\n\t\t\tit.clicked = false\n\t\t\tit.current = &StateChangeRelease{Key: MouseRight}\n\t\t\treturn true\n\t\t}\n\t}\n\t// ...\n```\n\nNote that pressure may be important for this feature and _is_ used in\ntominator1pl's fork where this feature is already implemented.\n\n### Full Wacom Support\n\nThe tablet hardware events include things like pressure and tilt that map to the\nsame events from Wacom style tablets. Unfortunately, pressure sensitivity and\ntilt are difficult to implement as `remouseable` features.\n\nToday, the tool works by consuming a stream of pen events from the Linux system\non the tablet and translating some of them into mouse events on the computer.\nEach operating system has a different interface and different set of libraries\nthat must be used to control the mouse. This project embeds some C code, copied\nfrom <https://github.com/go-vgo/robotgo>, that handles the OS specific mouse\noperations. Click, release, move, and drag are the only mouse operations that\nmap to pen movement so it's not much code needed to support Windows, OSX, and\nLinux together. The limitation with this method is that the tool can only do\nwhat the mouse does and a mouse doesn't have tilt or pressure features.\n\nTo act as a full tablet interface to the host machine, the `remouseable` app\nwould need to communicate with the operating system as a wacom style device\nrather than a mouse. Even though the remarkable tablet is doing exactly this\ninternally, it's not easy or simple to mirror a tablet device across computers.\nI've researched this idea a bit to see how it might be done and my best guess is\nthat it is only made possible by implementing a custom device driver for each\nOS. That device driver would need to translate the Linux device events from the\nremarkable into OS specific hardware events that match up with that OS's\nexpectations for a pen or wacom style tablet.\n\nIf you're using Linux then the Linux to Linux translation is possible.\n<https://github.com/Evidlo/remarkable_mouse> is a Python project that works\nalmost identically to this one but also supports the full pen feature set on\nLinux when you use the `--evdev` flag. They're able to accomplish this because\nthere is an open source Python module for creating Linux device drivers and the\nLinux device events coming from the remarkable are exactly the same ones the\ndriver needs to emit. There is no equivalent Go module for creating Linux device\ndrivers which is why `remouseable` doesn't already have this feature. To\nimplement this in `remouseable`, you would need to port the relevant Python code\nto Go. Note that <https://github.com/gvalkov/golang-evdev> exists and was used\nfor this project but it only supports reading from devices. It cannot create or\nwrite to them. This is the feature that must be ported from the Python EvDev\nlibrary.\n\nThere may be an easier way to accomplish full tablet usage but this is all the\ninformation I've been able to find and learn on the subject. Here are some links\nto operating system specific information about device drivers, virtual devices,\nand tablet controls that might be useful to anyone implementing this feature:\n\n- Resources for Windows\n  - https://docs.microsoft.com/en-us/windows-hardware/design/component-guidelines/legacy-touchscreen-and-pen-resources\n  - https://docs.microsoft.com/en-us/windows-hardware/design/component-guidelines/pen-devices\n  - https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/\n\n- Resources for OSX\n  - https://developer.apple.com/documentation/driverkit/creating_a_driver_using_the_driverkit_sdk\n\n- Resources for Linux\n  - https://github.com/Evidlo/remarkable_mouse/blob/master/remarkable_mouse/evdev.py\n  - https://github.com/gvalkov/python-evdev\n\n- Resources for cross platform\n  - https://github.com/OpenTabletDriver/OpenTabletDriver\n\n"
  },
  {
    "path": "technical-documentation/static-assets/diagrams.puml",
    "content": "@startuml remouseable_overview\n\nnode \"reMarkable Tablet\" as tablet {\n    folder \"Linux\" as linux {\n        component \"EvDev\" as evdev_source\n        component \"SSH Agent\" as tablet_ssh\n    }\n}\n\ncloud \"Network\" as network\n\nnode \"Personal Computer\" as pc {\n    folder \"Operating System\" as pc_os {\n        component \"SSH Agent\" as pc_ssh\n        component \"reMouseable\" as remouseable\n        component \"Virtual Mouse\" as mouse\n    }\n}\n\nremouseable --> pc_ssh\npc_ssh -> network\nnetwork -> tablet_ssh\ntablet_ssh --> evdev_source\nremouseable -left-> mouse\n\n@enduml\n\n@startuml remouseable_internal\n\nnode \"reMouseable\" as remouseable {\n    component \"Runtime\" as runtime\n    component \"Coordinate Scaler\" as scaler\n    component \"EvDev Iterator\" as iterator\n    component \"State Machine\" as state\n    component \"Driver\" as driver\n}\n\niterator -up-> state\nruntime --> state\nruntime --> scaler\nruntime --> driver\n\nnote bottom of iterator\n    Produce a stream of hardware events.\n    Generally, this is sourced from\n    EvDev on the tablet.\nendnote\n\nnote bottom of state\n    Convert low level hardware events\n    into state changes. For example,\n    converts pen touching the tablet into\n    a \"click\" event.\nendnote\n\nnote left of driver\n    Issues system specific commands to\n    move or operate the mouse.\nendnote\n\nnote top of scaler\n    Convert tablet X,Y coordinates into\n    X,Y coordinates of a different\n    screen.\nendnote\n\nnote top of runtime\n    Coordinate between the state machine,\n    scaler, and driver.\nendnote\n\n@enduml\n"
  },
  {
    "path": "tools/go.mod",
    "content": "module github.com/kevinconway/remouseable/tools\n\ngo 1.22.1\n\ntoolchain go1.23.1\n\nrequire (\n\tgithub.com/AlekSi/gocov-xml v1.1.0\n\tgithub.com/axw/gocov v1.1.0\n\tgithub.com/golang/mock v1.6.0\n\tgithub.com/golangci/golangci-lint v1.61.0\n\tgithub.com/matm/gocov-html v0.0.0-20200509184451-71874e2e203b\n\tgithub.com/wadey/gocovmerge v0.0.0-20160331181800-b5bfa59ec0ad\n\tgolang.org/x/tools v0.25.0\n)\n\nrequire (\n\t4d63.com/gocheckcompilerdirectives v1.2.1 // indirect\n\t4d63.com/gochecknoglobals v0.2.1 // indirect\n\tbitbucket.org/creachadair/shell v0.0.6 // indirect\n\tcel.dev/expr v0.16.0 // indirect\n\tcloud.google.com/go v0.115.1 // indirect\n\tcloud.google.com/go/accessapproval v1.8.0 // indirect\n\tcloud.google.com/go/accesscontextmanager v1.9.0 // indirect\n\tcloud.google.com/go/ai v0.8.0 // indirect\n\tcloud.google.com/go/aiplatform v1.68.0 // indirect\n\tcloud.google.com/go/analytics v0.25.0 // indirect\n\tcloud.google.com/go/apigateway v1.7.0 // indirect\n\tcloud.google.com/go/apigeeconnect v1.7.0 // indirect\n\tcloud.google.com/go/apigeeregistry v0.9.0 // indirect\n\tcloud.google.com/go/apikeys v0.6.0 // indirect\n\tcloud.google.com/go/appengine v1.9.0 // indirect\n\tcloud.google.com/go/area120 v0.9.0 // indirect\n\tcloud.google.com/go/artifactregistry v1.15.0 // indirect\n\tcloud.google.com/go/asset v1.20.0 // indirect\n\tcloud.google.com/go/assuredworkloads v1.12.0 // indirect\n\tcloud.google.com/go/auth v0.9.3 // indirect\n\tcloud.google.com/go/auth/oauth2adapt v0.2.4 // indirect\n\tcloud.google.com/go/automl v1.14.0 // indirect\n\tcloud.google.com/go/baremetalsolution v1.3.0 // indirect\n\tcloud.google.com/go/batch v1.10.0 // indirect\n\tcloud.google.com/go/beyondcorp v1.1.0 // indirect\n\tcloud.google.com/go/bigquery v1.62.0 // indirect\n\tcloud.google.com/go/bigtable v1.31.0 // indirect\n\tcloud.google.com/go/billing v1.19.0 // indirect\n\tcloud.google.com/go/binaryauthorization v1.9.0 // indirect\n\tcloud.google.com/go/certificatemanager v1.9.0 // indirect\n\tcloud.google.com/go/channel v1.18.0 // indirect\n\tcloud.google.com/go/cloudbuild v1.17.0 // indirect\n\tcloud.google.com/go/clouddms v1.8.0 // indirect\n\tcloud.google.com/go/cloudtasks v1.13.0 // indirect\n\tcloud.google.com/go/compute v1.28.0 // indirect\n\tcloud.google.com/go/compute/metadata v0.5.0 // indirect\n\tcloud.google.com/go/contactcenterinsights v1.14.0 // indirect\n\tcloud.google.com/go/container v1.39.0 // indirect\n\tcloud.google.com/go/containeranalysis v0.13.0 // indirect\n\tcloud.google.com/go/datacatalog v1.22.0 // indirect\n\tcloud.google.com/go/dataflow v0.10.0 // indirect\n\tcloud.google.com/go/dataform v0.10.0 // indirect\n\tcloud.google.com/go/datafusion v1.8.0 // indirect\n\tcloud.google.com/go/datalabeling v0.9.0 // indirect\n\tcloud.google.com/go/dataplex v1.19.0 // indirect\n\tcloud.google.com/go/dataproc v1.12.0 // indirect\n\tcloud.google.com/go/dataproc/v2 v2.6.0 // indirect\n\tcloud.google.com/go/dataqna v0.9.0 // indirect\n\tcloud.google.com/go/datastore v1.19.0 // indirect\n\tcloud.google.com/go/datastream v1.11.0 // indirect\n\tcloud.google.com/go/deploy v1.22.0 // indirect\n\tcloud.google.com/go/dialogflow v1.57.0 // indirect\n\tcloud.google.com/go/dlp v1.18.0 // indirect\n\tcloud.google.com/go/documentai v1.33.0 // indirect\n\tcloud.google.com/go/domains v0.10.0 // indirect\n\tcloud.google.com/go/edgecontainer v1.3.0 // indirect\n\tcloud.google.com/go/errorreporting v0.3.1 // indirect\n\tcloud.google.com/go/essentialcontacts v1.7.0 // indirect\n\tcloud.google.com/go/eventarc v1.14.0 // indirect\n\tcloud.google.com/go/filestore v1.9.0 // indirect\n\tcloud.google.com/go/firestore v1.16.0 // indirect\n\tcloud.google.com/go/functions v1.19.0 // indirect\n\tcloud.google.com/go/gaming v1.10.1 // indirect\n\tcloud.google.com/go/gkebackup v1.6.0 // indirect\n\tcloud.google.com/go/gkeconnect v0.11.0 // indirect\n\tcloud.google.com/go/gkehub v0.15.0 // indirect\n\tcloud.google.com/go/gkemulticloud v1.3.0 // indirect\n\tcloud.google.com/go/grafeas v0.3.10 // indirect\n\tcloud.google.com/go/gsuiteaddons v1.7.0 // indirect\n\tcloud.google.com/go/iam v1.2.0 // indirect\n\tcloud.google.com/go/iap v1.10.0 // indirect\n\tcloud.google.com/go/ids v1.5.0 // indirect\n\tcloud.google.com/go/iot v1.8.0 // indirect\n\tcloud.google.com/go/kms v1.19.0 // indirect\n\tcloud.google.com/go/language v1.14.0 // indirect\n\tcloud.google.com/go/lifesciences v0.10.0 // indirect\n\tcloud.google.com/go/logging v1.11.0 // indirect\n\tcloud.google.com/go/longrunning v0.6.0 // indirect\n\tcloud.google.com/go/managedidentities v1.7.0 // indirect\n\tcloud.google.com/go/maps v1.12.0 // indirect\n\tcloud.google.com/go/mediatranslation v0.9.0 // indirect\n\tcloud.google.com/go/memcache v1.11.0 // indirect\n\tcloud.google.com/go/metastore v1.14.0 // indirect\n\tcloud.google.com/go/monitoring v1.21.0 // indirect\n\tcloud.google.com/go/networkconnectivity v1.15.0 // indirect\n\tcloud.google.com/go/networkmanagement v1.14.0 // indirect\n\tcloud.google.com/go/networksecurity v0.10.0 // indirect\n\tcloud.google.com/go/notebooks v1.12.0 // indirect\n\tcloud.google.com/go/optimization v1.7.0 // indirect\n\tcloud.google.com/go/orchestration v1.10.0 // indirect\n\tcloud.google.com/go/orgpolicy v1.13.0 // indirect\n\tcloud.google.com/go/osconfig v1.14.0 // indirect\n\tcloud.google.com/go/oslogin v1.14.0 // indirect\n\tcloud.google.com/go/phishingprotection v0.9.0 // indirect\n\tcloud.google.com/go/policytroubleshooter v1.11.0 // indirect\n\tcloud.google.com/go/privatecatalog v0.10.0 // indirect\n\tcloud.google.com/go/pubsub v1.42.0 // indirect\n\tcloud.google.com/go/pubsublite v1.8.2 // indirect\n\tcloud.google.com/go/recaptchaenterprise v1.3.1 // indirect\n\tcloud.google.com/go/recaptchaenterprise/v2 v2.17.0 // indirect\n\tcloud.google.com/go/recommendationengine v0.9.0 // indirect\n\tcloud.google.com/go/recommender v1.13.0 // indirect\n\tcloud.google.com/go/redis v1.17.0 // indirect\n\tcloud.google.com/go/resourcemanager v1.10.0 // indirect\n\tcloud.google.com/go/resourcesettings v1.8.0 // indirect\n\tcloud.google.com/go/retail v1.18.0 // indirect\n\tcloud.google.com/go/run v1.5.0 // indirect\n\tcloud.google.com/go/scheduler v1.11.0 // indirect\n\tcloud.google.com/go/secretmanager v1.14.0 // indirect\n\tcloud.google.com/go/security v1.18.0 // indirect\n\tcloud.google.com/go/securitycenter v1.35.0 // indirect\n\tcloud.google.com/go/servicecontrol v1.11.1 // indirect\n\tcloud.google.com/go/servicedirectory v1.12.0 // indirect\n\tcloud.google.com/go/servicemanagement v1.8.0 // indirect\n\tcloud.google.com/go/serviceusage v1.6.0 // indirect\n\tcloud.google.com/go/shell v1.8.0 // indirect\n\tcloud.google.com/go/spanner v1.67.0 // indirect\n\tcloud.google.com/go/speech v1.25.0 // indirect\n\tcloud.google.com/go/storage v1.43.0 // indirect\n\tcloud.google.com/go/storagetransfer v1.11.0 // indirect\n\tcloud.google.com/go/talent v1.7.0 // indirect\n\tcloud.google.com/go/texttospeech v1.8.0 // indirect\n\tcloud.google.com/go/tpu v1.7.0 // indirect\n\tcloud.google.com/go/trace v1.11.0 // indirect\n\tcloud.google.com/go/translate v1.12.0 // indirect\n\tcloud.google.com/go/video v1.23.0 // indirect\n\tcloud.google.com/go/videointelligence v1.12.0 // indirect\n\tcloud.google.com/go/vision v1.2.0 // indirect\n\tcloud.google.com/go/vision/v2 v2.9.0 // indirect\n\tcloud.google.com/go/vmmigration v1.8.0 // indirect\n\tcloud.google.com/go/vmwareengine v1.3.0 // indirect\n\tcloud.google.com/go/vpcaccess v1.8.0 // indirect\n\tcloud.google.com/go/webrisk v1.10.0 // indirect\n\tcloud.google.com/go/websecurityscanner v1.7.0 // indirect\n\tcloud.google.com/go/workflows v1.13.0 // indirect\n\tcontrib.go.opencensus.io/exporter/stackdriver v0.13.4 // indirect\n\tdmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9 // indirect\n\tgioui.org v0.0.0-20210308172011-57750fc8a0a6 // indirect\n\tgit.sr.ht/~sbinet/gg v0.3.1 // indirect\n\tgithub.com/4meepo/tagalign v1.3.4 // indirect\n\tgithub.com/Abirdcfly/dupword v0.1.1 // indirect\n\tgithub.com/Antonboom/errname v0.1.13 // indirect\n\tgithub.com/Antonboom/nilnil v0.1.9 // indirect\n\tgithub.com/Antonboom/testifylint v1.4.3 // indirect\n\tgithub.com/BurntSushi/toml v1.4.1-0.20240526193622-a339e1f7089c // indirect\n\tgithub.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802 // indirect\n\tgithub.com/Crocmagnon/fatcontext v0.5.2 // indirect\n\tgithub.com/DataDog/datadog-go v3.2.0+incompatible // indirect\n\tgithub.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24 // indirect\n\tgithub.com/GaijinEntertainment/go-exhaustruct/v3 v3.3.0 // indirect\n\tgithub.com/GoogleCloudPlatform/grpc-gcp-go/grpcgcp v1.5.0 // indirect\n\tgithub.com/JohnCGriffin/overflow v0.0.0-20211019200055-46fa312c352c // indirect\n\tgithub.com/Masterminds/goutils v1.1.0 // indirect\n\tgithub.com/Masterminds/semver v1.5.0 // indirect\n\tgithub.com/Masterminds/semver/v3 v3.3.0 // indirect\n\tgithub.com/Masterminds/sprig v2.22.0+incompatible // indirect\n\tgithub.com/OneOfOne/xxhash v1.2.2 // indirect\n\tgithub.com/OpenPeeDeeP/depguard v1.1.1 // indirect\n\tgithub.com/OpenPeeDeeP/depguard/v2 v2.2.0 // indirect\n\tgithub.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d // indirect\n\tgithub.com/ajstarks/deck v0.0.0-20200831202436-30c9fc6549a9 // indirect\n\tgithub.com/ajstarks/deck/generate v0.0.0-20210309230005-c3f852c02e19 // indirect\n\tgithub.com/ajstarks/svgo v0.0.0-20211024235047-1546f124cd8b // indirect\n\tgithub.com/alecthomas/assert/v2 v2.3.0 // indirect\n\tgithub.com/alecthomas/go-check-sumtype v0.1.4 // indirect\n\tgithub.com/alecthomas/participle/v2 v2.1.0 // indirect\n\tgithub.com/alecthomas/repr v0.2.0 // indirect\n\tgithub.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 // indirect\n\tgithub.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 // indirect\n\tgithub.com/alexkohler/nakedret/v2 v2.0.4 // indirect\n\tgithub.com/alexkohler/prealloc v1.0.0 // indirect\n\tgithub.com/alingse/asasalint v0.0.11 // indirect\n\tgithub.com/andybalholm/brotli v1.1.0 // indirect\n\tgithub.com/antihax/optional v1.0.0 // indirect\n\tgithub.com/aokoli/goutils v1.0.1 // indirect\n\tgithub.com/apache/arrow/go/v10 v10.0.1 // indirect\n\tgithub.com/apache/arrow/go/v11 v11.0.0 // indirect\n\tgithub.com/apache/arrow/go/v12 v12.0.1 // indirect\n\tgithub.com/apache/arrow/go/v14 v14.0.2 // indirect\n\tgithub.com/apache/arrow/go/v15 v15.0.2 // indirect\n\tgithub.com/apache/thrift v0.17.0 // indirect\n\tgithub.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e // indirect\n\tgithub.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6 // indirect\n\tgithub.com/armon/go-metrics v0.4.1 // indirect\n\tgithub.com/armon/go-radix v1.0.0 // indirect\n\tgithub.com/ashanbrown/forbidigo v1.6.0 // indirect\n\tgithub.com/ashanbrown/makezero v1.1.1 // indirect\n\tgithub.com/aws/aws-sdk-go v1.36.30 // indirect\n\tgithub.com/benbjohnson/clock v1.1.0 // indirect\n\tgithub.com/beorn7/perks v1.0.1 // indirect\n\tgithub.com/bgentry/speakeasy v0.1.0 // indirect\n\tgithub.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c // indirect\n\tgithub.com/bkielbasa/cyclop v1.2.1 // indirect\n\tgithub.com/blizzy78/varnamelen v0.8.0 // indirect\n\tgithub.com/bombsimon/wsl/v3 v3.4.0 // indirect\n\tgithub.com/bombsimon/wsl/v4 v4.4.1 // indirect\n\tgithub.com/boombuler/barcode v1.0.1 // indirect\n\tgithub.com/breml/bidichk v0.3.1 // indirect\n\tgithub.com/breml/errchkjson v0.4.0 // indirect\n\tgithub.com/butuzov/ireturn v0.3.0 // indirect\n\tgithub.com/butuzov/mirror v1.2.0 // indirect\n\tgithub.com/catenacyber/perfsprint v0.7.1 // indirect\n\tgithub.com/ccojocar/zxcvbn-go v1.0.2 // indirect\n\tgithub.com/census-instrumentation/opencensus-proto v0.4.1 // indirect\n\tgithub.com/cespare/xxhash v1.1.0 // indirect\n\tgithub.com/cespare/xxhash/v2 v2.3.0 // indirect\n\tgithub.com/charithe/durationcheck v0.0.10 // indirect\n\tgithub.com/chavacava/garif v0.1.0 // indirect\n\tgithub.com/chromedp/cdproto v0.0.0-20230802225258-3cf4e6d46a89 // indirect\n\tgithub.com/chromedp/chromedp v0.9.2 // indirect\n\tgithub.com/chromedp/sysutil v1.0.0 // indirect\n\tgithub.com/chzyer/logex v1.2.1 // indirect\n\tgithub.com/chzyer/readline v1.5.1 // indirect\n\tgithub.com/chzyer/test v1.0.0 // indirect\n\tgithub.com/circonus-labs/circonus-gometrics v2.3.1+incompatible // indirect\n\tgithub.com/circonus-labs/circonusllhist v0.1.3 // indirect\n\tgithub.com/ckaznocha/intrange v0.2.1 // indirect\n\tgithub.com/client9/misspell v0.3.4 // indirect\n\tgithub.com/cncf/udpa/go v0.0.0-20220112060539-c52dc94e7fbe // indirect\n\tgithub.com/cncf/xds/go v0.0.0-20240822171458-6449f94b4d59 // indirect\n\tgithub.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa // indirect\n\tgithub.com/coreos/bbolt v1.3.2 // indirect\n\tgithub.com/coreos/etcd v3.3.13+incompatible // indirect\n\tgithub.com/coreos/go-etcd v2.0.0+incompatible // indirect\n\tgithub.com/coreos/go-semver v0.3.0 // indirect\n\tgithub.com/coreos/go-systemd v0.0.0-20190620071333-e64a0ec8b42a // indirect\n\tgithub.com/coreos/go-systemd/v22 v22.3.2 // indirect\n\tgithub.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f // indirect\n\tgithub.com/cpuguy83/go-md2man v1.0.10 // indirect\n\tgithub.com/cpuguy83/go-md2man/v2 v2.0.4 // indirect\n\tgithub.com/creack/pty v1.1.9 // indirect\n\tgithub.com/cristalhq/acmd v0.12.0 // indirect\n\tgithub.com/curioswitch/go-reassign v0.2.0 // indirect\n\tgithub.com/daixiang0/gci v0.13.5 // indirect\n\tgithub.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect\n\tgithub.com/denis-tingaikin/go-header v0.5.0 // indirect\n\tgithub.com/denis-tingajkin/go-header v0.4.2 // indirect\n\tgithub.com/dgrijalva/jwt-go v3.2.0+incompatible // indirect\n\tgithub.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954 // indirect\n\tgithub.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815 // indirect\n\tgithub.com/dustin/go-humanize v1.0.1 // indirect\n\tgithub.com/envoyproxy/go-control-plane v0.13.0 // indirect\n\tgithub.com/envoyproxy/protoc-gen-validate v1.1.0 // indirect\n\tgithub.com/esimonov/ifshort v1.0.4 // indirect\n\tgithub.com/ettle/strcase v0.2.0 // indirect\n\tgithub.com/fatih/color v1.17.0 // indirect\n\tgithub.com/fatih/structtag v1.2.0 // indirect\n\tgithub.com/felixge/httpsnoop v1.0.4 // indirect\n\tgithub.com/firefart/nonamedreturns v1.0.5 // indirect\n\tgithub.com/fogleman/gg v1.3.0 // indirect\n\tgithub.com/frankban/quicktest v1.14.6 // indirect\n\tgithub.com/fsnotify/fsnotify v1.7.0 // indirect\n\tgithub.com/fullstorydev/grpcurl v1.6.0 // indirect\n\tgithub.com/fzipp/gocyclo v0.6.0 // indirect\n\tgithub.com/ghodss/yaml v1.0.0 // indirect\n\tgithub.com/ghostiam/protogetter v0.3.8 // indirect\n\tgithub.com/go-critic/go-critic v0.11.4 // indirect\n\tgithub.com/go-fonts/dejavu v0.1.0 // indirect\n\tgithub.com/go-fonts/latin-modern v0.2.0 // indirect\n\tgithub.com/go-fonts/liberation v0.2.0 // indirect\n\tgithub.com/go-fonts/stix v0.1.0 // indirect\n\tgithub.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1 // indirect\n\tgithub.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4 // indirect\n\tgithub.com/go-kit/kit v0.9.0 // indirect\n\tgithub.com/go-kit/log v0.2.1 // indirect\n\tgithub.com/go-latex/latex v0.0.0-20210823091927-c0d11ff05a81 // indirect\n\tgithub.com/go-logfmt/logfmt v0.5.1 // indirect\n\tgithub.com/go-logr/logr v1.4.2 // indirect\n\tgithub.com/go-logr/stdr v1.2.2 // indirect\n\tgithub.com/go-ole/go-ole v1.2.6 // indirect\n\tgithub.com/go-pdf/fpdf v0.6.0 // indirect\n\tgithub.com/go-playground/assert/v2 v2.0.1 // indirect\n\tgithub.com/go-playground/locales v0.13.0 // indirect\n\tgithub.com/go-playground/universal-translator v0.17.0 // indirect\n\tgithub.com/go-playground/validator/v10 v10.4.1 // indirect\n\tgithub.com/go-quicktest/qt v1.101.0 // indirect\n\tgithub.com/go-redis/redis v6.15.8+incompatible // indirect\n\tgithub.com/go-sql-driver/mysql v1.7.1 // indirect\n\tgithub.com/go-stack/stack v1.8.0 // indirect\n\tgithub.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect\n\tgithub.com/go-task/slim-sprig/v3 v3.0.0 // indirect\n\tgithub.com/go-toolsmith/astcast v1.1.0 // indirect\n\tgithub.com/go-toolsmith/astcopy v1.1.0 // indirect\n\tgithub.com/go-toolsmith/astequal v1.2.0 // indirect\n\tgithub.com/go-toolsmith/astfmt v1.1.0 // indirect\n\tgithub.com/go-toolsmith/astinfo v0.0.0-20180906194353-9809ff7efb21 // indirect\n\tgithub.com/go-toolsmith/astp v1.1.0 // indirect\n\tgithub.com/go-toolsmith/pkgload v1.2.2 // indirect\n\tgithub.com/go-toolsmith/strparse v1.1.0 // indirect\n\tgithub.com/go-toolsmith/typep v1.1.0 // indirect\n\tgithub.com/go-viper/mapstructure/v2 v2.1.0 // indirect\n\tgithub.com/go-xmlfmt/xmlfmt v1.1.2 // indirect\n\tgithub.com/gobwas/glob v0.2.3 // indirect\n\tgithub.com/gobwas/httphead v0.1.0 // indirect\n\tgithub.com/gobwas/pool v0.2.1 // indirect\n\tgithub.com/gobwas/ws v1.2.1 // indirect\n\tgithub.com/goccy/go-json v0.10.2 // indirect\n\tgithub.com/goccy/go-yaml v1.11.0 // indirect\n\tgithub.com/godbus/dbus/v5 v5.0.4 // indirect\n\tgithub.com/gofrs/flock v0.12.1 // indirect\n\tgithub.com/gogo/protobuf v1.3.2 // indirect\n\tgithub.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect\n\tgithub.com/golang/glog v1.2.1 // indirect\n\tgithub.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect\n\tgithub.com/golang/protobuf v1.5.4 // indirect\n\tgithub.com/golang/snappy v0.0.4 // indirect\n\tgithub.com/golangci/check v0.0.0-20180506172741-cfe4005ccda2 // indirect\n\tgithub.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a // indirect\n\tgithub.com/golangci/go-misc v0.0.0-20220329215616-d24fe342adfe // indirect\n\tgithub.com/golangci/gofmt v0.0.0-20240816233607-d8596aa466a9 // indirect\n\tgithub.com/golangci/lint-1 v0.0.0-20191013205115-297bf364a8e0 // indirect\n\tgithub.com/golangci/maligned v0.0.0-20180506175553-b1d89398deca // indirect\n\tgithub.com/golangci/misspell v0.6.0 // indirect\n\tgithub.com/golangci/modinfo v0.3.4 // indirect\n\tgithub.com/golangci/plugin-module-register v0.1.1 // indirect\n\tgithub.com/golangci/revgrep v0.5.3 // indirect\n\tgithub.com/golangci/unconvert v0.0.0-20240309020433-c5143eacb3ed // indirect\n\tgithub.com/google/btree v1.1.3 // indirect\n\tgithub.com/google/certificate-transparency-go v1.1.1 // indirect\n\tgithub.com/google/flatbuffers v23.5.26+incompatible // indirect\n\tgithub.com/google/generative-ai-go v0.18.0 // indirect\n\tgithub.com/google/go-cmp v0.6.0 // indirect\n\tgithub.com/google/go-pkcs11 v0.3.0 // indirect\n\tgithub.com/google/gofuzz v1.0.0 // indirect\n\tgithub.com/google/martian v2.1.0+incompatible // indirect\n\tgithub.com/google/martian/v3 v3.3.3 // indirect\n\tgithub.com/google/pprof v0.0.0-20240827171923-fa2c70bbbfe5 // indirect\n\tgithub.com/google/renameio v0.1.0 // indirect\n\tgithub.com/google/s2a-go v0.1.8 // indirect\n\tgithub.com/google/trillian v1.3.11 // indirect\n\tgithub.com/google/uuid v1.6.0 // indirect\n\tgithub.com/googleapis/cloud-bigtable-clients-test v0.0.2 // indirect\n\tgithub.com/googleapis/enterprise-certificate-proxy v0.3.4 // indirect\n\tgithub.com/googleapis/gax-go/v2 v2.13.0 // indirect\n\tgithub.com/googleapis/go-type-adapters v1.0.0 // indirect\n\tgithub.com/googleapis/google-cloud-go-testing v0.0.0-20210719221736-1c9a4c676720 // indirect\n\tgithub.com/gookit/color v1.5.4 // indirect\n\tgithub.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 // indirect\n\tgithub.com/gordonklaus/ineffassign v0.1.0 // indirect\n\tgithub.com/gorhill/cronexpr v0.0.0-20180427100037-88b0669f7d75 // indirect\n\tgithub.com/gorilla/mux v1.8.0 // indirect\n\tgithub.com/gorilla/websocket v1.4.2 // indirect\n\tgithub.com/gostaticanalysis/analysisutil v0.7.1 // indirect\n\tgithub.com/gostaticanalysis/comment v1.4.2 // indirect\n\tgithub.com/gostaticanalysis/forcetypeassert v0.1.0 // indirect\n\tgithub.com/gostaticanalysis/nilerr v0.1.1 // indirect\n\tgithub.com/gostaticanalysis/testutil v0.4.0 // indirect\n\tgithub.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 // indirect\n\tgithub.com/grpc-ecosystem/go-grpc-middleware v1.2.2 // indirect\n\tgithub.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 // indirect\n\tgithub.com/grpc-ecosystem/grpc-gateway v1.16.0 // indirect\n\tgithub.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 // indirect\n\tgithub.com/hamba/avro/v2 v2.17.2 // indirect\n\tgithub.com/hashicorp/consul/api v1.28.2 // indirect\n\tgithub.com/hashicorp/consul/sdk v0.16.0 // indirect\n\tgithub.com/hashicorp/errwrap v1.1.0 // indirect\n\tgithub.com/hashicorp/go-cleanhttp v0.5.2 // indirect\n\tgithub.com/hashicorp/go-hclog v1.5.0 // indirect\n\tgithub.com/hashicorp/go-immutable-radix v1.3.1 // indirect\n\tgithub.com/hashicorp/go-msgpack v0.5.5 // indirect\n\tgithub.com/hashicorp/go-multierror v1.1.1 // indirect\n\tgithub.com/hashicorp/go-retryablehttp v0.5.3 // indirect\n\tgithub.com/hashicorp/go-rootcerts v1.0.2 // indirect\n\tgithub.com/hashicorp/go-sockaddr v1.0.2 // indirect\n\tgithub.com/hashicorp/go-syslog v1.0.0 // indirect\n\tgithub.com/hashicorp/go-uuid v1.0.3 // indirect\n\tgithub.com/hashicorp/go-version v1.7.0 // indirect\n\tgithub.com/hashicorp/go.net v0.0.1 // indirect\n\tgithub.com/hashicorp/golang-lru v0.5.4 // indirect\n\tgithub.com/hashicorp/hcl v1.0.0 // indirect\n\tgithub.com/hashicorp/logutils v1.0.0 // indirect\n\tgithub.com/hashicorp/mdns v1.0.4 // indirect\n\tgithub.com/hashicorp/memberlist v0.5.0 // indirect\n\tgithub.com/hashicorp/serf v0.10.1 // indirect\n\tgithub.com/hexops/gotextdiff v1.0.3 // indirect\n\tgithub.com/hpcloud/tail v1.0.0 // indirect\n\tgithub.com/huandu/xstrings v1.2.0 // indirect\n\tgithub.com/iancoleman/strcase v0.3.0 // indirect\n\tgithub.com/ianlancetaylor/demangle v0.0.0-20240312041847-bd984b5ce465 // indirect\n\tgithub.com/imdario/mergo v0.3.8 // indirect\n\tgithub.com/inconshreveable/mousetrap v1.1.0 // indirect\n\tgithub.com/jackc/pgpassfile v1.0.0 // indirect\n\tgithub.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect\n\tgithub.com/jackc/pgx/v5 v5.4.3 // indirect\n\tgithub.com/jackc/puddle/v2 v2.2.1 // indirect\n\tgithub.com/jgautheron/goconst v1.7.1 // indirect\n\tgithub.com/jhump/protoreflect v1.6.1 // indirect\n\tgithub.com/jingyugao/rowserrcheck v1.1.1 // indirect\n\tgithub.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af // indirect\n\tgithub.com/jjti/go-spancheck v0.6.2 // indirect\n\tgithub.com/jmespath/go-jmespath v0.4.0 // indirect\n\tgithub.com/jmespath/go-jmespath/internal/testify v1.5.1 // indirect\n\tgithub.com/jmoiron/sqlx v1.3.5 // indirect\n\tgithub.com/jonboulle/clockwork v0.2.0 // indirect\n\tgithub.com/josharian/intern v1.0.0 // indirect\n\tgithub.com/josharian/txtarfs v0.0.0-20210218200122-0702f000015a // indirect\n\tgithub.com/jpillora/backoff v1.0.0 // indirect\n\tgithub.com/json-iterator/go v1.1.12 // indirect\n\tgithub.com/jstemmer/go-junit-report v0.9.1 // indirect\n\tgithub.com/jtolds/gls v4.20.0+incompatible // indirect\n\tgithub.com/juju/ratelimit v1.0.1 // indirect\n\tgithub.com/julienschmidt/httprouter v1.3.0 // indirect\n\tgithub.com/julz/importas v0.1.0 // indirect\n\tgithub.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5 // indirect\n\tgithub.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88 // indirect\n\tgithub.com/karamaru-alpha/copyloopvar v1.1.0 // indirect\n\tgithub.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect\n\tgithub.com/kisielk/errcheck v1.7.0 // indirect\n\tgithub.com/kisielk/gotool v1.0.0 // indirect\n\tgithub.com/kkHAIKE/contextcheck v1.1.5 // indirect\n\tgithub.com/klauspost/asmfmt v1.3.2 // indirect\n\tgithub.com/klauspost/compress v1.17.9 // indirect\n\tgithub.com/klauspost/cpuid/v2 v2.2.5 // indirect\n\tgithub.com/konsorten/go-windows-terminal-sequences v1.0.3 // indirect\n\tgithub.com/kr/fs v0.1.0 // indirect\n\tgithub.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515 // indirect\n\tgithub.com/kr/pretty v0.3.1 // indirect\n\tgithub.com/kr/pty v1.1.1 // indirect\n\tgithub.com/kr/text v0.2.0 // indirect\n\tgithub.com/kulti/thelper v0.6.3 // indirect\n\tgithub.com/kunwardeep/paralleltest v1.0.10 // indirect\n\tgithub.com/kylelemons/godebug v1.1.0 // indirect\n\tgithub.com/kyoh86/exportloopref v0.1.11 // indirect\n\tgithub.com/lasiar/canonicalheader v1.1.1 // indirect\n\tgithub.com/ldez/gomoddirectives v0.2.4 // indirect\n\tgithub.com/ldez/tagliatelle v0.5.0 // indirect\n\tgithub.com/ledongthuc/pdf v0.0.0-20220302134840-0c2507a12d80 // indirect\n\tgithub.com/leodido/go-urn v1.2.0 // indirect\n\tgithub.com/leonklingele/grouper v1.1.2 // indirect\n\tgithub.com/letsencrypt/pkcs11key/v4 v4.0.0 // indirect\n\tgithub.com/lib/pq v1.10.9 // indirect\n\tgithub.com/logrusorgru/aurora v0.0.0-20181002194514-a7b3b318ed4e // indirect\n\tgithub.com/lufeee/execinquery v1.2.1 // indirect\n\tgithub.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect\n\tgithub.com/lyft/protoc-gen-star v0.6.1 // indirect\n\tgithub.com/lyft/protoc-gen-star/v2 v2.0.4-0.20230330145011-496ad1ac90a4 // indirect\n\tgithub.com/macabu/inamedparam v0.1.3 // indirect\n\tgithub.com/magefile/mage v1.15.0 // indirect\n\tgithub.com/magiconair/properties v1.8.7 // indirect\n\tgithub.com/mailru/easyjson v0.7.7 // indirect\n\tgithub.com/maratori/testableexamples v1.0.0 // indirect\n\tgithub.com/maratori/testpackage v1.1.1 // indirect\n\tgithub.com/matoous/godox v0.0.0-20240105082147-c5b5e0e7c0c0 // indirect\n\tgithub.com/matryer/is v1.4.0 // indirect\n\tgithub.com/mattn/go-colorable v0.1.13 // indirect\n\tgithub.com/mattn/go-isatty v0.0.20 // indirect\n\tgithub.com/mattn/go-runewidth v0.0.16 // indirect\n\tgithub.com/mattn/go-sqlite3 v1.14.16 // indirect\n\tgithub.com/mattn/goveralls v0.0.2 // indirect\n\tgithub.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect\n\tgithub.com/mbilski/exhaustivestruct v1.2.0 // indirect\n\tgithub.com/mgechev/dots v0.0.0-20210922191527-e955255bf517 // indirect\n\tgithub.com/mgechev/revive v1.3.9 // indirect\n\tgithub.com/miekg/dns v1.1.41 // indirect\n\tgithub.com/miekg/pkcs11 v1.0.3 // indirect\n\tgithub.com/minio/asm2plan9s v0.0.0-20200509001527-cdd76441f9d8 // indirect\n\tgithub.com/minio/c2goasm v0.0.0-20190812172519-36a3d3bbc4f3 // indirect\n\tgithub.com/mitchellh/cli v1.1.0 // indirect\n\tgithub.com/mitchellh/copystructure v1.0.0 // indirect\n\tgithub.com/mitchellh/go-homedir v1.1.0 // indirect\n\tgithub.com/mitchellh/go-ps v1.0.0 // indirect\n\tgithub.com/mitchellh/go-testing-interface v1.0.0 // indirect\n\tgithub.com/mitchellh/go-wordwrap v1.0.0 // indirect\n\tgithub.com/mitchellh/gox v0.4.0 // indirect\n\tgithub.com/mitchellh/iochan v1.0.0 // indirect\n\tgithub.com/mitchellh/mapstructure v1.5.0 // indirect\n\tgithub.com/mitchellh/reflectwalk v1.0.1 // indirect\n\tgithub.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect\n\tgithub.com/modern-go/reflect2 v1.0.2 // indirect\n\tgithub.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect\n\tgithub.com/moricho/tparallel v0.3.2 // indirect\n\tgithub.com/mozilla/scribe v0.0.0-20180711195314-fb71baf557c1 // indirect\n\tgithub.com/mozilla/tls-observatory v0.0.0-20210609171429-7bc42856d2e5 // indirect\n\tgithub.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect\n\tgithub.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f // indirect\n\tgithub.com/mwitkow/go-proto-validators v0.2.0 // indirect\n\tgithub.com/nakabonne/nestif v0.3.1 // indirect\n\tgithub.com/nats-io/nats.go v1.34.0 // indirect\n\tgithub.com/nats-io/nkeys v0.4.7 // indirect\n\tgithub.com/nats-io/nuid v1.0.1 // indirect\n\tgithub.com/nbutton23/zxcvbn-go v0.0.0-20210217022336-fa2cb2858354 // indirect\n\tgithub.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect\n\tgithub.com/nishanths/exhaustive v0.12.0 // indirect\n\tgithub.com/nishanths/predeclared v0.2.2 // indirect\n\tgithub.com/nunnatsa/ginkgolinter v0.16.2 // indirect\n\tgithub.com/nxadm/tail v1.4.8 // indirect\n\tgithub.com/oklog/ulid v1.3.1 // indirect\n\tgithub.com/olekukonko/tablewriter v0.0.5 // indirect\n\tgithub.com/onsi/ginkgo v1.16.4 // indirect\n\tgithub.com/onsi/ginkgo/v2 v2.20.2 // indirect\n\tgithub.com/onsi/gomega v1.34.2 // indirect\n\tgithub.com/opentracing/opentracing-go v1.1.0 // indirect\n\tgithub.com/orisano/pixelmatch v0.0.0-20220722002657-fb0b55479cde // indirect\n\tgithub.com/otiai10/copy v1.14.0 // indirect\n\tgithub.com/otiai10/curr v1.0.0 // indirect\n\tgithub.com/otiai10/mint v1.5.1 // indirect\n\tgithub.com/pascaldekloe/goe v0.1.0 // indirect\n\tgithub.com/pborman/uuid v1.2.0 // indirect\n\tgithub.com/pelletier/go-toml v1.9.5 // indirect\n\tgithub.com/pelletier/go-toml/v2 v2.2.3 // indirect\n\tgithub.com/peterbourgon/diskv v2.0.1+incompatible // indirect\n\tgithub.com/phayes/checkstyle v0.0.0-20170904204023-bfd46e6a821d // indirect\n\tgithub.com/phpdave11/gofpdf v1.4.2 // indirect\n\tgithub.com/phpdave11/gofpdi v1.0.13 // indirect\n\tgithub.com/pierrec/lz4/v4 v4.1.18 // indirect\n\tgithub.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e // indirect\n\tgithub.com/pkg/errors v0.9.1 // indirect\n\tgithub.com/pkg/sftp v1.13.6 // indirect\n\tgithub.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 // indirect\n\tgithub.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect\n\tgithub.com/polyfloyd/go-errorlint v1.6.0 // indirect\n\tgithub.com/posener/complete v1.2.3 // indirect\n\tgithub.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect\n\tgithub.com/prashantv/gostub v1.1.0 // indirect\n\tgithub.com/prometheus/client_golang v1.20.4 // indirect\n\tgithub.com/prometheus/client_model v0.6.1 // indirect\n\tgithub.com/prometheus/common v0.59.1 // indirect\n\tgithub.com/prometheus/procfs v0.15.1 // indirect\n\tgithub.com/prometheus/tsdb v0.7.1 // indirect\n\tgithub.com/pseudomuto/protoc-gen-doc v1.3.2 // indirect\n\tgithub.com/pseudomuto/protokit v0.2.0 // indirect\n\tgithub.com/quasilyte/go-consistent v0.0.0-20190521200055-c6f3937de18c // indirect\n\tgithub.com/quasilyte/go-ruleguard v0.4.3-0.20240823090925-0fe6f58b47b1 // indirect\n\tgithub.com/quasilyte/go-ruleguard/dsl v0.3.22 // indirect\n\tgithub.com/quasilyte/go-ruleguard/rules v0.0.0-20211022131956-028d6511ab71 // indirect\n\tgithub.com/quasilyte/gogrep v0.5.0 // indirect\n\tgithub.com/quasilyte/regex/syntax v0.0.0-20210819130434-b3f0c404a727 // indirect\n\tgithub.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567 // indirect\n\tgithub.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect\n\tgithub.com/remyoudompheng/go-dbus v0.0.0-20121104212943-b7232d34b1d5 // indirect\n\tgithub.com/remyoudompheng/go-liblzma v0.0.0-20190506200333-81bf2d431b96 // indirect\n\tgithub.com/remyoudompheng/go-misc v0.0.0-20190427085024-2d6ac652a50e // indirect\n\tgithub.com/rivo/uniseg v0.4.7 // indirect\n\tgithub.com/rogpeppe/fastuuid v1.2.0 // indirect\n\tgithub.com/rogpeppe/go-internal v1.12.0 // indirect\n\tgithub.com/rs/cors v1.7.0 // indirect\n\tgithub.com/russross/blackfriday v1.5.2 // indirect\n\tgithub.com/russross/blackfriday/v2 v2.1.0 // indirect\n\tgithub.com/ruudk/golang-pdf417 v0.0.0-20201230142125-a7e3863a1245 // indirect\n\tgithub.com/ryancurrah/gomodguard v1.3.5 // indirect\n\tgithub.com/ryanrolds/sqlclosecheck v0.5.1 // indirect\n\tgithub.com/ryanuber/columnize v2.1.0+incompatible // indirect\n\tgithub.com/sagikazarmark/crypt v0.19.0 // indirect\n\tgithub.com/sagikazarmark/locafero v0.6.0 // indirect\n\tgithub.com/sagikazarmark/slog-shim v0.1.0 // indirect\n\tgithub.com/sanposhiho/wastedassign v1.0.0 // indirect\n\tgithub.com/sanposhiho/wastedassign/v2 v2.0.7 // indirect\n\tgithub.com/santhosh-tekuri/jsonschema/v5 v5.3.1 // indirect\n\tgithub.com/sashamelentyev/interfacebloat v1.1.0 // indirect\n\tgithub.com/sashamelentyev/usestdlibvars v1.27.0 // indirect\n\tgithub.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 // indirect\n\tgithub.com/securego/gosec/v2 v2.21.3 // indirect\n\tgithub.com/sergi/go-diff v1.1.0 // indirect\n\tgithub.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c // indirect\n\tgithub.com/shirou/gopsutil/v3 v3.24.5 // indirect\n\tgithub.com/shoenig/go-m1cpu v0.1.6 // indirect\n\tgithub.com/shoenig/test v0.6.4 // indirect\n\tgithub.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e // indirect\n\tgithub.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041 // indirect\n\tgithub.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect\n\tgithub.com/sirupsen/logrus v1.9.3 // indirect\n\tgithub.com/sivchari/containedctx v1.0.3 // indirect\n\tgithub.com/sivchari/tenv v1.10.0 // indirect\n\tgithub.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d // indirect\n\tgithub.com/smartystreets/goconvey v1.6.4 // indirect\n\tgithub.com/soheilhy/cmux v0.1.4 // indirect\n\tgithub.com/sonatard/noctx v0.1.0 // indirect\n\tgithub.com/sourcegraph/conc v0.3.0 // indirect\n\tgithub.com/sourcegraph/go-diff v0.7.0 // indirect\n\tgithub.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72 // indirect\n\tgithub.com/spf13/afero v1.11.0 // indirect\n\tgithub.com/spf13/cast v1.7.0 // indirect\n\tgithub.com/spf13/cobra v1.8.1 // indirect\n\tgithub.com/spf13/jwalterweatherman v1.1.0 // indirect\n\tgithub.com/spf13/pflag v1.0.5 // indirect\n\tgithub.com/spf13/viper v1.19.0 // indirect\n\tgithub.com/ssgreg/nlreturn/v2 v2.2.1 // indirect\n\tgithub.com/stbenjam/no-sprintf-host-port v0.1.1 // indirect\n\tgithub.com/stoewer/go-strcase v1.3.0 // indirect\n\tgithub.com/stretchr/objx v0.5.2 // indirect\n\tgithub.com/stretchr/testify v1.9.0 // indirect\n\tgithub.com/subosito/gotenv v1.6.0 // indirect\n\tgithub.com/substrait-io/substrait-go v0.4.2 // indirect\n\tgithub.com/tdakkota/asciicheck v0.2.0 // indirect\n\tgithub.com/tenntenn/modver v1.0.1 // indirect\n\tgithub.com/tenntenn/text/transform v0.0.0-20200319021203-7eef512accb3 // indirect\n\tgithub.com/tetafro/godot v1.4.18 // indirect\n\tgithub.com/tidwall/gjson v1.14.2 // indirect\n\tgithub.com/tidwall/match v1.1.1 // indirect\n\tgithub.com/tidwall/pretty v1.2.0 // indirect\n\tgithub.com/tidwall/sjson v1.2.5 // indirect\n\tgithub.com/timakin/bodyclose v0.0.0-20240125160201-f835fa56326a // indirect\n\tgithub.com/timonwong/loggercheck v0.9.4 // indirect\n\tgithub.com/tklauser/go-sysconf v0.3.12 // indirect\n\tgithub.com/tklauser/numcpus v0.6.1 // indirect\n\tgithub.com/tmc/grpc-websocket-proxy v0.0.0-20200427203606-3cfed13b9966 // indirect\n\tgithub.com/tomarrell/wrapcheck v1.2.0 // indirect\n\tgithub.com/tomarrell/wrapcheck/v2 v2.9.0 // indirect\n\tgithub.com/tomasen/realip v0.0.0-20180522021738-f0c99a92ddce // indirect\n\tgithub.com/tommy-muehle/go-mnd/v2 v2.5.1 // indirect\n\tgithub.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926 // indirect\n\tgithub.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8 // indirect\n\tgithub.com/ultraware/funlen v0.1.0 // indirect\n\tgithub.com/ultraware/whitespace v0.1.1 // indirect\n\tgithub.com/urfave/cli v1.22.1 // indirect\n\tgithub.com/uudashr/gocognit v1.1.3 // indirect\n\tgithub.com/valyala/bytebufferpool v1.0.0 // indirect\n\tgithub.com/valyala/fasthttp v1.55.0 // indirect\n\tgithub.com/valyala/quicktemplate v1.8.0 // indirect\n\tgithub.com/valyala/tcplisten v1.0.0 // indirect\n\tgithub.com/viki-org/dnscache v0.0.0-20130720023526-c70c1f23c5d8 // indirect\n\tgithub.com/xen0n/gosmopolitan v1.2.2 // indirect\n\tgithub.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 // indirect\n\tgithub.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778 // indirect\n\tgithub.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77 // indirect\n\tgithub.com/yagipy/maintidx v1.0.0 // indirect\n\tgithub.com/yeya24/promlinter v0.3.0 // indirect\n\tgithub.com/ykadowak/zerologlint v0.1.5 // indirect\n\tgithub.com/yudai/gojsondiff v1.0.0 // indirect\n\tgithub.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 // indirect\n\tgithub.com/yudai/pp v2.0.1+incompatible // indirect\n\tgithub.com/yuin/goldmark v1.4.13 // indirect\n\tgithub.com/yusufpapurcu/wmi v1.2.4 // indirect\n\tgithub.com/zeebo/assert v1.3.0 // indirect\n\tgithub.com/zeebo/xxh3 v1.0.2 // indirect\n\tgitlab.com/bosi/decorder v0.4.2 // indirect\n\tgo-simpler.org/assert v0.9.0 // indirect\n\tgo-simpler.org/musttag v0.12.2 // indirect\n\tgo-simpler.org/sloglint v0.7.2 // indirect\n\tgo.einride.tech/aip v0.67.1 // indirect\n\tgo.etcd.io/bbolt v1.3.4 // indirect\n\tgo.etcd.io/etcd v0.0.0-20200513171258-e048e166ab9c // indirect\n\tgo.etcd.io/etcd/api/v3 v3.5.12 // indirect\n\tgo.etcd.io/etcd/client/pkg/v3 v3.5.12 // indirect\n\tgo.etcd.io/etcd/client/v2 v2.305.12 // indirect\n\tgo.etcd.io/etcd/client/v3 v3.5.12 // indirect\n\tgo.mozilla.org/mozlog v0.0.0-20170222151521-4bb13139d403 // indirect\n\tgo.opencensus.io v0.24.0 // indirect\n\tgo.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.54.0 // indirect\n\tgo.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0 // indirect\n\tgo.opentelemetry.io/otel v1.29.0 // indirect\n\tgo.opentelemetry.io/otel/metric v1.29.0 // indirect\n\tgo.opentelemetry.io/otel/sdk v1.29.0 // indirect\n\tgo.opentelemetry.io/otel/sdk/metric v1.29.0 // indirect\n\tgo.opentelemetry.io/otel/trace v1.29.0 // indirect\n\tgo.opentelemetry.io/proto/otlp v1.0.0 // indirect\n\tgo.uber.org/atomic v1.11.0 // indirect\n\tgo.uber.org/automaxprocs v1.5.3 // indirect\n\tgo.uber.org/goleak v1.3.0 // indirect\n\tgo.uber.org/multierr v1.11.0 // indirect\n\tgo.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee // indirect\n\tgo.uber.org/zap v1.27.0 // indirect\n\tgolang.org/x/crypto v0.27.0 // indirect\n\tgolang.org/x/exp v0.0.0-20240909161429-701f63a606c0 // indirect\n\tgolang.org/x/exp/typeparams v0.0.0-20240909161429-701f63a606c0 // indirect\n\tgolang.org/x/image v0.0.0-20220302094943-723b81ca9867 // indirect\n\tgolang.org/x/lint v0.0.0-20210508222113-6edffad5e616 // indirect\n\tgolang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028 // indirect\n\tgolang.org/x/mod v0.21.0 // indirect\n\tgolang.org/x/net v0.29.0 // indirect\n\tgolang.org/x/oauth2 v0.23.0 // indirect\n\tgolang.org/x/sync v0.8.0 // indirect\n\tgolang.org/x/sys v0.25.0 // indirect\n\tgolang.org/x/telemetry v0.0.0-20240521205824-bda55230c457 // indirect\n\tgolang.org/x/term v0.24.0 // indirect\n\tgolang.org/x/text v0.18.0 // indirect\n\tgolang.org/x/time v0.6.0 // indirect\n\tgolang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da // indirect\n\tgonum.org/v1/gonum v0.12.0 // indirect\n\tgonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0 // indirect\n\tgonum.org/v1/plot v0.10.1 // indirect\n\tgoogle.golang.org/api v0.197.0 // indirect\n\tgoogle.golang.org/appengine v1.6.8 // indirect\n\tgoogle.golang.org/genproto v0.0.0-20240903143218-8af14fe29dc1 // indirect\n\tgoogle.golang.org/genproto/googleapis/api v0.0.0-20240827150818-7e3bb234dfed // indirect\n\tgoogle.golang.org/genproto/googleapis/bytestream v0.0.0-20240903143218-8af14fe29dc1 // indirect\n\tgoogle.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 // indirect\n\tgoogle.golang.org/grpc v1.66.1 // indirect\n\tgoogle.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0 // indirect\n\tgoogle.golang.org/protobuf v1.34.2 // indirect\n\tgopkg.in/alecthomas/kingpin.v2 v2.2.6 // indirect\n\tgopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect\n\tgopkg.in/cheggaaa/pb.v1 v1.0.28 // indirect\n\tgopkg.in/errgo.v2 v2.1.0 // indirect\n\tgopkg.in/fsnotify.v1 v1.4.7 // indirect\n\tgopkg.in/gcfg.v1 v1.2.3 // indirect\n\tgopkg.in/ini.v1 v1.67.0 // indirect\n\tgopkg.in/resty.v1 v1.12.0 // indirect\n\tgopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect\n\tgopkg.in/warnings.v0 v0.1.2 // indirect\n\tgopkg.in/yaml.v2 v2.4.0 // indirect\n\tgopkg.in/yaml.v3 v3.0.1 // indirect\n\tgotest.tools/v3 v3.5.1 // indirect\n\thonnef.co/go/tools v0.5.1 // indirect\n\tlukechampine.com/uint128 v1.3.0 // indirect\n\tmodernc.org/cc/v3 v3.40.0 // indirect\n\tmodernc.org/ccgo/v3 v3.16.13 // indirect\n\tmodernc.org/ccorpus v1.11.6 // indirect\n\tmodernc.org/httpfs v1.0.6 // indirect\n\tmodernc.org/libc v1.22.4 // indirect\n\tmodernc.org/mathutil v1.5.0 // indirect\n\tmodernc.org/memory v1.5.0 // indirect\n\tmodernc.org/opt v0.1.3 // indirect\n\tmodernc.org/sqlite v1.21.2 // indirect\n\tmodernc.org/strutil v1.1.3 // indirect\n\tmodernc.org/tcl v1.15.1 // indirect\n\tmodernc.org/token v1.1.0 // indirect\n\tmodernc.org/z v1.7.0 // indirect\n\tmvdan.cc/gofumpt v0.7.0 // indirect\n\tmvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed // indirect\n\tmvdan.cc/lint v0.0.0-20170908181259-adc824a0674b // indirect\n\tmvdan.cc/unparam v0.0.0-20240917084806-57a3b4290ba3 // indirect\n\trsc.io/binaryregexp v0.2.0 // indirect\n\trsc.io/pdf v0.1.1 // indirect\n\trsc.io/quote/v3 v3.1.0 // indirect\n\trsc.io/sampler v1.3.0 // indirect\n\tsigs.k8s.io/yaml v1.2.0 // indirect\n)\n"
  },
  {
    "path": "tools/go.sum",
    "content": "4d63.com/gocheckcompilerdirectives v1.2.1 h1:AHcMYuw56NPjq/2y615IGg2kYkBdTvOaojYCBcRE7MA=\n4d63.com/gocheckcompilerdirectives v1.2.1/go.mod h1:yjDJSxmDTtIHHCqX0ufRYZDL6vQtMG7tJdKVeWwsqvs=\n4d63.com/gochecknoglobals v0.0.0-20201008074935-acfc0b28355a h1:wFEQiK85fRsEVF0CRrPAos5LoAryUsIX1kPW/WrIqFw=\n4d63.com/gochecknoglobals v0.0.0-20201008074935-acfc0b28355a/go.mod h1:wfdC5ZjKSPr7CybKEcgJhUOgeAQW1+7WcyK8OvUilfo=\n4d63.com/gochecknoglobals v0.2.1 h1:1eiorGsgHOFOuoOiJDy2psSrQbRdIHrlge0IJIkUgDc=\n4d63.com/gochecknoglobals v0.2.1/go.mod h1:KRE8wtJB3CXCsb1xy421JfTHIIbmT3U5ruxw2Qu8fSU=\nbitbucket.org/creachadair/shell v0.0.6/go.mod h1:8Qqi/cYk7vPnsOePHroKXDJYmb5x7ENhtiFtfZq8K+M=\ncel.dev/expr v0.16.0/go.mod h1:TRSuuV7DlVCE/uwv5QbAiW/v8l5O8C4eEPHeu7gf7Sg=\ncloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=\ncloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=\ncloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=\ncloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=\ncloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=\ncloud.google.com/go v0.44.3/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=\ncloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=\ncloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=\ncloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To=\ncloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4=\ncloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M=\ncloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc=\ncloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk=\ncloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=\ncloud.google.com/go v0.60.0/go.mod h1:yw2G51M9IfRboUH61Us8GqCeF1PzPblB823Mn2q2eAU=\ncloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=\ncloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=\ncloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI=\ncloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk=\ncloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY=\ncloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg=\ncloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8=\ncloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0=\ncloud.google.com/go v0.83.0/go.mod h1:Z7MJUsANfY0pYPdw0lbnivPx4/vhy/e2FEkSkF7vAVY=\ncloud.google.com/go v0.84.0/go.mod h1:RazrYuxIK6Kb7YrzzhPoLmCVzl7Sup4NrbKPg8KHSUM=\ncloud.google.com/go v0.87.0/go.mod h1:TpDYlFy7vuLzZMMZ+B6iRiELaY7z/gJPaqbMx6mlWcY=\ncloud.google.com/go v0.90.0/go.mod h1:kRX0mNRHe0e2rC6oNakvwQqzyDmg57xJ+SZU1eT2aDQ=\ncloud.google.com/go v0.93.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI=\ncloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW4=\ncloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc=\ncloud.google.com/go v0.99.0/go.mod h1:w0Xx2nLzqWJPuozYQX+hFfCSI8WioryfRDzkoI/Y2ZA=\ncloud.google.com/go v0.100.1/go.mod h1:fs4QogzfH5n2pBXBP9vRiU+eCny7lD2vmFZy79Iuw1U=\ncloud.google.com/go v0.100.2/go.mod h1:4Xra9TjzAeYHrl5+oeLlzbM2k3mjVhZh4UqTZ//w99A=\ncloud.google.com/go v0.102.0/go.mod h1:oWcCzKlqJ5zgHQt9YsaeTY9KzIvjyy0ArmiBUgpQ+nc=\ncloud.google.com/go v0.102.1/go.mod h1:XZ77E9qnTEnrgEOvr4xzfdX5TRo7fB4T2F4O6+34hIU=\ncloud.google.com/go v0.104.0/go.mod h1:OO6xxXdJyvuJPcEPBLN9BJPD+jep5G1+2U5B5gkRYtA=\ncloud.google.com/go v0.105.0/go.mod h1:PrLgOJNe5nfE9UMxKxgXj4mD3voiP+YQ6gdt6KMFOKM=\ncloud.google.com/go v0.107.0/go.mod h1:wpc2eNrD7hXUTy8EKS10jkxpZBjASrORK7goS+3YX2I=\ncloud.google.com/go v0.110.0/go.mod h1:SJnCLqQ0FCFGSZMUNUf84MV3Aia54kn7pi8st7tMzaY=\ncloud.google.com/go v0.115.1/go.mod h1:DuujITeaufu3gL68/lOFIirVNJwQeyf5UXyi+Wbgknc=\ncloud.google.com/go/accessapproval v1.4.0/go.mod h1:zybIuC3KpDOvotz59lFe5qxRZx6C75OtwbisN56xYB4=\ncloud.google.com/go/accessapproval v1.5.0/go.mod h1:HFy3tuiGvMdcd/u+Cu5b9NkO1pEICJ46IR82PoUdplw=\ncloud.google.com/go/accessapproval v1.6.0/go.mod h1:R0EiYnwV5fsRFiKZkPHr6mwyk2wxUJ30nL4j2pcFY2E=\ncloud.google.com/go/accessapproval v1.8.0/go.mod h1:ycc7qSIXOrH6gGOGQsuBwpRZw3QhZLi0OWeej3rA5Mg=\ncloud.google.com/go/accesscontextmanager v1.3.0/go.mod h1:TgCBehyr5gNMz7ZaH9xubp+CE8dkrszb4oK9CWyvD4o=\ncloud.google.com/go/accesscontextmanager v1.4.0/go.mod h1:/Kjh7BBu/Gh83sv+K60vN9QE5NJcd80sU33vIe2IFPE=\ncloud.google.com/go/accesscontextmanager v1.6.0/go.mod h1:8XCvZWfYw3K/ji0iVnp+6pu7huxoQTLmxAbVjbloTtM=\ncloud.google.com/go/accesscontextmanager v1.7.0/go.mod h1:CEGLewx8dwa33aDAZQujl7Dx+uYhS0eay198wB/VumQ=\ncloud.google.com/go/accesscontextmanager v1.9.0/go.mod h1:EmdQRGq5FHLrjGjGTp2X2tlRBvU3LDCUqfnysFYooxQ=\ncloud.google.com/go/ai v0.8.0/go.mod h1:t3Dfk4cM61sytiggo2UyGsDVW3RF1qGZaUKDrZFyqkE=\ncloud.google.com/go/aiplatform v1.22.0/go.mod h1:ig5Nct50bZlzV6NvKaTwmplLLddFx0YReh9WfTO5jKw=\ncloud.google.com/go/aiplatform v1.24.0/go.mod h1:67UUvRBKG6GTayHKV8DBv2RtR1t93YRu5B1P3x99mYY=\ncloud.google.com/go/aiplatform v1.27.0/go.mod h1:Bvxqtl40l0WImSb04d0hXFU7gDOiq9jQmorivIiWcKg=\ncloud.google.com/go/aiplatform v1.35.0/go.mod h1:7MFT/vCaOyZT/4IIFfxH4ErVg/4ku6lKv3w0+tFTgXQ=\ncloud.google.com/go/aiplatform v1.36.1/go.mod h1:WTm12vJRPARNvJ+v6P52RDHCNe4AhvjcIZ/9/RRHy/k=\ncloud.google.com/go/aiplatform v1.37.0/go.mod h1:IU2Cv29Lv9oCn/9LkFiiuKfwrRTq+QQMbW+hPCxJGZw=\ncloud.google.com/go/aiplatform v1.68.0/go.mod h1:105MFA3svHjC3Oazl7yjXAmIR89LKhRAeNdnDKJczME=\ncloud.google.com/go/analytics v0.11.0/go.mod h1:DjEWCu41bVbYcKyvlws9Er60YE4a//bK6mnhWvQeFNI=\ncloud.google.com/go/analytics v0.12.0/go.mod h1:gkfj9h6XRf9+TS4bmuhPEShsh3hH8PAZzm/41OOhQd4=\ncloud.google.com/go/analytics v0.17.0/go.mod h1:WXFa3WSym4IZ+JiKmavYdJwGG/CvpqiqczmL59bTD9M=\ncloud.google.com/go/analytics v0.18.0/go.mod h1:ZkeHGQlcIPkw0R/GW+boWHhCOR43xz9RN/jn7WcqfIE=\ncloud.google.com/go/analytics v0.19.0/go.mod h1:k8liqf5/HCnOUkbawNtrWWc+UAzyDlW89doe8TtoDsE=\ncloud.google.com/go/analytics v0.25.0/go.mod h1:LZMfjJnKU1GDkvJV16dKnXm7KJJaMZfvUXx58ujgVLg=\ncloud.google.com/go/apigateway v1.3.0/go.mod h1:89Z8Bhpmxu6AmUxuVRg/ECRGReEdiP3vQtk4Z1J9rJk=\ncloud.google.com/go/apigateway v1.4.0/go.mod h1:pHVY9MKGaH9PQ3pJ4YLzoj6U5FUDeDFBllIz7WmzJoc=\ncloud.google.com/go/apigateway v1.5.0/go.mod h1:GpnZR3Q4rR7LVu5951qfXPJCHquZt02jf7xQx7kpqN8=\ncloud.google.com/go/apigateway v1.7.0/go.mod h1:miZGNhmrC+SFhxjA7ayjKHk1cA+7vsSINp9K+JxKwZI=\ncloud.google.com/go/apigeeconnect v1.3.0/go.mod h1:G/AwXFAKo0gIXkPTVfZDd2qA1TxBXJ3MgMRBQkIi9jc=\ncloud.google.com/go/apigeeconnect v1.4.0/go.mod h1:kV4NwOKqjvt2JYR0AoIWo2QGfoRtn/pkS3QlHp0Ni04=\ncloud.google.com/go/apigeeconnect v1.5.0/go.mod h1:KFaCqvBRU6idyhSNyn3vlHXc8VMDJdRmwDF6JyFRqZ8=\ncloud.google.com/go/apigeeconnect v1.7.0/go.mod h1:fd8NFqzu5aXGEUpxiyeCyb4LBLU7B/xIPztfBQi+1zg=\ncloud.google.com/go/apigeeregistry v0.4.0/go.mod h1:EUG4PGcsZvxOXAdyEghIdXwAEi/4MEaoqLMLDMIwKXY=\ncloud.google.com/go/apigeeregistry v0.5.0/go.mod h1:YR5+s0BVNZfVOUkMa5pAR2xGd0A473vA5M7j247o1wM=\ncloud.google.com/go/apigeeregistry v0.6.0/go.mod h1:BFNzW7yQVLZ3yj0TKcwzb8n25CFBri51GVGOEUcgQsc=\ncloud.google.com/go/apigeeregistry v0.9.0/go.mod h1:4S/btGnijdt9LSIZwBDHgtYfYkFGekzNyWkyYTP8Qzs=\ncloud.google.com/go/apikeys v0.4.0/go.mod h1:XATS/yqZbaBK0HOssf+ALHp8jAlNHUgyfprvNcBIszU=\ncloud.google.com/go/apikeys v0.5.0/go.mod h1:5aQfwY4D+ewMMWScd3hm2en3hCj+BROlyrt3ytS7KLI=\ncloud.google.com/go/apikeys v0.6.0/go.mod h1:kbpXu5upyiAlGkKrJgQl8A0rKNNJ7dQ377pdroRSSi8=\ncloud.google.com/go/appengine v1.4.0/go.mod h1:CS2NhuBuDXM9f+qscZ6V86m1MIIqPj3WC/UoEuR1Sno=\ncloud.google.com/go/appengine v1.5.0/go.mod h1:TfasSozdkFI0zeoxW3PTBLiNqRmzraodCWatWI9Dmak=\ncloud.google.com/go/appengine v1.6.0/go.mod h1:hg6i0J/BD2cKmDJbaFSYHFyZkgBEfQrDg/X0V5fJn84=\ncloud.google.com/go/appengine v1.7.0/go.mod h1:eZqpbHFCqRGa2aCdope7eC0SWLV1j0neb/QnMJVWx6A=\ncloud.google.com/go/appengine v1.7.1/go.mod h1:IHLToyb/3fKutRysUlFO0BPt5j7RiQ45nrzEJmKTo6E=\ncloud.google.com/go/appengine v1.9.0/go.mod h1:y5oI+JT3/6s77QmxbTnLHyiMKz3NPHYOjuhmVi+FyYU=\ncloud.google.com/go/area120 v0.5.0/go.mod h1:DE/n4mp+iqVyvxHN41Vf1CR602GiHQjFPusMFW6bGR4=\ncloud.google.com/go/area120 v0.6.0/go.mod h1:39yFJqWVgm0UZqWTOdqkLhjoC7uFfgXRC8g/ZegeAh0=\ncloud.google.com/go/area120 v0.7.0/go.mod h1:a3+8EUD1SX5RUcCs3MY5YasiO1z6yLiNLRiFrykbynY=\ncloud.google.com/go/area120 v0.7.1/go.mod h1:j84i4E1RboTWjKtZVWXPqvK5VHQFJRF2c1Nm69pWm9k=\ncloud.google.com/go/area120 v0.9.0/go.mod h1:ujIhRz2gJXutmFYGAUgz3KZ5IRJ6vOwL4CYlNy/jDo4=\ncloud.google.com/go/artifactregistry v1.6.0/go.mod h1:IYt0oBPSAGYj/kprzsBjZ/4LnG/zOcHyFHjWPCi6SAQ=\ncloud.google.com/go/artifactregistry v1.7.0/go.mod h1:mqTOFOnGZx8EtSqK/ZWcsm/4U8B77rbcLP6ruDU2Ixk=\ncloud.google.com/go/artifactregistry v1.8.0/go.mod h1:w3GQXkJX8hiKN0v+at4b0qotwijQbYUqF2GWkZzAhC0=\ncloud.google.com/go/artifactregistry v1.9.0/go.mod h1:2K2RqvA2CYvAeARHRkLDhMDJ3OXy26h3XW+3/Jh2uYc=\ncloud.google.com/go/artifactregistry v1.11.1/go.mod h1:lLYghw+Itq9SONbCa1YWBoWs1nOucMH0pwXN1rOBZFI=\ncloud.google.com/go/artifactregistry v1.11.2/go.mod h1:nLZns771ZGAwVLzTX/7Al6R9ehma4WUEhZGWV6CeQNQ=\ncloud.google.com/go/artifactregistry v1.12.0/go.mod h1:o6P3MIvtzTOnmvGagO9v/rOjjA0HmhJ+/6KAXrmYDCI=\ncloud.google.com/go/artifactregistry v1.13.0/go.mod h1:uy/LNfoOIivepGhooAUpL1i30Hgee3Cu0l4VTWHUC08=\ncloud.google.com/go/artifactregistry v1.15.0/go.mod h1:4xrfigx32/3N7Pp7YSPOZZGs4VPhyYeRyJ67ZfVdOX4=\ncloud.google.com/go/asset v1.5.0/go.mod h1:5mfs8UvcM5wHhqtSv8J1CtxxaQq3AdBxxQi2jGW/K4o=\ncloud.google.com/go/asset v1.7.0/go.mod h1:YbENsRK4+xTiL+Ofoj5Ckf+O17kJtgp3Y3nn4uzZz5s=\ncloud.google.com/go/asset v1.8.0/go.mod h1:mUNGKhiqIdbr8X7KNayoYvyc4HbbFO9URsjbytpUaW0=\ncloud.google.com/go/asset v1.9.0/go.mod h1:83MOE6jEJBMqFKadM9NLRcs80Gdw76qGuHn8m3h8oHQ=\ncloud.google.com/go/asset v1.10.0/go.mod h1:pLz7uokL80qKhzKr4xXGvBQXnzHn5evJAEAtZiIb0wY=\ncloud.google.com/go/asset v1.11.1/go.mod h1:fSwLhbRvC9p9CXQHJ3BgFeQNM4c9x10lqlrdEUYXlJo=\ncloud.google.com/go/asset v1.12.0/go.mod h1:h9/sFOa4eDIyKmH6QMpm4eUK3pDojWnUhTgJlk762Hg=\ncloud.google.com/go/asset v1.13.0/go.mod h1:WQAMyYek/b7NBpYq/K4KJWcRqzoalEsxz/t/dTk4THw=\ncloud.google.com/go/asset v1.20.0/go.mod h1:CT3ME6xNZKsPSvi0lMBPgW3azvRhiurJTFSnNl6ahw8=\ncloud.google.com/go/assuredworkloads v1.5.0/go.mod h1:n8HOZ6pff6re5KYfBXcFvSViQjDwxFkAkmUFffJRbbY=\ncloud.google.com/go/assuredworkloads v1.6.0/go.mod h1:yo2YOk37Yc89Rsd5QMVECvjaMKymF9OP+QXWlKXUkXw=\ncloud.google.com/go/assuredworkloads v1.7.0/go.mod h1:z/736/oNmtGAyU47reJgGN+KVoYoxeLBoj4XkKYscNI=\ncloud.google.com/go/assuredworkloads v1.8.0/go.mod h1:AsX2cqyNCOvEQC8RMPnoc0yEarXQk6WEKkxYfL6kGIo=\ncloud.google.com/go/assuredworkloads v1.9.0/go.mod h1:kFuI1P78bplYtT77Tb1hi0FMxM0vVpRC7VVoJC3ZoT0=\ncloud.google.com/go/assuredworkloads v1.10.0/go.mod h1:kwdUQuXcedVdsIaKgKTp9t0UJkE5+PAVNhdQm4ZVq2E=\ncloud.google.com/go/assuredworkloads v1.12.0/go.mod h1:jX84R+0iANggmSbzvVgrGWaqdhRsQihAv4fF7IQ4r7Q=\ncloud.google.com/go/auth v0.9.3/go.mod h1:7z6VY+7h3KUdRov5F1i8NDP5ZzWKYmEPO842BgCsmTk=\ncloud.google.com/go/auth/oauth2adapt v0.2.4/go.mod h1:jC/jOpwFP6JBxhB3P5Rr0a9HLMC/Pe3eaL4NmdvqPtc=\ncloud.google.com/go/automl v1.5.0/go.mod h1:34EjfoFGMZ5sgJ9EoLsRtdPSNZLcfflJR39VbVNS2M0=\ncloud.google.com/go/automl v1.6.0/go.mod h1:ugf8a6Fx+zP0D59WLhqgTDsQI9w07o64uf/Is3Nh5p8=\ncloud.google.com/go/automl v1.7.0/go.mod h1:RL9MYCCsJEOmt0Wf3z9uzG0a7adTT1fe+aObgSpkCt8=\ncloud.google.com/go/automl v1.8.0/go.mod h1:xWx7G/aPEe/NP+qzYXktoBSDfjO+vnKMGgsApGJJquM=\ncloud.google.com/go/automl v1.12.0/go.mod h1:tWDcHDp86aMIuHmyvjuKeeHEGq76lD7ZqfGLN6B0NuU=\ncloud.google.com/go/automl v1.14.0/go.mod h1:Kr7rN9ANSjlHyBLGvwhrnt35/vVZy3n/CP4Xmyj0shM=\ncloud.google.com/go/baremetalsolution v0.3.0/go.mod h1:XOrocE+pvK1xFfleEnShBlNAXf+j5blPPxrhjKgnIFc=\ncloud.google.com/go/baremetalsolution v0.4.0/go.mod h1:BymplhAadOO/eBa7KewQ0Ppg4A4Wplbn+PsFKRLo0uI=\ncloud.google.com/go/baremetalsolution v0.5.0/go.mod h1:dXGxEkmR9BMwxhzBhV0AioD0ULBmuLZI8CdwalUxuss=\ncloud.google.com/go/baremetalsolution v1.3.0/go.mod h1:E+n44UaDVO5EeSa4SUsDFxQLt6dD1CoE2h+mtxxaJKo=\ncloud.google.com/go/batch v0.3.0/go.mod h1:TR18ZoAekj1GuirsUsR1ZTKN3FC/4UDnScjT8NXImFE=\ncloud.google.com/go/batch v0.4.0/go.mod h1:WZkHnP43R/QCGQsZ+0JyG4i79ranE2u8xvjq/9+STPE=\ncloud.google.com/go/batch v0.7.0/go.mod h1:vLZN95s6teRUqRQ4s3RLDsH8PvboqBK+rn1oevL159g=\ncloud.google.com/go/batch v1.10.0/go.mod h1:JlktZqyKbcUJWdHOV8juvAiQNH8xXHXTqLp6bD9qreE=\ncloud.google.com/go/beyondcorp v0.2.0/go.mod h1:TB7Bd+EEtcw9PCPQhCJtJGjk/7TC6ckmnSFS+xwTfm4=\ncloud.google.com/go/beyondcorp v0.3.0/go.mod h1:E5U5lcrcXMsCuoDNyGrpyTm/hn7ne941Jz2vmksAxW8=\ncloud.google.com/go/beyondcorp v0.4.0/go.mod h1:3ApA0mbhHx6YImmuubf5pyW8srKnCEPON32/5hj+RmM=\ncloud.google.com/go/beyondcorp v0.5.0/go.mod h1:uFqj9X+dSfrheVp7ssLTaRHd2EHqSL4QZmH4e8WXGGU=\ncloud.google.com/go/beyondcorp v1.1.0/go.mod h1:F6Rl20QbayaloWIsMhuz+DICcJxckdFKc7R2HCe6iNA=\ncloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=\ncloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=\ncloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=\ncloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=\ncloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=\ncloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=\ncloud.google.com/go/bigquery v1.42.0/go.mod h1:8dRTJxhtG+vwBKzE5OseQn/hiydoQN3EedCaOdYmxRA=\ncloud.google.com/go/bigquery v1.43.0/go.mod h1:ZMQcXHsl+xmU1z36G2jNGZmKp9zNY5BUua5wDgmNCfw=\ncloud.google.com/go/bigquery v1.44.0/go.mod h1:0Y33VqXTEsbamHJvJHdFmtqHvMIY28aK1+dFsvaChGc=\ncloud.google.com/go/bigquery v1.47.0/go.mod h1:sA9XOgy0A8vQK9+MWhEQTY6Tix87M/ZurWFIxmF9I/E=\ncloud.google.com/go/bigquery v1.48.0/go.mod h1:QAwSz+ipNgfL5jxiaK7weyOhzdoAy1zFm0Nf1fysJac=\ncloud.google.com/go/bigquery v1.49.0/go.mod h1:Sv8hMmTFFYBlt/ftw2uN6dFdQPzBlREY9yBh7Oy7/4Q=\ncloud.google.com/go/bigquery v1.50.0/go.mod h1:YrleYEh2pSEbgTBZYMJ5SuSr0ML3ypjRB1zgf7pvQLU=\ncloud.google.com/go/bigquery v1.62.0/go.mod h1:5ee+ZkF1x/ntgCsFQJAQTM3QkAZOecfCmvxhkJsWRSA=\ncloud.google.com/go/bigtable v1.31.0/go.mod h1:N/mwZO+4TSHOeyiE1JxO+sRPnW4bnR7WLn9AEaiJqew=\ncloud.google.com/go/billing v1.4.0/go.mod h1:g9IdKBEFlItS8bTtlrZdVLWSSdSyFUZKXNS02zKMOZY=\ncloud.google.com/go/billing v1.5.0/go.mod h1:mztb1tBc3QekhjSgmpf/CV4LzWXLzCArwpLmP2Gm88s=\ncloud.google.com/go/billing v1.6.0/go.mod h1:WoXzguj+BeHXPbKfNWkqVtDdzORazmCjraY+vrxcyvI=\ncloud.google.com/go/billing v1.7.0/go.mod h1:q457N3Hbj9lYwwRbnlD7vUpyjq6u5U1RAOArInEiD5Y=\ncloud.google.com/go/billing v1.12.0/go.mod h1:yKrZio/eu+okO/2McZEbch17O5CB5NpZhhXG6Z766ss=\ncloud.google.com/go/billing v1.13.0/go.mod h1:7kB2W9Xf98hP9Sr12KfECgfGclsH3CQR0R08tnRlRbc=\ncloud.google.com/go/billing v1.19.0/go.mod h1:bGvChbZguyaWRGmu5pQHfFN1VxTDPFmabnCVA/dNdRM=\ncloud.google.com/go/binaryauthorization v1.1.0/go.mod h1:xwnoWu3Y84jbuHa0zd526MJYmtnVXn0syOjaJgy4+dM=\ncloud.google.com/go/binaryauthorization v1.2.0/go.mod h1:86WKkJHtRcv5ViNABtYMhhNWRrD1Vpi//uKEy7aYEfI=\ncloud.google.com/go/binaryauthorization v1.3.0/go.mod h1:lRZbKgjDIIQvzYQS1p99A7/U1JqvqeZg0wiI5tp6tg0=\ncloud.google.com/go/binaryauthorization v1.4.0/go.mod h1:tsSPQrBd77VLplV70GUhBf/Zm3FsKmgSqgm4UmiDItk=\ncloud.google.com/go/binaryauthorization v1.5.0/go.mod h1:OSe4OU1nN/VswXKRBmciKpo9LulY41gch5c68htf3/Q=\ncloud.google.com/go/binaryauthorization v1.9.0/go.mod h1:fssQuxfI9D6dPPqfvDmObof+ZBKsxA9iSigd8aSA1ik=\ncloud.google.com/go/certificatemanager v1.3.0/go.mod h1:n6twGDvcUBFu9uBgt4eYvvf3sQ6My8jADcOVwHmzadg=\ncloud.google.com/go/certificatemanager v1.4.0/go.mod h1:vowpercVFyqs8ABSmrdV+GiFf2H/ch3KyudYQEMM590=\ncloud.google.com/go/certificatemanager v1.6.0/go.mod h1:3Hh64rCKjRAX8dXgRAyOcY5vQ/fE1sh8o+Mdd6KPgY8=\ncloud.google.com/go/certificatemanager v1.9.0/go.mod h1:hQBpwtKNjUq+er6Rdg675N7lSsNGqMgt7Bt7Dbcm7d0=\ncloud.google.com/go/channel v1.8.0/go.mod h1:W5SwCXDJsq/rg3tn3oG0LOxpAo6IMxNa09ngphpSlnk=\ncloud.google.com/go/channel v1.9.0/go.mod h1:jcu05W0my9Vx4mt3/rEHpfxc9eKi9XwsdDL8yBMbKUk=\ncloud.google.com/go/channel v1.11.0/go.mod h1:IdtI0uWGqhEeatSB62VOoJ8FSUhJ9/+iGkJVqp74CGE=\ncloud.google.com/go/channel v1.12.0/go.mod h1:VkxCGKASi4Cq7TbXxlaBezonAYpp1GCnKMY6tnMQnLU=\ncloud.google.com/go/channel v1.18.0/go.mod h1:gQr50HxC/FGvufmqXD631ldL1Ee7CNMU5F4pDyJWlt0=\ncloud.google.com/go/cloudbuild v1.3.0/go.mod h1:WequR4ULxlqvMsjDEEEFnOG5ZSRSgWOywXYDb1vPE6U=\ncloud.google.com/go/cloudbuild v1.4.0/go.mod h1:5Qwa40LHiOXmz3386FrjrYM93rM/hdRr7b53sySrTqA=\ncloud.google.com/go/cloudbuild v1.6.0/go.mod h1:UIbc/w9QCbH12xX+ezUsgblrWv+Cv4Tw83GiSMHOn9M=\ncloud.google.com/go/cloudbuild v1.7.0/go.mod h1:zb5tWh2XI6lR9zQmsm1VRA+7OCuve5d8S+zJUul8KTg=\ncloud.google.com/go/cloudbuild v1.9.0/go.mod h1:qK1d7s4QlO0VwfYn5YuClDGg2hfmLZEb4wQGAbIgL1s=\ncloud.google.com/go/cloudbuild v1.17.0/go.mod h1:/RbwgDlbQEwIKoWLIYnW72W3cWs+e83z7nU45xRKnj8=\ncloud.google.com/go/clouddms v1.3.0/go.mod h1:oK6XsCDdW4Ib3jCCBugx+gVjevp2TMXFtgxvPSee3OM=\ncloud.google.com/go/clouddms v1.4.0/go.mod h1:Eh7sUGCC+aKry14O1NRljhjyrr0NFC0G2cjwX0cByRk=\ncloud.google.com/go/clouddms v1.5.0/go.mod h1:QSxQnhikCLUw13iAbffF2CZxAER3xDGNHjsTAkQJcQA=\ncloud.google.com/go/clouddms v1.8.0/go.mod h1:JUgTgqd1M9iPa7p3jodjLTuecdkGTcikrg7nz++XB5E=\ncloud.google.com/go/cloudtasks v1.5.0/go.mod h1:fD92REy1x5woxkKEkLdvavGnPJGEn8Uic9nWuLzqCpY=\ncloud.google.com/go/cloudtasks v1.6.0/go.mod h1:C6Io+sxuke9/KNRkbQpihnW93SWDU3uXt92nu85HkYI=\ncloud.google.com/go/cloudtasks v1.7.0/go.mod h1:ImsfdYWwlWNJbdgPIIGJWC+gemEGTBK/SunNQQNCAb4=\ncloud.google.com/go/cloudtasks v1.8.0/go.mod h1:gQXUIwCSOI4yPVK7DgTVFiiP0ZW/eQkydWzwVMdHxrI=\ncloud.google.com/go/cloudtasks v1.9.0/go.mod h1:w+EyLsVkLWHcOaqNEyvcKAsWp9p29dL6uL9Nst1cI7Y=\ncloud.google.com/go/cloudtasks v1.10.0/go.mod h1:NDSoTLkZ3+vExFEWu2UJV1arUyzVDAiZtdWcsUyNwBs=\ncloud.google.com/go/cloudtasks v1.13.0/go.mod h1:O1jFRGb1Vm3sN2u/tBdPiVGVTWIsrsbEs3K3N3nNlEU=\ncloud.google.com/go/compute v0.1.0/go.mod h1:GAesmwr110a34z04OlxYkATPBEfVhkymfTBXtfbBFow=\ncloud.google.com/go/compute v1.3.0/go.mod h1:cCZiE1NHEtai4wiufUhW8I8S1JKkAnhnQJWM7YD99wM=\ncloud.google.com/go/compute v1.5.0/go.mod h1:9SMHyhJlzhlkJqrPAc839t2BZFTSk6Jdj6mkzQJeu0M=\ncloud.google.com/go/compute v1.6.0/go.mod h1:T29tfhtVbq1wvAPo0E3+7vhgmkOYeXjhFvz/FMzPu0s=\ncloud.google.com/go/compute v1.6.1/go.mod h1:g85FgpzFvNULZ+S8AYq87axRKuf2Kh7deLqV/jJ3thU=\ncloud.google.com/go/compute v1.7.0/go.mod h1:435lt8av5oL9P3fv1OEzSbSUe+ybHXGMPQHHZWZxy9U=\ncloud.google.com/go/compute v1.10.0/go.mod h1:ER5CLbMxl90o2jtNbGSbtfOpQKR0t15FOtRsugnLrlU=\ncloud.google.com/go/compute v1.12.0/go.mod h1:e8yNOBcBONZU1vJKCvCoDw/4JQsA0dpM4x/6PIIOocU=\ncloud.google.com/go/compute v1.12.1/go.mod h1:e8yNOBcBONZU1vJKCvCoDw/4JQsA0dpM4x/6PIIOocU=\ncloud.google.com/go/compute v1.13.0/go.mod h1:5aPTS0cUNMIc1CE546K+Th6weJUNQErARyZtRXDJ8GE=\ncloud.google.com/go/compute v1.14.0/go.mod h1:YfLtxrj9sU4Yxv+sXzZkyPjEyPBZfXHUvjxega5vAdo=\ncloud.google.com/go/compute v1.15.1/go.mod h1:bjjoF/NtFUrkD/urWfdHaKuOPDR5nWIs63rR+SXhcpA=\ncloud.google.com/go/compute v1.18.0/go.mod h1:1X7yHxec2Ga+Ss6jPyjxRxpu2uu7PLgsOVXvgU0yacs=\ncloud.google.com/go/compute v1.19.0/go.mod h1:rikpw2y+UMidAe9tISo04EHNOIf42RLYF/q8Bs93scU=\ncloud.google.com/go/compute v1.19.1/go.mod h1:6ylj3a05WF8leseCdIf77NK0g1ey+nj5IKd5/kvShxE=\ncloud.google.com/go/compute v1.28.0/go.mod h1:DEqZBtYrDnD5PvjsKwb3onnhX+qjdCVM7eshj1XdjV4=\ncloud.google.com/go/compute/metadata v0.1.0/go.mod h1:Z1VN+bulIf6bt4P/C37K4DyZYZEXYonfTBHHFPO/4UU=\ncloud.google.com/go/compute/metadata v0.2.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k=\ncloud.google.com/go/compute/metadata v0.2.1/go.mod h1:jgHgmJd2RKBGzXqF5LR2EZMGxBkeanZ9wwa75XHJgOM=\ncloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA=\ncloud.google.com/go/compute/metadata v0.5.0/go.mod h1:aHnloV2TPI38yx4s9+wAZhHykWvVCfu7hQbF+9CWoiY=\ncloud.google.com/go/contactcenterinsights v1.3.0/go.mod h1:Eu2oemoePuEFc/xKFPjbTuPSj0fYJcPls9TFlPNnHHY=\ncloud.google.com/go/contactcenterinsights v1.4.0/go.mod h1:L2YzkGbPsv+vMQMCADxJoT9YiTTnSEd6fEvCeHTYVck=\ncloud.google.com/go/contactcenterinsights v1.6.0/go.mod h1:IIDlT6CLcDoyv79kDv8iWxMSTZhLxSCofVV5W6YFM/w=\ncloud.google.com/go/contactcenterinsights v1.14.0/go.mod h1:APmWYHDN4sASnUBnXs4o68t1EUfnqadA53//CzXZ1xE=\ncloud.google.com/go/container v1.6.0/go.mod h1:Xazp7GjJSeUYo688S+6J5V+n/t+G5sKBTFkKNudGRxg=\ncloud.google.com/go/container v1.7.0/go.mod h1:Dp5AHtmothHGX3DwwIHPgq45Y8KmNsgN3amoYfxVkLo=\ncloud.google.com/go/container v1.13.1/go.mod h1:6wgbMPeQRw9rSnKBCAJXnds3Pzj03C4JHamr8asWKy4=\ncloud.google.com/go/container v1.14.0/go.mod h1:3AoJMPhHfLDxLvrlVWaK57IXzaPnLaZq63WX59aQBfM=\ncloud.google.com/go/container v1.15.0/go.mod h1:ft+9S0WGjAyjDggg5S06DXj+fHJICWg8L7isCQe9pQA=\ncloud.google.com/go/container v1.39.0/go.mod h1:gNgnvs1cRHXjYxrotVm+0nxDfZkqzBbXCffh5WtqieI=\ncloud.google.com/go/containeranalysis v0.5.1/go.mod h1:1D92jd8gRR/c0fGMlymRgxWD3Qw9C1ff6/T7mLgVL8I=\ncloud.google.com/go/containeranalysis v0.6.0/go.mod h1:HEJoiEIu+lEXM+k7+qLCci0h33lX3ZqoYFdmPcoO7s4=\ncloud.google.com/go/containeranalysis v0.7.0/go.mod h1:9aUL+/vZ55P2CXfuZjS4UjQ9AgXoSw8Ts6lemfmxBxI=\ncloud.google.com/go/containeranalysis v0.9.0/go.mod h1:orbOANbwk5Ejoom+s+DUCTTJ7IBdBQJDcSylAx/on9s=\ncloud.google.com/go/containeranalysis v0.13.0/go.mod h1:OpufGxsNzMOZb6w5yqwUgHr5GHivsAD18KEI06yGkQs=\ncloud.google.com/go/datacatalog v1.3.0/go.mod h1:g9svFY6tuR+j+hrTw3J2dNcmI0dzmSiyOzm8kpLq0a0=\ncloud.google.com/go/datacatalog v1.5.0/go.mod h1:M7GPLNQeLfWqeIm3iuiruhPzkt65+Bx8dAKvScX8jvs=\ncloud.google.com/go/datacatalog v1.6.0/go.mod h1:+aEyF8JKg+uXcIdAmmaMUmZ3q1b/lKLtXCmXdnc0lbc=\ncloud.google.com/go/datacatalog v1.7.0/go.mod h1:9mEl4AuDYWw81UGc41HonIHH7/sn52H0/tc8f8ZbZIE=\ncloud.google.com/go/datacatalog v1.8.0/go.mod h1:KYuoVOv9BM8EYz/4eMFxrr4DUKhGIOXxZoKYF5wdISM=\ncloud.google.com/go/datacatalog v1.8.1/go.mod h1:RJ58z4rMp3gvETA465Vg+ag8BGgBdnRPEMMSTr5Uv+M=\ncloud.google.com/go/datacatalog v1.12.0/go.mod h1:CWae8rFkfp6LzLumKOnmVh4+Zle4A3NXLzVJ1d1mRm0=\ncloud.google.com/go/datacatalog v1.13.0/go.mod h1:E4Rj9a5ZtAxcQJlEBTLgMTphfP11/lNaAshpoBgemX8=\ncloud.google.com/go/datacatalog v1.22.0/go.mod h1:4Wff6GphTY6guF5WphrD76jOdfBiflDiRGFAxq7t//I=\ncloud.google.com/go/dataflow v0.6.0/go.mod h1:9QwV89cGoxjjSR9/r7eFDqqjtvbKxAK2BaYU6PVk9UM=\ncloud.google.com/go/dataflow v0.7.0/go.mod h1:PX526vb4ijFMesO1o202EaUmouZKBpjHsTlCtB4parQ=\ncloud.google.com/go/dataflow v0.8.0/go.mod h1:Rcf5YgTKPtQyYz8bLYhFoIV/vP39eL7fWNcSOyFfLJE=\ncloud.google.com/go/dataflow v0.10.0/go.mod h1:zAv3YUNe/2pXWKDSPvbf31mCIUuJa+IHtKmhfzaeGww=\ncloud.google.com/go/dataform v0.3.0/go.mod h1:cj8uNliRlHpa6L3yVhDOBrUXH+BPAO1+KFMQQNSThKo=\ncloud.google.com/go/dataform v0.4.0/go.mod h1:fwV6Y4Ty2yIFL89huYlEkwUPtS7YZinZbzzj5S9FzCE=\ncloud.google.com/go/dataform v0.5.0/go.mod h1:GFUYRe8IBa2hcomWplodVmUx/iTL0FrsauObOM3Ipr0=\ncloud.google.com/go/dataform v0.6.0/go.mod h1:QPflImQy33e29VuapFdf19oPbE4aYTJxr31OAPV+ulA=\ncloud.google.com/go/dataform v0.7.0/go.mod h1:7NulqnVozfHvWUBpMDfKMUESr+85aJsC/2O0o3jWPDE=\ncloud.google.com/go/dataform v0.10.0/go.mod h1:0NKefI6v1ppBEDnwrp6gOMEA3s/RH3ypLUM0+YWqh6A=\ncloud.google.com/go/datafusion v1.4.0/go.mod h1:1Zb6VN+W6ALo85cXnM1IKiPw+yQMKMhB9TsTSRDo/38=\ncloud.google.com/go/datafusion v1.5.0/go.mod h1:Kz+l1FGHB0J+4XF2fud96WMmRiq/wj8N9u007vyXZ2w=\ncloud.google.com/go/datafusion v1.6.0/go.mod h1:WBsMF8F1RhSXvVM8rCV3AeyWVxcC2xY6vith3iw3S+8=\ncloud.google.com/go/datafusion v1.8.0/go.mod h1:zHZ5dJYHhMP1P8SZDZm+6yRY9BCCcfm7Xg7YmP+iA6E=\ncloud.google.com/go/datalabeling v0.5.0/go.mod h1:TGcJ0G2NzcsXSE/97yWjIZO0bXj0KbVlINXMG9ud42I=\ncloud.google.com/go/datalabeling v0.6.0/go.mod h1:WqdISuk/+WIGeMkpw/1q7bK/tFEZxsrFJOJdY2bXvTQ=\ncloud.google.com/go/datalabeling v0.7.0/go.mod h1:WPQb1y08RJbmpM3ww0CSUAGweL0SxByuW2E+FU+wXcM=\ncloud.google.com/go/datalabeling v0.9.0/go.mod h1:GVX4sW4cY5OPKu/9v6dv20AU9xmGr4DXR6K26qN0mzw=\ncloud.google.com/go/dataplex v1.3.0/go.mod h1:hQuRtDg+fCiFgC8j0zV222HvzFQdRd+SVX8gdmFcZzA=\ncloud.google.com/go/dataplex v1.4.0/go.mod h1:X51GfLXEMVJ6UN47ESVqvlsRplbLhcsAt0kZCCKsU0A=\ncloud.google.com/go/dataplex v1.5.2/go.mod h1:cVMgQHsmfRoI5KFYq4JtIBEUbYwc3c7tXmIDhRmNNVQ=\ncloud.google.com/go/dataplex v1.6.0/go.mod h1:bMsomC/aEJOSpHXdFKFGQ1b0TDPIeL28nJObeO1ppRs=\ncloud.google.com/go/dataplex v1.19.0/go.mod h1:5H9ftGuZWMtoEIUpTdGUtGgje36YGmtRXoC8wx6QSUc=\ncloud.google.com/go/dataproc v1.7.0/go.mod h1:CKAlMjII9H90RXaMpSxQ8EU6dQx6iAYNPcYPOkSbi8s=\ncloud.google.com/go/dataproc v1.8.0/go.mod h1:5OW+zNAH0pMpw14JVrPONsxMQYMBqJuzORhIBfBn9uI=\ncloud.google.com/go/dataproc v1.12.0/go.mod h1:zrF3aX0uV3ikkMz6z4uBbIKyhRITnxvr4i3IjKsKrw4=\ncloud.google.com/go/dataproc/v2 v2.6.0/go.mod h1:amsKInI+TU4GcXnz+gmmApYbiYM4Fw051SIMDoWCWeE=\ncloud.google.com/go/dataqna v0.5.0/go.mod h1:90Hyk596ft3zUQ8NkFfvICSIfHFh1Bc7C4cK3vbhkeo=\ncloud.google.com/go/dataqna v0.6.0/go.mod h1:1lqNpM7rqNLVgWBJyk5NF6Uen2PHym0jtVJonplVsDA=\ncloud.google.com/go/dataqna v0.7.0/go.mod h1:Lx9OcIIeqCrw1a6KdO3/5KMP1wAmTc0slZWwP12Qq3c=\ncloud.google.com/go/dataqna v0.9.0/go.mod h1:WlRhvLLZv7TfpONlb/rEQx5Qrr7b5sxgSuz5NP6amrw=\ncloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=\ncloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=\ncloud.google.com/go/datastore v1.10.0/go.mod h1:PC5UzAmDEkAmkfaknstTYbNpgE49HAgW2J1gcgUfmdM=\ncloud.google.com/go/datastore v1.11.0/go.mod h1:TvGxBIHCS50u8jzG+AW/ppf87v1of8nwzFNgEZU1D3c=\ncloud.google.com/go/datastore v1.19.0/go.mod h1:KGzkszuj87VT8tJe67GuB+qLolfsOt6bZq/KFuWaahc=\ncloud.google.com/go/datastream v1.2.0/go.mod h1:i/uTP8/fZwgATHS/XFu0TcNUhuA0twZxxQ3EyCUQMwo=\ncloud.google.com/go/datastream v1.3.0/go.mod h1:cqlOX8xlyYF/uxhiKn6Hbv6WjwPPuI9W2M9SAXwaLLQ=\ncloud.google.com/go/datastream v1.4.0/go.mod h1:h9dpzScPhDTs5noEMQVWP8Wx8AFBRyS0s8KWPx/9r0g=\ncloud.google.com/go/datastream v1.5.0/go.mod h1:6TZMMNPwjUqZHBKPQ1wwXpb0d5VDVPl2/XoS5yi88q4=\ncloud.google.com/go/datastream v1.6.0/go.mod h1:6LQSuswqLa7S4rPAOZFVjHIG3wJIjZcZrw8JDEDJuIs=\ncloud.google.com/go/datastream v1.7.0/go.mod h1:uxVRMm2elUSPuh65IbZpzJNMbuzkcvu5CjMqVIUHrww=\ncloud.google.com/go/datastream v1.11.0/go.mod h1:vio/5TQ0qNtGcIj7sFb0gucFoqZW19gZ7HztYtkzq9g=\ncloud.google.com/go/deploy v1.4.0/go.mod h1:5Xghikd4VrmMLNaF6FiRFDlHb59VM59YoDQnOUdsH/c=\ncloud.google.com/go/deploy v1.5.0/go.mod h1:ffgdD0B89tToyW/U/D2eL0jN2+IEV/3EMuXHA0l4r+s=\ncloud.google.com/go/deploy v1.6.0/go.mod h1:f9PTHehG/DjCom3QH0cntOVRm93uGBDt2vKzAPwpXQI=\ncloud.google.com/go/deploy v1.8.0/go.mod h1:z3myEJnA/2wnB4sgjqdMfgxCA0EqC3RBTNcVPs93mtQ=\ncloud.google.com/go/deploy v1.22.0/go.mod h1:qXJgBcnyetoOe+w/79sCC99c5PpHJsgUXCNhwMjG0e4=\ncloud.google.com/go/dialogflow v1.15.0/go.mod h1:HbHDWs33WOGJgn6rfzBW1Kv807BE3O1+xGbn59zZWI4=\ncloud.google.com/go/dialogflow v1.16.1/go.mod h1:po6LlzGfK+smoSmTBnbkIZY2w8ffjz/RcGSS+sh1el0=\ncloud.google.com/go/dialogflow v1.17.0/go.mod h1:YNP09C/kXA1aZdBgC/VtXX74G/TKn7XVCcVumTflA+8=\ncloud.google.com/go/dialogflow v1.18.0/go.mod h1:trO7Zu5YdyEuR+BhSNOqJezyFQ3aUzz0njv7sMx/iek=\ncloud.google.com/go/dialogflow v1.19.0/go.mod h1:JVmlG1TwykZDtxtTXujec4tQ+D8SBFMoosgy+6Gn0s0=\ncloud.google.com/go/dialogflow v1.29.0/go.mod h1:b+2bzMe+k1s9V+F2jbJwpHPzrnIyHihAdRFMtn2WXuM=\ncloud.google.com/go/dialogflow v1.31.0/go.mod h1:cuoUccuL1Z+HADhyIA7dci3N5zUssgpBJmCzI6fNRB4=\ncloud.google.com/go/dialogflow v1.32.0/go.mod h1:jG9TRJl8CKrDhMEcvfcfFkkpp8ZhgPz3sBGmAUYJ2qE=\ncloud.google.com/go/dialogflow v1.57.0/go.mod h1:wegtnocuYEfue6IGlX96n5mHu3JGZUaZxv1L5HzJUJY=\ncloud.google.com/go/dlp v1.6.0/go.mod h1:9eyB2xIhpU0sVwUixfBubDoRwP+GjeUoxxeueZmqvmM=\ncloud.google.com/go/dlp v1.7.0/go.mod h1:68ak9vCiMBjbasxeVD17hVPxDEck+ExiHavX8kiHG+Q=\ncloud.google.com/go/dlp v1.9.0/go.mod h1:qdgmqgTyReTz5/YNSSuueR8pl7hO0o9bQ39ZhtgkWp4=\ncloud.google.com/go/dlp v1.18.0/go.mod h1:RVO9zkh+xXgUa7+YOf9IFNHL/2FXt9Vnv/GKNYmc1fE=\ncloud.google.com/go/documentai v1.7.0/go.mod h1:lJvftZB5NRiFSX4moiye1SMxHx0Bc3x1+p9e/RfXYiU=\ncloud.google.com/go/documentai v1.8.0/go.mod h1:xGHNEB7CtsnySCNrCFdCyyMz44RhFEEX2Q7UD0c5IhU=\ncloud.google.com/go/documentai v1.9.0/go.mod h1:FS5485S8R00U10GhgBC0aNGrJxBP8ZVpEeJ7PQDZd6k=\ncloud.google.com/go/documentai v1.10.0/go.mod h1:vod47hKQIPeCfN2QS/jULIvQTugbmdc0ZvxxfQY1bg4=\ncloud.google.com/go/documentai v1.16.0/go.mod h1:o0o0DLTEZ+YnJZ+J4wNfTxmDVyrkzFvttBXXtYRMHkM=\ncloud.google.com/go/documentai v1.18.0/go.mod h1:F6CK6iUH8J81FehpskRmhLq/3VlwQvb7TvwOceQ2tbs=\ncloud.google.com/go/documentai v1.33.0/go.mod h1:lI9Mti9COZ5qVjdpfDZxNjOrTVf6tJ//vaqbtt81214=\ncloud.google.com/go/domains v0.6.0/go.mod h1:T9Rz3GasrpYk6mEGHh4rymIhjlnIuB4ofT1wTxDeT4Y=\ncloud.google.com/go/domains v0.7.0/go.mod h1:PtZeqS1xjnXuRPKE/88Iru/LdfoRyEHYA9nFQf4UKpg=\ncloud.google.com/go/domains v0.8.0/go.mod h1:M9i3MMDzGFXsydri9/vW+EWz9sWb4I6WyHqdlAk0idE=\ncloud.google.com/go/domains v0.10.0/go.mod h1:VpPXnkCNRsxkieDFDfjBIrLv3p1kRjJ03wLoPeL30To=\ncloud.google.com/go/edgecontainer v0.1.0/go.mod h1:WgkZ9tp10bFxqO8BLPqv2LlfmQF1X8lZqwW4r1BTajk=\ncloud.google.com/go/edgecontainer v0.2.0/go.mod h1:RTmLijy+lGpQ7BXuTDa4C4ssxyXT34NIuHIgKuP4s5w=\ncloud.google.com/go/edgecontainer v0.3.0/go.mod h1:FLDpP4nykgwwIfcLt6zInhprzw0lEi2P1fjO6Ie0qbc=\ncloud.google.com/go/edgecontainer v1.0.0/go.mod h1:cttArqZpBB2q58W/upSG++ooo6EsblxDIolxa3jSjbY=\ncloud.google.com/go/edgecontainer v1.3.0/go.mod h1:dV1qTl2KAnQOYG+7plYr53KSq/37aga5/xPgOlYXh3A=\ncloud.google.com/go/errorreporting v0.3.0/go.mod h1:xsP2yaAp+OAW4OIm60An2bbLpqIhKXdWR/tawvl7QzU=\ncloud.google.com/go/errorreporting v0.3.1/go.mod h1:6xVQXU1UuntfAf+bVkFk6nld41+CPyF2NSPCyXE3Ztk=\ncloud.google.com/go/essentialcontacts v1.3.0/go.mod h1:r+OnHa5jfj90qIfZDO/VztSFqbQan7HV75p8sA+mdGI=\ncloud.google.com/go/essentialcontacts v1.4.0/go.mod h1:8tRldvHYsmnBCHdFpvU+GL75oWiBKl80BiqlFh9tp+8=\ncloud.google.com/go/essentialcontacts v1.5.0/go.mod h1:ay29Z4zODTuwliK7SnX8E86aUF2CTzdNtvv42niCX0M=\ncloud.google.com/go/essentialcontacts v1.7.0/go.mod h1:0JEcNuyjyg43H/RJynZzv2eo6MkmnvRPUouBpOh6akY=\ncloud.google.com/go/eventarc v1.7.0/go.mod h1:6ctpF3zTnaQCxUjHUdcfgcA1A2T309+omHZth7gDfmc=\ncloud.google.com/go/eventarc v1.8.0/go.mod h1:imbzxkyAU4ubfsaKYdQg04WS1NvncblHEup4kvF+4gw=\ncloud.google.com/go/eventarc v1.10.0/go.mod h1:u3R35tmZ9HvswGRBnF48IlYgYeBcPUCjkr4BTdem2Kw=\ncloud.google.com/go/eventarc v1.11.0/go.mod h1:PyUjsUKPWoRBCHeOxZd/lbOOjahV41icXyUY5kSTvVY=\ncloud.google.com/go/eventarc v1.14.0/go.mod h1:60ZzZfOekvsc/keHc7uGHcoEOMVa+p+ZgRmTjpdamnA=\ncloud.google.com/go/filestore v1.3.0/go.mod h1:+qbvHGvXU1HaKX2nD0WEPo92TP/8AQuCVEBXNY9z0+w=\ncloud.google.com/go/filestore v1.4.0/go.mod h1:PaG5oDfo9r224f8OYXURtAsY+Fbyq/bLYoINEK8XQAI=\ncloud.google.com/go/filestore v1.5.0/go.mod h1:FqBXDWBp4YLHqRnVGveOkHDf8svj9r5+mUDLupOWEDs=\ncloud.google.com/go/filestore v1.6.0/go.mod h1:di5unNuss/qfZTw2U9nhFqo8/ZDSc466dre85Kydllg=\ncloud.google.com/go/filestore v1.9.0/go.mod h1:GlQK+VBaAGb19HqprnOMqYYpn7Gev5ZA9SSHpxFKD7Q=\ncloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk=\ncloud.google.com/go/firestore v1.9.0/go.mod h1:HMkjKHNTtRyZNiMzu7YAsLr9K3X2udY2AMwDaMEQiiE=\ncloud.google.com/go/firestore v1.16.0/go.mod h1:+22v/7p+WNBSQwdSwP57vz47aZiY+HrDkrOsJNhk7rg=\ncloud.google.com/go/functions v1.6.0/go.mod h1:3H1UA3qiIPRWD7PeZKLvHZ9SaQhR26XIJcC0A5GbvAk=\ncloud.google.com/go/functions v1.7.0/go.mod h1:+d+QBcWM+RsrgZfV9xo6KfA1GlzJfxcfZcRPEhDDfzg=\ncloud.google.com/go/functions v1.8.0/go.mod h1:RTZ4/HsQjIqIYP9a9YPbU+QFoQsAlYgrwOXJWHn1POY=\ncloud.google.com/go/functions v1.9.0/go.mod h1:Y+Dz8yGguzO3PpIjhLTbnqV1CWmgQ5UwtlpzoyquQ08=\ncloud.google.com/go/functions v1.10.0/go.mod h1:0D3hEOe3DbEvCXtYOZHQZmD+SzYsi1YbI7dGvHfldXw=\ncloud.google.com/go/functions v1.12.0/go.mod h1:AXWGrF3e2C/5ehvwYo/GH6O5s09tOPksiKhz+hH8WkA=\ncloud.google.com/go/functions v1.13.0/go.mod h1:EU4O007sQm6Ef/PwRsI8N2umygGqPBS/IZQKBQBcJ3c=\ncloud.google.com/go/functions v1.19.0/go.mod h1:WDreEDZoUVoOkXKDejFWGnprrGYn2cY2KHx73UQERC0=\ncloud.google.com/go/gaming v1.5.0/go.mod h1:ol7rGcxP/qHTRQE/RO4bxkXq+Fix0j6D4LFPzYTIrDM=\ncloud.google.com/go/gaming v1.6.0/go.mod h1:YMU1GEvA39Qt3zWGyAVA9bpYz/yAhTvaQ1t2sK4KPUA=\ncloud.google.com/go/gaming v1.7.0/go.mod h1:LrB8U7MHdGgFG851iHAfqUdLcKBdQ55hzXy9xBJz0+w=\ncloud.google.com/go/gaming v1.8.0/go.mod h1:xAqjS8b7jAVW0KFYeRUxngo9My3f33kFmua++Pi+ggM=\ncloud.google.com/go/gaming v1.9.0/go.mod h1:Fc7kEmCObylSWLO334NcO+O9QMDyz+TKC4v1D7X+Bc0=\ncloud.google.com/go/gaming v1.10.1/go.mod h1:XQQvtfP8Rb9Rxnxm5wFVpAp9zCQkJi2bLIb7iHGwB3s=\ncloud.google.com/go/gkebackup v0.2.0/go.mod h1:XKvv/4LfG829/B8B7xRkk8zRrOEbKtEam6yNfuQNH60=\ncloud.google.com/go/gkebackup v0.3.0/go.mod h1:n/E671i1aOQvUxT541aTkCwExO/bTer2HDlj4TsBRAo=\ncloud.google.com/go/gkebackup v0.4.0/go.mod h1:byAyBGUwYGEEww7xsbnUTBHIYcOPy/PgUWUtOeRm9Vg=\ncloud.google.com/go/gkebackup v1.6.0/go.mod h1:1rskt7NgawoMDHTdLASX8caXXYG3MvDsoZ7qF4RMamQ=\ncloud.google.com/go/gkeconnect v0.5.0/go.mod h1:c5lsNAg5EwAy7fkqX/+goqFsU1Da/jQFqArp+wGNr/o=\ncloud.google.com/go/gkeconnect v0.6.0/go.mod h1:Mln67KyU/sHJEBY8kFZ0xTeyPtzbq9StAVvEULYK16A=\ncloud.google.com/go/gkeconnect v0.7.0/go.mod h1:SNfmVqPkaEi3bF/B3CNZOAYPYdg7sU+obZ+QTky2Myw=\ncloud.google.com/go/gkeconnect v0.11.0/go.mod h1:l3iPZl1OfT+DUQ+QkmH1PC5RTLqxKQSVnboLiQGAcCA=\ncloud.google.com/go/gkehub v0.9.0/go.mod h1:WYHN6WG8w9bXU0hqNxt8rm5uxnk8IH+lPY9J2TV7BK0=\ncloud.google.com/go/gkehub v0.10.0/go.mod h1:UIPwxI0DsrpsVoWpLB0stwKCP+WFVG9+y977wO+hBH0=\ncloud.google.com/go/gkehub v0.11.0/go.mod h1:JOWHlmN+GHyIbuWQPl47/C2RFhnFKH38jH9Ascu3n0E=\ncloud.google.com/go/gkehub v0.12.0/go.mod h1:djiIwwzTTBrF5NaXCGv3mf7klpEMcST17VBTVVDcuaw=\ncloud.google.com/go/gkehub v0.15.0/go.mod h1:obpeROly2mjxZJbRkFfHEflcH54XhJI+g2QgfHphL0I=\ncloud.google.com/go/gkemulticloud v0.3.0/go.mod h1:7orzy7O0S+5kq95e4Hpn7RysVA7dPs8W/GgfUtsPbrA=\ncloud.google.com/go/gkemulticloud v0.4.0/go.mod h1:E9gxVBnseLWCk24ch+P9+B2CoDFJZTyIgLKSalC7tuI=\ncloud.google.com/go/gkemulticloud v0.5.0/go.mod h1:W0JDkiyi3Tqh0TJr//y19wyb1yf8llHVto2Htf2Ja3Y=\ncloud.google.com/go/gkemulticloud v1.3.0/go.mod h1:XmcOUQ+hJI62fi/klCjEGs6lhQ56Zjs14sGPXsGP0mE=\ncloud.google.com/go/grafeas v0.2.0/go.mod h1:KhxgtF2hb0P191HlY5besjYm6MqTSTj3LSI+M+ByZHc=\ncloud.google.com/go/grafeas v0.3.10/go.mod h1:Mz/AoXmxNhj74VW0fz5Idc3kMN2VZMi4UT5+UPx5Pq0=\ncloud.google.com/go/gsuiteaddons v1.3.0/go.mod h1:EUNK/J1lZEZO8yPtykKxLXI6JSVN2rg9bN8SXOa0bgM=\ncloud.google.com/go/gsuiteaddons v1.4.0/go.mod h1:rZK5I8hht7u7HxFQcFei0+AtfS9uSushomRlg+3ua1o=\ncloud.google.com/go/gsuiteaddons v1.5.0/go.mod h1:TFCClYLd64Eaa12sFVmUyG62tk4mdIsI7pAnSXRkcFo=\ncloud.google.com/go/gsuiteaddons v1.7.0/go.mod h1:/B1L8ANPbiSvxCgdSwqH9CqHIJBzTt6v50fPr3vJCtg=\ncloud.google.com/go/iam v0.1.0/go.mod h1:vcUNEa0pEm0qRVpmWepWaFMIAI8/hjB9mO8rNCJtF6c=\ncloud.google.com/go/iam v0.3.0/go.mod h1:XzJPvDayI+9zsASAFO68Hk07u3z+f+JrT2xXNdp4bnY=\ncloud.google.com/go/iam v0.5.0/go.mod h1:wPU9Vt0P4UmCux7mqtRu6jcpPAb74cP1fh50J3QpkUc=\ncloud.google.com/go/iam v0.6.0/go.mod h1:+1AH33ueBne5MzYccyMHtEKqLE4/kJOibtffMHDMFMc=\ncloud.google.com/go/iam v0.7.0/go.mod h1:H5Br8wRaDGNc8XP3keLc4unfUUZeyH3Sfl9XpQEYOeg=\ncloud.google.com/go/iam v0.8.0/go.mod h1:lga0/y3iH6CX7sYqypWJ33hf7kkfXJag67naqGESjkE=\ncloud.google.com/go/iam v0.11.0/go.mod h1:9PiLDanza5D+oWFZiH1uG+RnRCfEGKoyl6yo4cgWZGY=\ncloud.google.com/go/iam v0.12.0/go.mod h1:knyHGviacl11zrtZUoDuYpDgLjvr28sLQaG0YB2GYAY=\ncloud.google.com/go/iam v0.13.0/go.mod h1:ljOg+rcNfzZ5d6f1nAUJ8ZIxOaZUVoS14bKCtaLZ/D0=\ncloud.google.com/go/iam v1.2.0/go.mod h1:zITGuWgsLZxd8OwAlX+eMFgZDXzBm7icj1PVTYG766Q=\ncloud.google.com/go/iap v1.4.0/go.mod h1:RGFwRJdihTINIe4wZ2iCP0zF/qu18ZwyKxrhMhygBEc=\ncloud.google.com/go/iap v1.5.0/go.mod h1:UH/CGgKd4KyohZL5Pt0jSKE4m3FR51qg6FKQ/z/Ix9A=\ncloud.google.com/go/iap v1.6.0/go.mod h1:NSuvI9C/j7UdjGjIde7t7HBz+QTwBcapPE07+sSRcLk=\ncloud.google.com/go/iap v1.7.0/go.mod h1:beqQx56T9O1G1yNPph+spKpNibDlYIiIixiqsQXxLIo=\ncloud.google.com/go/iap v1.7.1/go.mod h1:WapEwPc7ZxGt2jFGB/C/bm+hP0Y6NXzOYGjpPnmMS74=\ncloud.google.com/go/iap v1.10.0/go.mod h1:gDT6LZnKnWNCaov/iQbj7NMUpknFDOkhhlH8PwIrpzU=\ncloud.google.com/go/ids v1.1.0/go.mod h1:WIuwCaYVOzHIj2OhN9HAwvW+DBdmUAdcWlFxRl+KubM=\ncloud.google.com/go/ids v1.2.0/go.mod h1:5WXvp4n25S0rA/mQWAg1YEEBBq6/s+7ml1RDCW1IrcY=\ncloud.google.com/go/ids v1.3.0/go.mod h1:JBdTYwANikFKaDP6LtW5JAi4gubs57SVNQjemdt6xV4=\ncloud.google.com/go/ids v1.5.0/go.mod h1:4NOlC1m9hAJL50j2cRV4PS/J6x/f4BBM0Xg54JQLCWw=\ncloud.google.com/go/iot v1.3.0/go.mod h1:r7RGh2B61+B8oz0AGE+J72AhA0G7tdXItODWsaA2oLs=\ncloud.google.com/go/iot v1.4.0/go.mod h1:dIDxPOn0UvNDUMD8Ger7FIaTuvMkj+aGk94RPP0iV+g=\ncloud.google.com/go/iot v1.5.0/go.mod h1:mpz5259PDl3XJthEmh9+ap0affn/MqNSP4My77Qql9o=\ncloud.google.com/go/iot v1.6.0/go.mod h1:IqdAsmE2cTYYNO1Fvjfzo9po179rAtJeVGUvkLN3rLE=\ncloud.google.com/go/iot v1.8.0/go.mod h1:/NMFENPnQ2t1UByUC1qFvA80fo1KFB920BlyUPn1m3s=\ncloud.google.com/go/kms v1.4.0/go.mod h1:fajBHndQ+6ubNw6Ss2sSd+SWvjL26RNo/dr7uxsnnOA=\ncloud.google.com/go/kms v1.5.0/go.mod h1:QJS2YY0eJGBg3mnDfuaCyLauWwBJiHRboYxJ++1xJNg=\ncloud.google.com/go/kms v1.6.0/go.mod h1:Jjy850yySiasBUDi6KFUwUv2n1+o7QZFyuUJg6OgjA0=\ncloud.google.com/go/kms v1.8.0/go.mod h1:4xFEhYFqvW+4VMELtZyxomGSYtSQKzM178ylFW4jMAg=\ncloud.google.com/go/kms v1.9.0/go.mod h1:qb1tPTgfF9RQP8e1wq4cLFErVuTJv7UsSC915J8dh3w=\ncloud.google.com/go/kms v1.10.0/go.mod h1:ng3KTUtQQU9bPX3+QGLsflZIHlkbn8amFAMY63m8d24=\ncloud.google.com/go/kms v1.10.1/go.mod h1:rIWk/TryCkR59GMC3YtHtXeLzd634lBbKenvyySAyYI=\ncloud.google.com/go/kms v1.19.0/go.mod h1:e4imokuPJUc17Trz2s6lEXFDt8bgDmvpVynH39bdrHM=\ncloud.google.com/go/language v1.4.0/go.mod h1:F9dRpNFQmJbkaop6g0JhSBXCNlO90e1KWx5iDdxbWic=\ncloud.google.com/go/language v1.6.0/go.mod h1:6dJ8t3B+lUYfStgls25GusK04NLh3eDLQnWM3mdEbhI=\ncloud.google.com/go/language v1.7.0/go.mod h1:DJ6dYN/W+SQOjF8e1hLQXMF21AkH2w9wiPzPCJa2MIE=\ncloud.google.com/go/language v1.8.0/go.mod h1:qYPVHf7SPoNNiCL2Dr0FfEFNil1qi3pQEyygwpgVKB8=\ncloud.google.com/go/language v1.9.0/go.mod h1:Ns15WooPM5Ad/5no/0n81yUetis74g3zrbeJBE+ptUY=\ncloud.google.com/go/language v1.14.0/go.mod h1:ldEdlZOFwZREnn/1yWtXdNzfD7hHi9rf87YDkOY9at4=\ncloud.google.com/go/lifesciences v0.5.0/go.mod h1:3oIKy8ycWGPUyZDR/8RNnTOYevhaMLqh5vLUXs9zvT8=\ncloud.google.com/go/lifesciences v0.6.0/go.mod h1:ddj6tSX/7BOnhxCSd3ZcETvtNr8NZ6t/iPhY2Tyfu08=\ncloud.google.com/go/lifesciences v0.8.0/go.mod h1:lFxiEOMqII6XggGbOnKiyZ7IBwoIqA84ClvoezaA/bo=\ncloud.google.com/go/lifesciences v0.10.0/go.mod h1:1zMhgXQ7LbMbA5n4AYguFgbulbounfUoYvkV8dtsLcA=\ncloud.google.com/go/logging v1.6.1/go.mod h1:5ZO0mHHbvm8gEmeEUHrmDlTDSu5imF6MUP9OfilNXBw=\ncloud.google.com/go/logging v1.7.0/go.mod h1:3xjP2CjkM3ZkO73aj4ASA5wRPGGCRrPIAeNqVNkzY8M=\ncloud.google.com/go/logging v1.11.0/go.mod h1:5LDiJC/RxTt+fHc1LAt20R9TKiUTReDg6RuuFOZ67+A=\ncloud.google.com/go/longrunning v0.1.1/go.mod h1:UUFxuDWkv22EuY93jjmDMFT5GPQKeFVJBIF6QlTqdsE=\ncloud.google.com/go/longrunning v0.3.0/go.mod h1:qth9Y41RRSUE69rDcOn6DdK3HfQfsUI0YSmW3iIlLJc=\ncloud.google.com/go/longrunning v0.4.1/go.mod h1:4iWDqhBZ70CvZ6BfETbvam3T8FMvLK+eFj0E6AaRQTo=\ncloud.google.com/go/longrunning v0.6.0/go.mod h1:uHzSZqW89h7/pasCWNYdUpwGz3PcVWhrWupreVPYLts=\ncloud.google.com/go/managedidentities v1.3.0/go.mod h1:UzlW3cBOiPrzucO5qWkNkh0w33KFtBJU281hacNvsdE=\ncloud.google.com/go/managedidentities v1.4.0/go.mod h1:NWSBYbEMgqmbZsLIyKvxrYbtqOsxY1ZrGM+9RgDqInM=\ncloud.google.com/go/managedidentities v1.5.0/go.mod h1:+dWcZ0JlUmpuxpIDfyP5pP5y0bLdRwOS4Lp7gMni/LA=\ncloud.google.com/go/managedidentities v1.7.0/go.mod h1:o4LqQkQvJ9Pt7Q8CyZV39HrzCfzyX8zBzm8KIhRw91E=\ncloud.google.com/go/maps v0.1.0/go.mod h1:BQM97WGyfw9FWEmQMpZ5T6cpovXXSd1cGmFma94eubI=\ncloud.google.com/go/maps v0.6.0/go.mod h1:o6DAMMfb+aINHz/p/jbcY+mYeXBoZoxTfdSQ8VAJaCw=\ncloud.google.com/go/maps v0.7.0/go.mod h1:3GnvVl3cqeSvgMcpRlQidXsPYuDGQ8naBis7MVzpXsY=\ncloud.google.com/go/maps v1.12.0/go.mod h1:qjErDNStn3BaGx06vHner5d75MRMgGflbgCuWTuslMc=\ncloud.google.com/go/mediatranslation v0.5.0/go.mod h1:jGPUhGTybqsPQn91pNXw0xVHfuJ3leR1wj37oU3y1f4=\ncloud.google.com/go/mediatranslation v0.6.0/go.mod h1:hHdBCTYNigsBxshbznuIMFNe5QXEowAuNmmC7h8pu5w=\ncloud.google.com/go/mediatranslation v0.7.0/go.mod h1:LCnB/gZr90ONOIQLgSXagp8XUW1ODs2UmUMvcgMfI2I=\ncloud.google.com/go/mediatranslation v0.9.0/go.mod h1:udnxo0i4YJ5mZfkwvvQQrQ6ra47vcX8jeGV+6I5x+iU=\ncloud.google.com/go/memcache v1.4.0/go.mod h1:rTOfiGZtJX1AaFUrOgsMHX5kAzaTQ8azHiuDoTPzNsE=\ncloud.google.com/go/memcache v1.5.0/go.mod h1:dk3fCK7dVo0cUU2c36jKb4VqKPS22BTkf81Xq617aWM=\ncloud.google.com/go/memcache v1.6.0/go.mod h1:XS5xB0eQZdHtTuTF9Hf8eJkKtR3pVRCcvJwtm68T3rA=\ncloud.google.com/go/memcache v1.7.0/go.mod h1:ywMKfjWhNtkQTxrWxCkCFkoPjLHPW6A7WOTVI8xy3LY=\ncloud.google.com/go/memcache v1.9.0/go.mod h1:8oEyzXCu+zo9RzlEaEjHl4KkgjlNDaXbCQeQWlzNFJM=\ncloud.google.com/go/memcache v1.11.0/go.mod h1:99MVF02m5TByT1NKxsoKDnw5kYmMrjbGSeikdyfCYZk=\ncloud.google.com/go/metastore v1.5.0/go.mod h1:2ZNrDcQwghfdtCwJ33nM0+GrBGlVuh8rakL3vdPY3XY=\ncloud.google.com/go/metastore v1.6.0/go.mod h1:6cyQTls8CWXzk45G55x57DVQ9gWg7RiH65+YgPsNh9s=\ncloud.google.com/go/metastore v1.7.0/go.mod h1:s45D0B4IlsINu87/AsWiEVYbLaIMeUSoxlKKDqBGFS8=\ncloud.google.com/go/metastore v1.8.0/go.mod h1:zHiMc4ZUpBiM7twCIFQmJ9JMEkDSyZS9U12uf7wHqSI=\ncloud.google.com/go/metastore v1.10.0/go.mod h1:fPEnH3g4JJAk+gMRnrAnoqyv2lpUCqJPWOodSaf45Eo=\ncloud.google.com/go/metastore v1.14.0/go.mod h1:vtPt5oVF/+ocXO4rv4GUzC8Si5s8gfmo5OIt6bACDuE=\ncloud.google.com/go/monitoring v1.7.0/go.mod h1:HpYse6kkGo//7p6sT0wsIC6IBDET0RhIsnmlA53dvEk=\ncloud.google.com/go/monitoring v1.8.0/go.mod h1:E7PtoMJ1kQXWxPjB6mv2fhC5/15jInuulFdYYtlcvT4=\ncloud.google.com/go/monitoring v1.12.0/go.mod h1:yx8Jj2fZNEkL/GYZyTLS4ZtZEZN8WtDEiEqG4kLK50w=\ncloud.google.com/go/monitoring v1.13.0/go.mod h1:k2yMBAB1H9JT/QETjNkgdCGD9bPF712XiLTVr+cBrpw=\ncloud.google.com/go/monitoring v1.21.0/go.mod h1:tuJ+KNDdJbetSsbSGTqnaBvbauS5kr3Q/koy3Up6r+4=\ncloud.google.com/go/networkconnectivity v1.4.0/go.mod h1:nOl7YL8odKyAOtzNX73/M5/mGZgqqMeryi6UPZTk/rA=\ncloud.google.com/go/networkconnectivity v1.5.0/go.mod h1:3GzqJx7uhtlM3kln0+x5wyFvuVH1pIBJjhCpjzSt75o=\ncloud.google.com/go/networkconnectivity v1.6.0/go.mod h1:OJOoEXW+0LAxHh89nXd64uGG+FbQoeH8DtxCHVOMlaM=\ncloud.google.com/go/networkconnectivity v1.7.0/go.mod h1:RMuSbkdbPwNMQjB5HBWD5MpTBnNm39iAVpC3TmsExt8=\ncloud.google.com/go/networkconnectivity v1.10.0/go.mod h1:UP4O4sWXJG13AqrTdQCD9TnLGEbtNRqjuaaA7bNjF5E=\ncloud.google.com/go/networkconnectivity v1.11.0/go.mod h1:iWmDD4QF16VCDLXUqvyspJjIEtBR/4zq5hwnY2X3scM=\ncloud.google.com/go/networkconnectivity v1.15.0/go.mod h1:uBQqx/YHI6gzqfV5J/7fkKwTGlXvQhHevUuzMpos9WY=\ncloud.google.com/go/networkmanagement v1.4.0/go.mod h1:Q9mdLLRn60AsOrPc8rs8iNV6OHXaGcDdsIQe1ohekq8=\ncloud.google.com/go/networkmanagement v1.5.0/go.mod h1:ZnOeZ/evzUdUsnvRt792H0uYEnHQEMaz+REhhzJRcf4=\ncloud.google.com/go/networkmanagement v1.6.0/go.mod h1:5pKPqyXjB/sgtvB5xqOemumoQNB7y95Q7S+4rjSOPYY=\ncloud.google.com/go/networkmanagement v1.14.0/go.mod h1:4myfd4A0uULCOCGHL1npZN0U+kr1Z2ENlbHdCCX4cE8=\ncloud.google.com/go/networksecurity v0.5.0/go.mod h1:xS6fOCoqpVC5zx15Z/MqkfDwH4+m/61A3ODiDV1xmiQ=\ncloud.google.com/go/networksecurity v0.6.0/go.mod h1:Q5fjhTr9WMI5mbpRYEbiexTzROf7ZbDzvzCrNl14nyU=\ncloud.google.com/go/networksecurity v0.7.0/go.mod h1:mAnzoxx/8TBSyXEeESMy9OOYwo1v+gZ5eMRnsT5bC8k=\ncloud.google.com/go/networksecurity v0.8.0/go.mod h1:B78DkqsxFG5zRSVuwYFRZ9Xz8IcQ5iECsNrPn74hKHU=\ncloud.google.com/go/networksecurity v0.10.0/go.mod h1:IcpI5pyzlZyYG8cNRCJmY1AYKajsd9Uz575HoeyYoII=\ncloud.google.com/go/notebooks v1.2.0/go.mod h1:9+wtppMfVPUeJ8fIWPOq1UnATHISkGXGqTkxeieQ6UY=\ncloud.google.com/go/notebooks v1.3.0/go.mod h1:bFR5lj07DtCPC7YAAJ//vHskFBxA5JzYlH68kXVdk34=\ncloud.google.com/go/notebooks v1.4.0/go.mod h1:4QPMngcwmgb6uw7Po99B2xv5ufVoIQ7nOGDyL4P8AgA=\ncloud.google.com/go/notebooks v1.5.0/go.mod h1:q8mwhnP9aR8Hpfnrc5iN5IBhrXUy8S2vuYs+kBJ/gu0=\ncloud.google.com/go/notebooks v1.7.0/go.mod h1:PVlaDGfJgj1fl1S3dUwhFMXFgfYGhYQt2164xOMONmE=\ncloud.google.com/go/notebooks v1.8.0/go.mod h1:Lq6dYKOYOWUCTvw5t2q1gp1lAp0zxAxRycayS0iJcqQ=\ncloud.google.com/go/notebooks v1.12.0/go.mod h1:euIZBbGY6G0J+UHzQ0XflysP0YoAUnDPZU7Fq0KXNw8=\ncloud.google.com/go/optimization v1.1.0/go.mod h1:5po+wfvX5AQlPznyVEZjGJTMr4+CAkJf2XSTQOOl9l4=\ncloud.google.com/go/optimization v1.2.0/go.mod h1:Lr7SOHdRDENsh+WXVmQhQTrzdu9ybg0NecjHidBq6xs=\ncloud.google.com/go/optimization v1.3.1/go.mod h1:IvUSefKiwd1a5p0RgHDbWCIbDFgKuEdB+fPPuP0IDLI=\ncloud.google.com/go/optimization v1.7.0/go.mod h1:6KvAB1HtlsMMblT/lsQRIlLjUhKjmMWNqV1AJUctbWs=\ncloud.google.com/go/orchestration v1.3.0/go.mod h1:Sj5tq/JpWiB//X/q3Ngwdl5K7B7Y0KZ7bfv0wL6fqVA=\ncloud.google.com/go/orchestration v1.4.0/go.mod h1:6W5NLFWs2TlniBphAViZEVhrXRSMgUGDfW7vrWKvsBk=\ncloud.google.com/go/orchestration v1.6.0/go.mod h1:M62Bevp7pkxStDfFfTuCOaXgaaqRAga1yKyoMtEoWPQ=\ncloud.google.com/go/orchestration v1.10.0/go.mod h1:pGiFgTTU6c/nXHTPpfsGT8N4Dax8awccCe6kjhVdWjI=\ncloud.google.com/go/orgpolicy v1.4.0/go.mod h1:xrSLIV4RePWmP9P3tBl8S93lTmlAxjm06NSm2UTmKvE=\ncloud.google.com/go/orgpolicy v1.5.0/go.mod h1:hZEc5q3wzwXJaKrsx5+Ewg0u1LxJ51nNFlext7Tanwc=\ncloud.google.com/go/orgpolicy v1.10.0/go.mod h1:w1fo8b7rRqlXlIJbVhOMPrwVljyuW5mqssvBtU18ONc=\ncloud.google.com/go/orgpolicy v1.13.0/go.mod h1:oKtT56zEFSsYORUunkN2mWVQBc9WGP7yBAPOZW1XCXc=\ncloud.google.com/go/osconfig v1.7.0/go.mod h1:oVHeCeZELfJP7XLxcBGTMBvRO+1nQ5tFG9VQTmYS2Fs=\ncloud.google.com/go/osconfig v1.8.0/go.mod h1:EQqZLu5w5XA7eKizepumcvWx+m8mJUhEwiPqWiZeEdg=\ncloud.google.com/go/osconfig v1.9.0/go.mod h1:Yx+IeIZJ3bdWmzbQU4fxNl8xsZ4amB+dygAwFPlvnNo=\ncloud.google.com/go/osconfig v1.10.0/go.mod h1:uMhCzqC5I8zfD9zDEAfvgVhDS8oIjySWh+l4WK6GnWw=\ncloud.google.com/go/osconfig v1.11.0/go.mod h1:aDICxrur2ogRd9zY5ytBLV89KEgT2MKB2L/n6x1ooPw=\ncloud.google.com/go/osconfig v1.14.0/go.mod h1:GhZzWYVrnQ42r+K5pA/hJCsnWVW2lB6bmVg+GnZ6JkM=\ncloud.google.com/go/oslogin v1.4.0/go.mod h1:YdgMXWRaElXz/lDk1Na6Fh5orF7gvmJ0FGLIs9LId4E=\ncloud.google.com/go/oslogin v1.5.0/go.mod h1:D260Qj11W2qx/HVF29zBg+0fd6YCSjSqLUkY/qEenQU=\ncloud.google.com/go/oslogin v1.6.0/go.mod h1:zOJ1O3+dTU8WPlGEkFSh7qeHPPSoxrcMbbK1Nm2iX70=\ncloud.google.com/go/oslogin v1.7.0/go.mod h1:e04SN0xO1UNJ1M5GP0vzVBFicIe4O53FOfcixIqTyXo=\ncloud.google.com/go/oslogin v1.9.0/go.mod h1:HNavntnH8nzrn8JCTT5fj18FuJLFJc4NaZJtBnQtKFs=\ncloud.google.com/go/oslogin v1.14.0/go.mod h1:VtMzdQPRP3T+w5OSFiYhaT/xOm7H1wo1HZUD2NAoVK4=\ncloud.google.com/go/phishingprotection v0.5.0/go.mod h1:Y3HZknsK9bc9dMi+oE8Bim0lczMU6hrX0UpADuMefr0=\ncloud.google.com/go/phishingprotection v0.6.0/go.mod h1:9Y3LBLgy0kDTcYET8ZH3bq/7qni15yVUoAxiFxnlSUA=\ncloud.google.com/go/phishingprotection v0.7.0/go.mod h1:8qJI4QKHoda/sb/7/YmMQ2omRLSLYSu9bU0EKCNI+Lk=\ncloud.google.com/go/phishingprotection v0.9.0/go.mod h1:CzttceTk9UskH9a8BycYmHL64zakEt3EXaM53r4i0Iw=\ncloud.google.com/go/policytroubleshooter v1.3.0/go.mod h1:qy0+VwANja+kKrjlQuOzmlvscn4RNsAc0e15GGqfMxg=\ncloud.google.com/go/policytroubleshooter v1.4.0/go.mod h1:DZT4BcRw3QoO8ota9xw/LKtPa8lKeCByYeKTIf/vxdE=\ncloud.google.com/go/policytroubleshooter v1.5.0/go.mod h1:Rz1WfV+1oIpPdN2VvvuboLVRsB1Hclg3CKQ53j9l8vw=\ncloud.google.com/go/policytroubleshooter v1.6.0/go.mod h1:zYqaPTsmfvpjm5ULxAyD/lINQxJ0DDsnWOP/GZ7xzBc=\ncloud.google.com/go/policytroubleshooter v1.11.0/go.mod h1:yTqY8n60lPLdU5bRbImn9IazrmF1o5b0VBshVxPzblQ=\ncloud.google.com/go/privatecatalog v0.5.0/go.mod h1:XgosMUvvPyxDjAVNDYxJ7wBW8//hLDDYmnsNcMGq1K0=\ncloud.google.com/go/privatecatalog v0.6.0/go.mod h1:i/fbkZR0hLN29eEWiiwue8Pb+GforiEIBnV9yrRUOKI=\ncloud.google.com/go/privatecatalog v0.7.0/go.mod h1:2s5ssIFO69F5csTXcwBP7NPFTZvps26xGzvQ2PQaBYg=\ncloud.google.com/go/privatecatalog v0.8.0/go.mod h1:nQ6pfaegeDAq/Q5lrfCQzQLhubPiZhSaNhIgfJlnIXs=\ncloud.google.com/go/privatecatalog v0.10.0/go.mod h1:/Lci3oPTxJpixjiTBoiVv3PmUZg/IdhPvKHcLEgObuc=\ncloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=\ncloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=\ncloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=\ncloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU=\ncloud.google.com/go/pubsub v1.5.0/go.mod h1:ZEwJccE3z93Z2HWvstpri00jOg7oO4UZDtKhwDwqF0w=\ncloud.google.com/go/pubsub v1.26.0/go.mod h1:QgBH3U/jdJy/ftjPhTkyXNj543Tin1pRYcdcPRnFIRI=\ncloud.google.com/go/pubsub v1.27.1/go.mod h1:hQN39ymbV9geqBnfQq6Xf63yNhUAhv9CZhzp5O6qsW0=\ncloud.google.com/go/pubsub v1.28.0/go.mod h1:vuXFpwaVoIPQMGXqRyUQigu/AX1S3IWugR9xznmcXX8=\ncloud.google.com/go/pubsub v1.30.0/go.mod h1:qWi1OPS0B+b5L+Sg6Gmc9zD1Y+HaM0MdUr7LsupY1P4=\ncloud.google.com/go/pubsub v1.42.0/go.mod h1:KADJ6s4MbTwhXmse/50SebEhE4SmUwHi48z3/dHar1Y=\ncloud.google.com/go/pubsublite v1.5.0/go.mod h1:xapqNQ1CuLfGi23Yda/9l4bBCKz/wC3KIJ5gKcxveZg=\ncloud.google.com/go/pubsublite v1.6.0/go.mod h1:1eFCS0U11xlOuMFV/0iBqw3zP12kddMeCbj/F3FSj9k=\ncloud.google.com/go/pubsublite v1.7.0/go.mod h1:8hVMwRXfDfvGm3fahVbtDbiLePT3gpoiJYJY+vxWxVM=\ncloud.google.com/go/pubsublite v1.8.2/go.mod h1:4r8GSa9NznExjuLPEJlF1VjOPOpgf3IT6k8x/YgaOPI=\ncloud.google.com/go/recaptchaenterprise v1.3.1/go.mod h1:OdD+q+y4XGeAlxRaMn1Y7/GveP6zmq76byL6tjPE7d4=\ncloud.google.com/go/recaptchaenterprise/v2 v2.1.0/go.mod h1:w9yVqajwroDNTfGuhmOjPDN//rZGySaf6PtFVcSCa7o=\ncloud.google.com/go/recaptchaenterprise/v2 v2.2.0/go.mod h1:/Zu5jisWGeERrd5HnlS3EUGb/D335f9k51B/FVil0jk=\ncloud.google.com/go/recaptchaenterprise/v2 v2.3.0/go.mod h1:O9LwGCjrhGHBQET5CA7dd5NwwNQUErSgEDit1DLNTdo=\ncloud.google.com/go/recaptchaenterprise/v2 v2.4.0/go.mod h1:Am3LHfOuBstrLrNCBrlI5sbwx9LBg3te2N6hGvHn2mE=\ncloud.google.com/go/recaptchaenterprise/v2 v2.5.0/go.mod h1:O8LzcHXN3rz0j+LBC91jrwI3R+1ZSZEWrfL7XHgNo9U=\ncloud.google.com/go/recaptchaenterprise/v2 v2.6.0/go.mod h1:RPauz9jeLtB3JVzg6nCbe12qNoaa8pXc4d/YukAmcnA=\ncloud.google.com/go/recaptchaenterprise/v2 v2.7.0/go.mod h1:19wVj/fs5RtYtynAPJdDTb69oW0vNHYDBTbB4NvMD9c=\ncloud.google.com/go/recaptchaenterprise/v2 v2.17.0/go.mod h1:SS4QDdlmJ3NvbOMCXQxaFhVGRjvNMfoKCoCdxqXadqs=\ncloud.google.com/go/recommendationengine v0.5.0/go.mod h1:E5756pJcVFeVgaQv3WNpImkFP8a+RptV6dDLGPILjvg=\ncloud.google.com/go/recommendationengine v0.6.0/go.mod h1:08mq2umu9oIqc7tDy8sx+MNJdLG0fUi3vaSVbztHgJ4=\ncloud.google.com/go/recommendationengine v0.7.0/go.mod h1:1reUcE3GIu6MeBz/h5xZJqNLuuVjNg1lmWMPyjatzac=\ncloud.google.com/go/recommendationengine v0.9.0/go.mod h1:59ydKXFyXO4Y8S0Bk224sKfj6YvIyzgcpG6w8kXIMm4=\ncloud.google.com/go/recommender v1.5.0/go.mod h1:jdoeiBIVrJe9gQjwd759ecLJbxCDED4A6p+mqoqDvTg=\ncloud.google.com/go/recommender v1.6.0/go.mod h1:+yETpm25mcoiECKh9DEScGzIRyDKpZ0cEhWGo+8bo+c=\ncloud.google.com/go/recommender v1.7.0/go.mod h1:XLHs/W+T8olwlGOgfQenXBTbIseGclClff6lhFVe9Bs=\ncloud.google.com/go/recommender v1.8.0/go.mod h1:PkjXrTT05BFKwxaUxQmtIlrtj0kph108r02ZZQ5FE70=\ncloud.google.com/go/recommender v1.9.0/go.mod h1:PnSsnZY7q+VL1uax2JWkt/UegHssxjUVVCrX52CuEmQ=\ncloud.google.com/go/recommender v1.13.0/go.mod h1:+XkXkeB9k6zG222ZH70U6DBkmvEL0na+pSjZRmlWcrk=\ncloud.google.com/go/redis v1.7.0/go.mod h1:V3x5Jq1jzUcg+UNsRvdmsfuFnit1cfe3Z/PGyq/lm4Y=\ncloud.google.com/go/redis v1.8.0/go.mod h1:Fm2szCDavWzBk2cDKxrkmWBqoCiL1+Ctwq7EyqBCA/A=\ncloud.google.com/go/redis v1.9.0/go.mod h1:HMYQuajvb2D0LvMgZmLDZW8V5aOC/WxstZHiy4g8OiA=\ncloud.google.com/go/redis v1.10.0/go.mod h1:ThJf3mMBQtW18JzGgh41/Wld6vnDDc/F/F35UolRZPM=\ncloud.google.com/go/redis v1.11.0/go.mod h1:/X6eicana+BWcUda5PpwZC48o37SiFVTFSs0fWAJ7uQ=\ncloud.google.com/go/redis v1.17.0/go.mod h1:pzTdaIhriMLiXu8nn2CgiS52SYko0tO1Du4d3MPOG5I=\ncloud.google.com/go/resourcemanager v1.3.0/go.mod h1:bAtrTjZQFJkiWTPDb1WBjzvc6/kifjj4QBYuKCCoqKA=\ncloud.google.com/go/resourcemanager v1.4.0/go.mod h1:MwxuzkumyTX7/a3n37gmsT3py7LIXwrShilPh3P1tR0=\ncloud.google.com/go/resourcemanager v1.5.0/go.mod h1:eQoXNAiAvCf5PXxWxXjhKQoTMaUSNrEfg+6qdf/wots=\ncloud.google.com/go/resourcemanager v1.6.0/go.mod h1:YcpXGRs8fDzcUl1Xw8uOVmI8JEadvhRIkoXXUNVYcVo=\ncloud.google.com/go/resourcemanager v1.7.0/go.mod h1:HlD3m6+bwhzj9XCouqmeiGuni95NTrExfhoSrkC/3EI=\ncloud.google.com/go/resourcemanager v1.10.0/go.mod h1:kIx3TWDCjLnUQUdjQ/e8EXsS9GJEzvcY+YMOHpADxrk=\ncloud.google.com/go/resourcesettings v1.3.0/go.mod h1:lzew8VfESA5DQ8gdlHwMrqZs1S9V87v3oCnKCWoOuQU=\ncloud.google.com/go/resourcesettings v1.4.0/go.mod h1:ldiH9IJpcrlC3VSuCGvjR5of/ezRrOxFtpJoJo5SmXg=\ncloud.google.com/go/resourcesettings v1.5.0/go.mod h1:+xJF7QSG6undsQDfsCJyqWXyBwUoJLhetkRMDRnIoXA=\ncloud.google.com/go/resourcesettings v1.8.0/go.mod h1:/hleuSOq8E6mF1sRYZrSzib8BxFHprQXrPluWTuZ6Ys=\ncloud.google.com/go/retail v1.8.0/go.mod h1:QblKS8waDmNUhghY2TI9O3JLlFk8jybHeV4BF19FrE4=\ncloud.google.com/go/retail v1.9.0/go.mod h1:g6jb6mKuCS1QKnH/dpu7isX253absFl6iE92nHwlBUY=\ncloud.google.com/go/retail v1.10.0/go.mod h1:2gDk9HsL4HMS4oZwz6daui2/jmKvqShXKQuB2RZ+cCc=\ncloud.google.com/go/retail v1.11.0/go.mod h1:MBLk1NaWPmh6iVFSz9MeKG/Psyd7TAgm6y/9L2B4x9Y=\ncloud.google.com/go/retail v1.12.0/go.mod h1:UMkelN/0Z8XvKymXFbD4EhFJlYKRx1FGhQkVPU5kF14=\ncloud.google.com/go/retail v1.18.0/go.mod h1:vaCabihbSrq88mKGKcKc4/FDHvVcPP0sQDAt0INM+v8=\ncloud.google.com/go/run v0.2.0/go.mod h1:CNtKsTA1sDcnqqIFR3Pb5Tq0usWxJJvsWOCPldRU3Do=\ncloud.google.com/go/run v0.3.0/go.mod h1:TuyY1+taHxTjrD0ZFk2iAR+xyOXEA0ztb7U3UNA0zBo=\ncloud.google.com/go/run v0.8.0/go.mod h1:VniEnuBwqjigv0A7ONfQUaEItaiCRVujlMqerPPiktM=\ncloud.google.com/go/run v0.9.0/go.mod h1:Wwu+/vvg8Y+JUApMwEDfVfhetv30hCG4ZwDR/IXl2Qg=\ncloud.google.com/go/run v1.5.0/go.mod h1:Z4Tv/XNC/veO6rEpF0waVhR7vEu5RN1uJQ8dD1PeMtI=\ncloud.google.com/go/scheduler v1.4.0/go.mod h1:drcJBmxF3aqZJRhmkHQ9b3uSSpQoltBPGPxGAWROx6s=\ncloud.google.com/go/scheduler v1.5.0/go.mod h1:ri073ym49NW3AfT6DZi21vLZrG07GXr5p3H1KxN5QlI=\ncloud.google.com/go/scheduler v1.6.0/go.mod h1:SgeKVM7MIwPn3BqtcBntpLyrIJftQISRrYB5ZtT+KOk=\ncloud.google.com/go/scheduler v1.7.0/go.mod h1:jyCiBqWW956uBjjPMMuX09n3x37mtyPJegEWKxRsn44=\ncloud.google.com/go/scheduler v1.8.0/go.mod h1:TCET+Y5Gp1YgHT8py4nlg2Sew8nUHMqcpousDgXJVQc=\ncloud.google.com/go/scheduler v1.9.0/go.mod h1:yexg5t+KSmqu+njTIh3b7oYPheFtBWGcbVUYF1GGMIc=\ncloud.google.com/go/scheduler v1.11.0/go.mod h1:RBSu5/rIsF5mDbQUiruvIE6FnfKpLd3HlTDu8aWk0jw=\ncloud.google.com/go/secretmanager v1.6.0/go.mod h1:awVa/OXF6IiyaU1wQ34inzQNc4ISIDIrId8qE5QGgKA=\ncloud.google.com/go/secretmanager v1.8.0/go.mod h1:hnVgi/bN5MYHd3Gt0SPuTPPp5ENina1/LxM+2W9U9J4=\ncloud.google.com/go/secretmanager v1.9.0/go.mod h1:b71qH2l1yHmWQHt9LC80akm86mX8AL6X1MA01dW8ht4=\ncloud.google.com/go/secretmanager v1.10.0/go.mod h1:MfnrdvKMPNra9aZtQFvBcvRU54hbPD8/HayQdlUgJpU=\ncloud.google.com/go/secretmanager v1.14.0/go.mod h1:q0hSFHzoW7eRgyYFH8trqEFavgrMeiJI4FETNN78vhM=\ncloud.google.com/go/security v1.5.0/go.mod h1:lgxGdyOKKjHL4YG3/YwIL2zLqMFCKs0UbQwgyZmfJl4=\ncloud.google.com/go/security v1.7.0/go.mod h1:mZklORHl6Bg7CNnnjLH//0UlAlaXqiG7Lb9PsPXLfD0=\ncloud.google.com/go/security v1.8.0/go.mod h1:hAQOwgmaHhztFhiQ41CjDODdWP0+AE1B3sX4OFlq+GU=\ncloud.google.com/go/security v1.9.0/go.mod h1:6Ta1bO8LXI89nZnmnsZGp9lVoVWXqsVbIq/t9dzI+2Q=\ncloud.google.com/go/security v1.10.0/go.mod h1:QtOMZByJVlibUT2h9afNDWRZ1G96gVywH8T5GUSb9IA=\ncloud.google.com/go/security v1.12.0/go.mod h1:rV6EhrpbNHrrxqlvW0BWAIawFWq3X90SduMJdFwtLB8=\ncloud.google.com/go/security v1.13.0/go.mod h1:Q1Nvxl1PAgmeW0y3HTt54JYIvUdtcpYKVfIB8AOMZ+0=\ncloud.google.com/go/security v1.18.0/go.mod h1:oS/kRVUNmkwEqzCgSmK2EaGd8SbDUvliEiADjSb/8Mo=\ncloud.google.com/go/securitycenter v1.13.0/go.mod h1:cv5qNAqjY84FCN6Y9z28WlkKXyWsgLO832YiWwkCWcU=\ncloud.google.com/go/securitycenter v1.14.0/go.mod h1:gZLAhtyKv85n52XYWt6RmeBdydyxfPeTrpToDPw4Auc=\ncloud.google.com/go/securitycenter v1.15.0/go.mod h1:PeKJ0t8MoFmmXLXWm41JidyzI3PJjd8sXWaVqg43WWk=\ncloud.google.com/go/securitycenter v1.16.0/go.mod h1:Q9GMaLQFUD+5ZTabrbujNWLtSLZIZF7SAR0wWECrjdk=\ncloud.google.com/go/securitycenter v1.18.1/go.mod h1:0/25gAzCM/9OL9vVx4ChPeM/+DlfGQJDwBy/UC8AKK0=\ncloud.google.com/go/securitycenter v1.19.0/go.mod h1:LVLmSg8ZkkyaNy4u7HCIshAngSQ8EcIRREP3xBnyfag=\ncloud.google.com/go/securitycenter v1.35.0/go.mod h1:gotw8mBfCxX0CGrRK917CP/l+Z+QoDchJ9HDpSR8eDc=\ncloud.google.com/go/servicecontrol v1.4.0/go.mod h1:o0hUSJ1TXJAmi/7fLJAedOovnujSEvjKCAFNXPQ1RaU=\ncloud.google.com/go/servicecontrol v1.5.0/go.mod h1:qM0CnXHhyqKVuiZnGKrIurvVImCs8gmqWsDoqe9sU1s=\ncloud.google.com/go/servicecontrol v1.10.0/go.mod h1:pQvyvSRh7YzUF2efw7H87V92mxU8FnFDawMClGCNuAA=\ncloud.google.com/go/servicecontrol v1.11.0/go.mod h1:kFmTzYzTUIuZs0ycVqRHNaNhgR+UMUpw9n02l/pY+mc=\ncloud.google.com/go/servicecontrol v1.11.1/go.mod h1:aSnNNlwEFBY+PWGQ2DoM0JJ/QUXqV5/ZD9DOLB7SnUk=\ncloud.google.com/go/servicedirectory v1.4.0/go.mod h1:gH1MUaZCgtP7qQiI+F+A+OpeKF/HQWgtAddhTbhL2bs=\ncloud.google.com/go/servicedirectory v1.5.0/go.mod h1:QMKFL0NUySbpZJ1UZs3oFAmdvVxhhxB6eJ/Vlp73dfg=\ncloud.google.com/go/servicedirectory v1.6.0/go.mod h1:pUlbnWsLH9c13yGkxCmfumWEPjsRs1RlmJ4pqiNjVL4=\ncloud.google.com/go/servicedirectory v1.7.0/go.mod h1:5p/U5oyvgYGYejufvxhgwjL8UVXjkuw7q5XcG10wx1U=\ncloud.google.com/go/servicedirectory v1.8.0/go.mod h1:srXodfhY1GFIPvltunswqXpVxFPpZjf8nkKQT7XcXaY=\ncloud.google.com/go/servicedirectory v1.9.0/go.mod h1:29je5JjiygNYlmsGz8k6o+OZ8vd4f//bQLtvzkPPT/s=\ncloud.google.com/go/servicedirectory v1.12.0/go.mod h1:lKKBoVStJa+8S+iH7h/YRBMUkkqFjfPirkOTEyYAIUk=\ncloud.google.com/go/servicemanagement v1.4.0/go.mod h1:d8t8MDbezI7Z2R1O/wu8oTggo3BI2GKYbdG4y/SJTco=\ncloud.google.com/go/servicemanagement v1.5.0/go.mod h1:XGaCRe57kfqu4+lRxaFEAuqmjzF0r+gWHjWqKqBvKFo=\ncloud.google.com/go/servicemanagement v1.6.0/go.mod h1:aWns7EeeCOtGEX4OvZUWCCJONRZeFKiptqKf1D0l/Jc=\ncloud.google.com/go/servicemanagement v1.8.0/go.mod h1:MSS2TDlIEQD/fzsSGfCdJItQveu9NXnUniTrq/L8LK4=\ncloud.google.com/go/serviceusage v1.3.0/go.mod h1:Hya1cozXM4SeSKTAgGXgj97GlqUvF5JaoXacR1JTP/E=\ncloud.google.com/go/serviceusage v1.4.0/go.mod h1:SB4yxXSaYVuUBYUml6qklyONXNLt83U0Rb+CXyhjEeU=\ncloud.google.com/go/serviceusage v1.5.0/go.mod h1:w8U1JvqUqwJNPEOTQjrMHkw3IaIFLoLsPLvsE3xueec=\ncloud.google.com/go/serviceusage v1.6.0/go.mod h1:R5wwQcbOWsyuOfbP9tGdAnCAc6B9DRwPG1xtWMDeuPA=\ncloud.google.com/go/shell v1.3.0/go.mod h1:VZ9HmRjZBsjLGXusm7K5Q5lzzByZmJHf1d0IWHEN5X4=\ncloud.google.com/go/shell v1.4.0/go.mod h1:HDxPzZf3GkDdhExzD/gs8Grqk+dmYcEjGShZgYa9URw=\ncloud.google.com/go/shell v1.6.0/go.mod h1:oHO8QACS90luWgxP3N9iZVuEiSF84zNyLytb+qE2f9A=\ncloud.google.com/go/shell v1.8.0/go.mod h1:EoQR8uXuEWHUAMoB4+ijXqRVYatDCdKYOLAaay1R/yw=\ncloud.google.com/go/spanner v1.7.0/go.mod h1:sd3K2gZ9Fd0vMPLXzeCrF6fq4i63Q7aTLW/lBIfBkIk=\ncloud.google.com/go/spanner v1.41.0/go.mod h1:MLYDBJR/dY4Wt7ZaMIQ7rXOTLjYrmxLE/5ve9vFfWos=\ncloud.google.com/go/spanner v1.44.0/go.mod h1:G8XIgYdOK+Fbcpbs7p2fiprDw4CaZX63whnSMLVBxjk=\ncloud.google.com/go/spanner v1.45.0/go.mod h1:FIws5LowYz8YAE1J8fOS7DJup8ff7xJeetWEo5REA2M=\ncloud.google.com/go/spanner v1.67.0/go.mod h1:Um+TNmxfcCHqNCKid4rmAMvoe/Iu1vdz6UfxJ9GPxRQ=\ncloud.google.com/go/speech v1.6.0/go.mod h1:79tcr4FHCimOp56lwC01xnt/WPJZc4v3gzyT7FoBkCM=\ncloud.google.com/go/speech v1.7.0/go.mod h1:KptqL+BAQIhMsj1kOP2la5DSEEerPDuOP/2mmkhHhZQ=\ncloud.google.com/go/speech v1.8.0/go.mod h1:9bYIl1/tjsAnMgKGHKmBZzXKEkGgtU+MpdDPTE9f7y0=\ncloud.google.com/go/speech v1.9.0/go.mod h1:xQ0jTcmnRFFM2RfX/U+rk6FQNUF6DQlydUSyoooSpco=\ncloud.google.com/go/speech v1.14.1/go.mod h1:gEosVRPJ9waG7zqqnsHpYTOoAS4KouMRLDFMekpJ0J0=\ncloud.google.com/go/speech v1.15.0/go.mod h1:y6oH7GhqCaZANH7+Oe0BhgIogsNInLlz542tg3VqeYI=\ncloud.google.com/go/speech v1.25.0/go.mod h1:2IUTYClcJhqPgee5Ko+qJqq29/bglVizgIap0c5MvYs=\ncloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=\ncloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=\ncloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=\ncloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=\ncloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=\ncloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo=\ncloud.google.com/go/storage v1.22.1/go.mod h1:S8N1cAStu7BOeFfE8KAQzmyyLkK8p/vmRq6kuBTW58Y=\ncloud.google.com/go/storage v1.23.0/go.mod h1:vOEEDNFnciUMhBeT6hsJIn3ieU5cFRmzeLgDvXzfIXc=\ncloud.google.com/go/storage v1.27.0/go.mod h1:x9DOL8TK/ygDUMieqwfhdpQryTeEkhGKMi80i/iqR2s=\ncloud.google.com/go/storage v1.28.1/go.mod h1:Qnisd4CqDdo6BGs2AD5LLnEsmSQ80wQ5ogcBBKhU86Y=\ncloud.google.com/go/storage v1.29.0/go.mod h1:4puEjyTKnku6gfKoTfNOU/W+a9JyuVNxjpS5GBrB8h4=\ncloud.google.com/go/storage v1.43.0/go.mod h1:ajvxEa7WmZS1PxvKRq4bq0tFT3vMd502JwstCcYv0Q0=\ncloud.google.com/go/storagetransfer v1.5.0/go.mod h1:dxNzUopWy7RQevYFHewchb29POFv3/AaBgnhqzqiK0w=\ncloud.google.com/go/storagetransfer v1.6.0/go.mod h1:y77xm4CQV/ZhFZH75PLEXY0ROiS7Gh6pSKrM8dJyg6I=\ncloud.google.com/go/storagetransfer v1.7.0/go.mod h1:8Giuj1QNb1kfLAiWM1bN6dHzfdlDAVC9rv9abHot2W4=\ncloud.google.com/go/storagetransfer v1.8.0/go.mod h1:JpegsHHU1eXg7lMHkvf+KE5XDJ7EQu0GwNJbbVGanEw=\ncloud.google.com/go/storagetransfer v1.11.0/go.mod h1:arcvgzVC4HPcSikqV8D4h4PwrvGQHfKtbL4OwKPirjs=\ncloud.google.com/go/talent v1.1.0/go.mod h1:Vl4pt9jiHKvOgF9KoZo6Kob9oV4lwd/ZD5Cto54zDRw=\ncloud.google.com/go/talent v1.2.0/go.mod h1:MoNF9bhFQbiJ6eFD3uSsg0uBALw4n4gaCaEjBw9zo8g=\ncloud.google.com/go/talent v1.3.0/go.mod h1:CmcxwJ/PKfRgd1pBjQgU6W3YBwiewmUzQYH5HHmSCmM=\ncloud.google.com/go/talent v1.4.0/go.mod h1:ezFtAgVuRf8jRsvyE6EwmbTK5LKciD4KVnHuDEFmOOA=\ncloud.google.com/go/talent v1.5.0/go.mod h1:G+ODMj9bsasAEJkQSzO2uHQWXHHXUomArjWQQYkqK6c=\ncloud.google.com/go/talent v1.7.0/go.mod h1:8zfRPWWV4GNZuUmBwQub0gWAe2KaKhsthyGtV8fV1bY=\ncloud.google.com/go/texttospeech v1.4.0/go.mod h1:FX8HQHA6sEpJ7rCMSfXuzBcysDAuWusNNNvN9FELDd8=\ncloud.google.com/go/texttospeech v1.5.0/go.mod h1:oKPLhR4n4ZdQqWKURdwxMy0uiTS1xU161C8W57Wkea4=\ncloud.google.com/go/texttospeech v1.6.0/go.mod h1:YmwmFT8pj1aBblQOI3TfKmwibnsfvhIBzPXcW4EBovc=\ncloud.google.com/go/texttospeech v1.8.0/go.mod h1:hAgeA01K5QNfLy2sPUAVETE0L4WdEpaCMfwKH1qjCQU=\ncloud.google.com/go/tpu v1.3.0/go.mod h1:aJIManG0o20tfDQlRIej44FcwGGl/cD0oiRyMKG19IQ=\ncloud.google.com/go/tpu v1.4.0/go.mod h1:mjZaX8p0VBgllCzF6wcU2ovUXN9TONFLd7iz227X2Xg=\ncloud.google.com/go/tpu v1.5.0/go.mod h1:8zVo1rYDFuW2l4yZVY0R0fb/v44xLh3llq7RuV61fPM=\ncloud.google.com/go/tpu v1.7.0/go.mod h1:/J6Co458YHMD60nM3cCjA0msvFU/miCGMfx/nYyxv/o=\ncloud.google.com/go/trace v1.3.0/go.mod h1:FFUE83d9Ca57C+K8rDl/Ih8LwOzWIV1krKgxg6N0G28=\ncloud.google.com/go/trace v1.4.0/go.mod h1:UG0v8UBqzusp+z63o7FK74SdFE+AXpCLdFb1rshXG+Y=\ncloud.google.com/go/trace v1.8.0/go.mod h1:zH7vcsbAhklH8hWFig58HvxcxyQbaIqMarMg9hn5ECA=\ncloud.google.com/go/trace v1.9.0/go.mod h1:lOQqpE5IaWY0Ixg7/r2SjixMuc6lfTFeO4QGM4dQWOk=\ncloud.google.com/go/trace v1.11.0/go.mod h1:Aiemdi52635dBR7o3zuc9lLjXo3BwGaChEjCa3tJNmM=\ncloud.google.com/go/translate v1.3.0/go.mod h1:gzMUwRjvOqj5i69y/LYLd8RrNQk+hOmIXTi9+nb3Djs=\ncloud.google.com/go/translate v1.4.0/go.mod h1:06Dn/ppvLD6WvA5Rhdp029IX2Mi3Mn7fpMRLPvXT5Wg=\ncloud.google.com/go/translate v1.5.0/go.mod h1:29YDSYveqqpA1CQFD7NQuP49xymq17RXNaUDdc0mNu0=\ncloud.google.com/go/translate v1.6.0/go.mod h1:lMGRudH1pu7I3n3PETiOB2507gf3HnfLV8qlkHZEyos=\ncloud.google.com/go/translate v1.7.0/go.mod h1:lMGRudH1pu7I3n3PETiOB2507gf3HnfLV8qlkHZEyos=\ncloud.google.com/go/translate v1.12.0/go.mod h1:4/C4shFIY5hSZ3b3g+xXWM5xhBLqcUqksSMrQ7tyFtc=\ncloud.google.com/go/video v1.8.0/go.mod h1:sTzKFc0bUSByE8Yoh8X0mn8bMymItVGPfTuUBUyRgxk=\ncloud.google.com/go/video v1.9.0/go.mod h1:0RhNKFRF5v92f8dQt0yhaHrEuH95m068JYOvLZYnJSw=\ncloud.google.com/go/video v1.12.0/go.mod h1:MLQew95eTuaNDEGriQdcYn0dTwf9oWiA4uYebxM5kdg=\ncloud.google.com/go/video v1.13.0/go.mod h1:ulzkYlYgCp15N2AokzKjy7MQ9ejuynOJdf1tR5lGthk=\ncloud.google.com/go/video v1.14.0/go.mod h1:SkgaXwT+lIIAKqWAJfktHT/RbgjSuY6DobxEp0C5yTQ=\ncloud.google.com/go/video v1.15.0/go.mod h1:SkgaXwT+lIIAKqWAJfktHT/RbgjSuY6DobxEp0C5yTQ=\ncloud.google.com/go/video v1.23.0/go.mod h1:EGLQv3Ce/VNqcl/+Amq7jlrnpg+KMgQcr6YOOBfE9oc=\ncloud.google.com/go/videointelligence v1.6.0/go.mod h1:w0DIDlVRKtwPCn/C4iwZIJdvC69yInhW0cfi+p546uU=\ncloud.google.com/go/videointelligence v1.7.0/go.mod h1:k8pI/1wAhjznARtVT9U1llUaFNPh7muw8QyOUpavru4=\ncloud.google.com/go/videointelligence v1.8.0/go.mod h1:dIcCn4gVDdS7yte/w+koiXn5dWVplOZkE+xwG9FgK+M=\ncloud.google.com/go/videointelligence v1.9.0/go.mod h1:29lVRMPDYHikk3v8EdPSaL8Ku+eMzDljjuvRs105XoU=\ncloud.google.com/go/videointelligence v1.10.0/go.mod h1:LHZngX1liVtUhZvi2uNS0VQuOzNi2TkY1OakiuoUOjU=\ncloud.google.com/go/videointelligence v1.12.0/go.mod h1:3rjmafNpCEqAb1CElGTA7dsg8dFDsx7RQNHS7o088D0=\ncloud.google.com/go/vision v1.2.0/go.mod h1:SmNwgObm5DpFBme2xpyOyasvBc1aPdjvMk2bBk0tKD0=\ncloud.google.com/go/vision/v2 v2.2.0/go.mod h1:uCdV4PpN1S0jyCyq8sIM42v2Y6zOLkZs+4R9LrGYwFo=\ncloud.google.com/go/vision/v2 v2.3.0/go.mod h1:UO61abBx9QRMFkNBbf1D8B1LXdS2cGiiCRx0vSpZoUo=\ncloud.google.com/go/vision/v2 v2.4.0/go.mod h1:VtI579ll9RpVTrdKdkMzckdnwMyX2JILb+MhPqRbPsY=\ncloud.google.com/go/vision/v2 v2.5.0/go.mod h1:MmaezXOOE+IWa+cS7OhRRLK2cNv1ZL98zhqFFZaaH2E=\ncloud.google.com/go/vision/v2 v2.6.0/go.mod h1:158Hes0MvOS9Z/bDMSFpjwsUrZ5fPrdwuyyvKSGAGMY=\ncloud.google.com/go/vision/v2 v2.7.0/go.mod h1:H89VysHy21avemp6xcf9b9JvZHVehWbET0uT/bcuY/0=\ncloud.google.com/go/vision/v2 v2.9.0/go.mod h1:sejxShqNOEucObbGNV5Gk85hPCgiVPP4sWv0GrgKuNw=\ncloud.google.com/go/vmmigration v1.2.0/go.mod h1:IRf0o7myyWFSmVR1ItrBSFLFD/rJkfDCUTO4vLlJvsE=\ncloud.google.com/go/vmmigration v1.3.0/go.mod h1:oGJ6ZgGPQOFdjHuocGcLqX4lc98YQ7Ygq8YQwHh9A7g=\ncloud.google.com/go/vmmigration v1.5.0/go.mod h1:E4YQ8q7/4W9gobHjQg4JJSgXXSgY21nA5r8swQV+Xxc=\ncloud.google.com/go/vmmigration v1.6.0/go.mod h1:bopQ/g4z+8qXzichC7GW1w2MjbErL54rk3/C843CjfY=\ncloud.google.com/go/vmmigration v1.8.0/go.mod h1:+AQnGUabjpYKnkfdXJZ5nteUfzNDCmwbj/HSLGPFG5E=\ncloud.google.com/go/vmwareengine v0.1.0/go.mod h1:RsdNEf/8UDvKllXhMz5J40XxDrNJNN4sagiox+OI208=\ncloud.google.com/go/vmwareengine v0.2.2/go.mod h1:sKdctNJxb3KLZkE/6Oui94iw/xs9PRNC2wnNLXsHvH8=\ncloud.google.com/go/vmwareengine v0.3.0/go.mod h1:wvoyMvNWdIzxMYSpH/R7y2h5h3WFkx6d+1TIsP39WGY=\ncloud.google.com/go/vmwareengine v1.3.0/go.mod h1:7W/C/YFpelGyZzRUfOYkbgUfbN1CK5ME3++doIkh1Vk=\ncloud.google.com/go/vpcaccess v1.4.0/go.mod h1:aQHVbTWDYUR1EbTApSVvMq1EnT57ppDmQzZ3imqIk4w=\ncloud.google.com/go/vpcaccess v1.5.0/go.mod h1:drmg4HLk9NkZpGfCmZ3Tz0Bwnm2+DKqViEpeEpOq0m8=\ncloud.google.com/go/vpcaccess v1.6.0/go.mod h1:wX2ILaNhe7TlVa4vC5xce1bCnqE3AeH27RV31lnmZes=\ncloud.google.com/go/vpcaccess v1.8.0/go.mod h1:7fz79sxE9DbGm9dbbIdir3tsJhwCxiNAs8aFG8MEhR8=\ncloud.google.com/go/webrisk v1.4.0/go.mod h1:Hn8X6Zr+ziE2aNd8SliSDWpEnSS1u4R9+xXZmFiHmGE=\ncloud.google.com/go/webrisk v1.5.0/go.mod h1:iPG6fr52Tv7sGk0H6qUFzmL3HHZev1htXuWDEEsqMTg=\ncloud.google.com/go/webrisk v1.6.0/go.mod h1:65sW9V9rOosnc9ZY7A7jsy1zoHS5W9IAXv6dGqhMQMc=\ncloud.google.com/go/webrisk v1.7.0/go.mod h1:mVMHgEYH0r337nmt1JyLthzMr6YxwN1aAIEc2fTcq7A=\ncloud.google.com/go/webrisk v1.8.0/go.mod h1:oJPDuamzHXgUc+b8SiHRcVInZQuybnvEW72PqTc7sSg=\ncloud.google.com/go/webrisk v1.10.0/go.mod h1:ztRr0MCLtksoeSOQCEERZXdzwJGoH+RGYQ2qodGOy2U=\ncloud.google.com/go/websecurityscanner v1.3.0/go.mod h1:uImdKm2wyeXQevQJXeh8Uun/Ym1VqworNDlBXQevGMo=\ncloud.google.com/go/websecurityscanner v1.4.0/go.mod h1:ebit/Fp0a+FWu5j4JOmJEV8S8CzdTkAS77oDsiSqYWQ=\ncloud.google.com/go/websecurityscanner v1.5.0/go.mod h1:Y6xdCPy81yi0SQnDY1xdNTNpfY1oAgXUlcfN3B3eSng=\ncloud.google.com/go/websecurityscanner v1.7.0/go.mod h1:d5OGdHnbky9MAZ8SGzdWIm3/c9p0r7t+5BerY5JYdZc=\ncloud.google.com/go/workflows v1.6.0/go.mod h1:6t9F5h/unJz41YqfBmqSASJSXccBLtD1Vwf+KmJENM0=\ncloud.google.com/go/workflows v1.7.0/go.mod h1:JhSrZuVZWuiDfKEFxU0/F1PQjmpnpcoISEXH2bcHC3M=\ncloud.google.com/go/workflows v1.8.0/go.mod h1:ysGhmEajwZxGn1OhGOGKsTXc5PyxOc0vfKf5Af+to4M=\ncloud.google.com/go/workflows v1.9.0/go.mod h1:ZGkj1aFIOd9c8Gerkjjq7OW7I5+l6cSvT3ujaO/WwSA=\ncloud.google.com/go/workflows v1.10.0/go.mod h1:fZ8LmRmZQWacon9UCX1r/g/DfAXx5VcPALq2CxzdePw=\ncloud.google.com/go/workflows v1.13.0/go.mod h1:StCuY3jhBj1HYMjCPqZs7J0deQLHPhF6hDtzWJaVF+Y=\ncontrib.go.opencensus.io/exporter/stackdriver v0.13.4/go.mod h1:aXENhDJ1Y4lIg4EUaVTwzvYETVNZk10Pu26tevFKLUc=\ndmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=\ngioui.org v0.0.0-20210308172011-57750fc8a0a6/go.mod h1:RSH6KIUZ0p2xy5zHDxgAM4zumjgTw83q2ge/PI+yyw8=\ngit.sr.ht/~sbinet/gg v0.3.1/go.mod h1:KGYtlADtqsqANL9ueOFkWymvzUvLMQllU5Ixo+8v3pc=\ngithub.com/4meepo/tagalign v1.3.4 h1:P51VcvBnf04YkHzjfclN6BbsopfJR5rxs1n+5zHt+w8=\ngithub.com/4meepo/tagalign v1.3.4/go.mod h1:M+pnkHH2vG8+qhE5bVc/zeP7HS/j910Fwa9TUSyZVI0=\ngithub.com/Abirdcfly/dupword v0.1.1 h1:Bsxe0fIw6OwBtXMIncaTxCLHYO5BB+3mcsR5E8VXloY=\ngithub.com/Abirdcfly/dupword v0.1.1/go.mod h1:B49AcJdTYYkpd4HjgAcutNGG9HZ2JWwKunH9Y2BA6sM=\ngithub.com/AlekSi/gocov-xml v0.0.0-20190121064608-3a14fb1c4737 h1:JZHBkt0GhM+ARQykshqpI49yaWCHQbJonH3XpDTwMZQ=\ngithub.com/AlekSi/gocov-xml v0.0.0-20190121064608-3a14fb1c4737/go.mod h1:w1KSuh2JgIL3nyRiZijboSUwbbxOrTzWwyWVFUHtXBQ=\ngithub.com/AlekSi/gocov-xml v1.1.0 h1:iElWGi7s/MuL8/d8WDtI2fOAsN3ap9x8nK5RrAhaDng=\ngithub.com/AlekSi/gocov-xml v1.1.0/go.mod h1:g1dRVOCHjKkMtlPfW6BokJ/qxoeZ1uPNAK7A/ii3CUo=\ngithub.com/Antonboom/errname v0.1.13 h1:JHICqsewj/fNckzrfVSe+T33svwQxmjC+1ntDsHOVvM=\ngithub.com/Antonboom/errname v0.1.13/go.mod h1:uWyefRYRN54lBg6HseYCFhs6Qjcy41Y3Jl/dVhA87Ns=\ngithub.com/Antonboom/nilnil v0.1.9 h1:eKFMejSxPSA9eLSensFmjW2XTgTwJMjZ8hUHtV4s/SQ=\ngithub.com/Antonboom/nilnil v0.1.9/go.mod h1:iGe2rYwCq5/Me1khrysB4nwI7swQvjclR8/YRPl5ihQ=\ngithub.com/Antonboom/testifylint v1.4.3 h1:ohMt6AHuHgttaQ1xb6SSnxCeK4/rnK7KKzbvs7DmEck=\ngithub.com/Antonboom/testifylint v1.4.3/go.mod h1:+8Q9+AOLsz5ZiQiiYujJKs9mNz398+M6UgslP4qgJLA=\ngithub.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=\ngithub.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=\ngithub.com/BurntSushi/toml v1.4.1-0.20240526193622-a339e1f7089c h1:pxW6RcqyfI9/kWtOwnv/G+AzdKuy2ZrqINhenH4HyNs=\ngithub.com/BurntSushi/toml v1.4.1-0.20240526193622-a339e1f7089c/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=\ngithub.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=\ngithub.com/Crocmagnon/fatcontext v0.5.2 h1:vhSEg8Gqng8awhPju2w7MKHqMlg4/NI+gSDHtR3xgwA=\ngithub.com/Crocmagnon/fatcontext v0.5.2/go.mod h1:87XhRMaInHP44Q7Tlc7jkgKKB7kZAOPiDkFMdKCC+74=\ngithub.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=\ngithub.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24 h1:sHglBQTwgx+rWPdisA5ynNEsoARbiCBOyGcJM4/OzsM=\ngithub.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24/go.mod h1:4UJr5HIiMZrwgkSPdsjy2uOQExX/WEILpIrO9UPGuXs=\ngithub.com/GaijinEntertainment/go-exhaustruct/v3 v3.3.0 h1:/fTUt5vmbkAcMBt4YQiuC23cV0kEsN1MVMNqeOW43cU=\ngithub.com/GaijinEntertainment/go-exhaustruct/v3 v3.3.0/go.mod h1:ONJg5sxcbsdQQ4pOW8TGdTidT2TMAUy/2Xhr8mrYaao=\ngithub.com/GoogleCloudPlatform/grpc-gcp-go/grpcgcp v1.5.0/go.mod h1:dppbR7CwXD4pgtV9t3wD1812RaLDcBjtblcDF5f1vI0=\ngithub.com/JohnCGriffin/overflow v0.0.0-20211019200055-46fa312c352c/go.mod h1:X0CRv0ky0k6m906ixxpzmDRLvX58TFUKS2eePweuyxk=\ngithub.com/Masterminds/goutils v1.1.0/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=\ngithub.com/Masterminds/semver v1.4.2/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=\ngithub.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww=\ngithub.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=\ngithub.com/Masterminds/semver/v3 v3.3.0 h1:B8LGeaivUe71a5qox1ICM/JLl0NqZSW5CHyL+hmvYS0=\ngithub.com/Masterminds/semver/v3 v3.3.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM=\ngithub.com/Masterminds/sprig v2.15.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o=\ngithub.com/Masterminds/sprig v2.22.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o=\ngithub.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=\ngithub.com/OpenPeeDeeP/depguard v1.0.1 h1:VlW4R6jmBIv3/u1JNlawEvJMM4J+dPORPaZasQee8Us=\ngithub.com/OpenPeeDeeP/depguard v1.0.1/go.mod h1:xsIw86fROiiwelg+jB2uM9PiKihMMmUx/1V+TNhjQvM=\ngithub.com/OpenPeeDeeP/depguard v1.1.1 h1:TSUznLjvp/4IUP+OQ0t/4jF4QUyxIcVX8YnghZdunyA=\ngithub.com/OpenPeeDeeP/depguard v1.1.1/go.mod h1:JtAMzWkmFEzDPyAd+W0NHl1lvpQKTvT9jnRVsohBKpc=\ngithub.com/OpenPeeDeeP/depguard/v2 v2.2.0 h1:vDfG60vDtIuf0MEOhmLlLLSzqaRM8EMcgJPdp74zmpA=\ngithub.com/OpenPeeDeeP/depguard/v2 v2.2.0/go.mod h1:CIzddKRvLBC4Au5aYP/i3nyaWQ+ClszLIuVocRiCYFQ=\ngithub.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg=\ngithub.com/ajstarks/deck v0.0.0-20200831202436-30c9fc6549a9/go.mod h1:JynElWSGnm/4RlzPXRlREEwqTHAN3T56Bv2ITsFT3gY=\ngithub.com/ajstarks/deck/generate v0.0.0-20210309230005-c3f852c02e19/go.mod h1:T13YZdzov6OU0A1+RfKZiZN9ca6VeKdBdyDV+BY97Tk=\ngithub.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw=\ngithub.com/ajstarks/svgo v0.0.0-20211024235047-1546f124cd8b/go.mod h1:1KcenG0jGWcpt8ov532z81sp/kMMUG485J2InIOyADM=\ngithub.com/alecthomas/assert/v2 v2.3.0/go.mod h1:pXcQ2Asjp247dahGEmsZ6ru0UVwnkhktn7S0bBDLxvQ=\ngithub.com/alecthomas/go-check-sumtype v0.1.4 h1:WCvlB3l5Vq5dZQTFmodqL2g68uHiSwwlWcT5a2FGK0c=\ngithub.com/alecthomas/go-check-sumtype v0.1.4/go.mod h1:WyYPfhfkdhyrdaligV6svFopZV8Lqdzn5pyVBaV6jhQ=\ngithub.com/alecthomas/participle/v2 v2.1.0/go.mod h1:Y1+hAs8DHPmc3YUFzqllV+eSQ9ljPTk0ZkPMtEdAx2c=\ngithub.com/alecthomas/repr v0.2.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4=\ngithub.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=\ngithub.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=\ngithub.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=\ngithub.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=\ngithub.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE=\ngithub.com/alexkohler/nakedret/v2 v2.0.4 h1:yZuKmjqGi0pSmjGpOC016LtPJysIL0WEUiaXW5SUnNg=\ngithub.com/alexkohler/nakedret/v2 v2.0.4/go.mod h1:bF5i0zF2Wo2o4X4USt9ntUWve6JbFv02Ff4vlkmS/VU=\ngithub.com/alexkohler/prealloc v1.0.0 h1:Hbq0/3fJPQhNkN0dR95AVrr6R7tou91y0uHG5pOcUuw=\ngithub.com/alexkohler/prealloc v1.0.0/go.mod h1:VetnK3dIgFBBKmg0YnD9F9x6Icjd+9cvfHR56wJVlKE=\ngithub.com/alingse/asasalint v0.0.11 h1:SFwnQXJ49Kx/1GghOFz1XGqHYKp21Kq1nHad/0WQRnw=\ngithub.com/alingse/asasalint v0.0.11/go.mod h1:nCaoMhw7a9kSJObvQyVzNTPBDbNpdocqrSP7t/cW5+I=\ngithub.com/andybalholm/brotli v1.0.0/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y=\ngithub.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=\ngithub.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY=\ngithub.com/antihax/optional v0.0.0-20180407024304-ca021399b1a6/go.mod h1:V8iCPQYkqmusNa815XgQio277wI47sdRh1dUOLdyC6Q=\ngithub.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=\ngithub.com/aokoli/goutils v1.0.1/go.mod h1:SijmP0QR8LtwsmDs8Yii5Z/S4trXFGFC2oO5g9DP+DQ=\ngithub.com/apache/arrow/go/v10 v10.0.1/go.mod h1:YvhnlEePVnBS4+0z3fhPfUy7W1Ikj0Ih0vcRo/gZ1M0=\ngithub.com/apache/arrow/go/v11 v11.0.0/go.mod h1:Eg5OsL5H+e299f7u5ssuXsuHQVEGC4xei5aX110hRiI=\ngithub.com/apache/arrow/go/v12 v12.0.1/go.mod h1:weuTY7JvTG/HDPtMQxEUp7pU73vkLWMLpY67QwZ/WWw=\ngithub.com/apache/arrow/go/v14 v14.0.2/go.mod h1:u3fgh3EdgN/YQ8cVQRguVW3R+seMybFg8QBQ5LU+eBY=\ngithub.com/apache/arrow/go/v15 v15.0.2/go.mod h1:DGXsR3ajT524njufqf95822i+KTh+yea1jass9YXgjA=\ngithub.com/apache/thrift v0.16.0/go.mod h1:PHK3hniurgQaNMZYaCLEqXKsYK8upmhPbmdP2FXSqgU=\ngithub.com/apache/thrift v0.17.0/go.mod h1:OLxhMRJxomX+1I/KUw03qoV3mMz16BwaKI+d4fPBx7Q=\ngithub.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=\ngithub.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=\ngithub.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=\ngithub.com/armon/go-metrics v0.4.1/go.mod h1:E6amYzXo6aW1tqzoZGT755KkbgrJsSdpwZ+3JqfkOG4=\ngithub.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=\ngithub.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=\ngithub.com/ashanbrown/forbidigo v1.1.0 h1:SJOPJyqsrVL3CvR0veFZFmIM0fXS/Kvyikqvfphd0Z4=\ngithub.com/ashanbrown/forbidigo v1.1.0/go.mod h1:vVW7PEdqEFqapJe95xHkTfB1+XvZXBFg8t0sG2FIxmI=\ngithub.com/ashanbrown/forbidigo v1.6.0 h1:D3aewfM37Yb3pxHujIPSpTf6oQk9sc9WZi8gerOIVIY=\ngithub.com/ashanbrown/forbidigo v1.6.0/go.mod h1:Y8j9jy9ZYAEHXdu723cUlraTqbzjKF1MUyfOKL+AjcU=\ngithub.com/ashanbrown/makezero v0.0.0-20201205152432-7b7cdbb3025a/go.mod h1:oG9Dnez7/ESBqc4EdrdNlryeo7d0KcW1ftXHm7nU/UU=\ngithub.com/ashanbrown/makezero v0.0.0-20210308000810-4155955488a0 h1:27owMIbvO33XL56BKWPy+SCU69I9wPwPXuMf5mAbVGU=\ngithub.com/ashanbrown/makezero v0.0.0-20210308000810-4155955488a0/go.mod h1:oG9Dnez7/ESBqc4EdrdNlryeo7d0KcW1ftXHm7nU/UU=\ngithub.com/ashanbrown/makezero v1.1.1 h1:iCQ87C0V0vSyO+M9E/FZYbu65auqH0lnsOkf5FcB28s=\ngithub.com/ashanbrown/makezero v1.1.1/go.mod h1:i1bJLCRSCHOcOa9Y6MyF2FTfMZMFdHvxKHxgO5Z1axI=\ngithub.com/aws/aws-sdk-go v1.23.20/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=\ngithub.com/aws/aws-sdk-go v1.25.37/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=\ngithub.com/aws/aws-sdk-go v1.36.30/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro=\ngithub.com/axw/gocov v1.0.0 h1:YsqYR66hUmilVr23tu8USgnJIJvnwh3n7j5zRn7x4LU=\ngithub.com/axw/gocov v1.0.0/go.mod h1:LvQpEYiwwIb2nYkXY2fDWhg9/AsYqkhmrCshjlUJECE=\ngithub.com/axw/gocov v1.1.0 h1:y5U1krExoJDlb/kNtzxyZQmNRprFOFCutWbNjcQvmVM=\ngithub.com/axw/gocov v1.1.0/go.mod h1:H9G4tivgdN3pYSSVrTFBr6kGDCmAkgbJhtxFzAvgcdw=\ngithub.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=\ngithub.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=\ngithub.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=\ngithub.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=\ngithub.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=\ngithub.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=\ngithub.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84=\ngithub.com/bkielbasa/cyclop v1.2.0 h1:7Jmnh0yL2DjKfw28p86YTd/B4lRGcNuu12sKE35sM7A=\ngithub.com/bkielbasa/cyclop v1.2.0/go.mod h1:qOI0yy6A7dYC4Zgsa72Ppm9kONl0RoIlPbzot9mhmeI=\ngithub.com/bkielbasa/cyclop v1.2.1 h1:AeF71HZDob1P2/pRm1so9cd1alZnrpyc4q2uP2l0gJY=\ngithub.com/bkielbasa/cyclop v1.2.1/go.mod h1:K/dT/M0FPAiYjBgQGau7tz+3TMh4FWAEqlMhzFWCrgM=\ngithub.com/blizzy78/varnamelen v0.8.0 h1:oqSblyuQvFsW1hbBHh1zfwrKe3kcSj0rnXkKzsQ089M=\ngithub.com/blizzy78/varnamelen v0.8.0/go.mod h1:V9TzQZ4fLJ1DSrjVDfl89H7aMnTvKkApdHeyESmyR7k=\ngithub.com/bombsimon/wsl/v3 v3.2.0 h1:x3QUbwW7tPGcCNridvqmhSRthZMTALnkg5/1J+vaUas=\ngithub.com/bombsimon/wsl/v3 v3.2.0/go.mod h1:st10JtZYLE4D5sC7b8xV4zTKZwAQjCH/Hy2Pm1FNZIc=\ngithub.com/bombsimon/wsl/v3 v3.4.0 h1:RkSxjT3tmlptwfgEgTgU+KYKLI35p/tviNXNXiL2aNU=\ngithub.com/bombsimon/wsl/v3 v3.4.0/go.mod h1:KkIB+TXkqy6MvK9BDZVbZxKNYsE1/oLRJbIFtf14qqo=\ngithub.com/bombsimon/wsl/v4 v4.4.1 h1:jfUaCkN+aUpobrMO24zwyAMwMAV5eSziCkOKEauOLdw=\ngithub.com/bombsimon/wsl/v4 v4.4.1/go.mod h1:Xu/kDxGZTofQcDGCtQe9KCzhHphIe0fDuyWTxER9Feo=\ngithub.com/boombuler/barcode v1.0.0/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=\ngithub.com/boombuler/barcode v1.0.1/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=\ngithub.com/breml/bidichk v0.3.1 h1:mm0l1NVE6lhaF4GUI8wX6TRV+e9kyHSvtA1wSG3nDqU=\ngithub.com/breml/bidichk v0.3.1/go.mod h1:Qo0jQtZkQYyArvHxFXxNmaioxJRgfnSo6UirDTaAJL4=\ngithub.com/breml/errchkjson v0.4.0 h1:gftf6uWZMtIa/Is3XJgibewBm2ksAQSY/kABDNFTAdk=\ngithub.com/breml/errchkjson v0.4.0/go.mod h1:AuBOSTHyLSaaAFlWsRSuRBIroCh3eh7ZHh5YeelDIk8=\ngithub.com/butuzov/ireturn v0.3.0 h1:hTjMqWw3y5JC3kpnC5vXmFJAWI/m31jaCYQqzkS6PL0=\ngithub.com/butuzov/ireturn v0.3.0/go.mod h1:A09nIiwiqzN/IoVo9ogpa0Hzi9fex1kd9PSD6edP5ZA=\ngithub.com/butuzov/mirror v1.2.0 h1:9YVK1qIjNspaqWutSv8gsge2e/Xpq1eqEkslEUHy5cs=\ngithub.com/butuzov/mirror v1.2.0/go.mod h1:DqZZDtzm42wIAIyHXeN8W/qb1EPlb9Qn/if9icBOpdQ=\ngithub.com/catenacyber/perfsprint v0.7.1 h1:PGW5G/Kxn+YrN04cRAZKC+ZuvlVwolYMrIyyTJ/rMmc=\ngithub.com/catenacyber/perfsprint v0.7.1/go.mod h1:/wclWYompEyjUD2FuIIDVKNkqz7IgBIWXIH3V0Zol50=\ngithub.com/ccojocar/zxcvbn-go v1.0.2 h1:na/czXU8RrhXO4EZme6eQJLR4PzcGsahsBOAwU6I3Vg=\ngithub.com/ccojocar/zxcvbn-go v1.0.2/go.mod h1:g1qkXtUSvHP8lhHp5GrSmTz6uWALGRMQdw6Qnz/hi60=\ngithub.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=\ngithub.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=\ngithub.com/census-instrumentation/opencensus-proto v0.4.1/go.mod h1:4T9NM4+4Vw91VeyqjLS6ao50K5bOcLKN6Q42XnYaRYw=\ngithub.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=\ngithub.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=\ngithub.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=\ngithub.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=\ngithub.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=\ngithub.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=\ngithub.com/charithe/durationcheck v0.0.6 h1:Tsy7EppNow2pDC0jN7Hsmcb6mHd71ZbI1vFissRBtc0=\ngithub.com/charithe/durationcheck v0.0.6/go.mod h1:SSbRIBVfMjCi/kEB6K65XEA83D6prSM8ap1UCpNKtgg=\ngithub.com/charithe/durationcheck v0.0.10 h1:wgw73BiocdBDQPik+zcEoBG/ob8uyBHf2iyoHGPf5w4=\ngithub.com/charithe/durationcheck v0.0.10/go.mod h1:bCWXb7gYRysD1CU3C+u4ceO49LoGOY1C1L6uouGNreQ=\ngithub.com/chavacava/garif v0.1.0 h1:2JHa3hbYf5D9dsgseMKAmc/MZ109otzgNFk5s87H9Pc=\ngithub.com/chavacava/garif v0.1.0/go.mod h1:XMyYCkEL58DF0oyW4qDjjnPWONs2HBqYKI+UIPD+Gww=\ngithub.com/chromedp/cdproto v0.0.0-20230802225258-3cf4e6d46a89/go.mod h1:GKljq0VrfU4D5yc+2qA6OVr8pmO/MBbPEWqWQ/oqGEs=\ngithub.com/chromedp/chromedp v0.9.2/go.mod h1:LkSXJKONWTCHAfQasKFUZI+mxqS4tZqhmtGzzhLsnLs=\ngithub.com/chromedp/sysutil v1.0.0/go.mod h1:kgWmDdq8fTzXYcKIBqIYvRRTnYb9aNS9moAV0xufSww=\ngithub.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=\ngithub.com/chzyer/logex v1.2.1/go.mod h1:JLbx6lG2kDbNRFnfkgvh4eRJRPX1QCoOIWomwysCBrQ=\ngithub.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=\ngithub.com/chzyer/readline v1.5.1/go.mod h1:Eh+b79XXUwfKfcPLepksvw2tcLE/Ct21YObkaSkeBlk=\ngithub.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=\ngithub.com/chzyer/test v1.0.0/go.mod h1:2JlltgoNkt4TW/z9V/IzDdFaMTM2JPIi26O1pF38GC8=\ngithub.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag=\ngithub.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I=\ngithub.com/ckaznocha/intrange v0.2.1 h1:M07spnNEQoALOJhwrImSrJLaxwuiQK+hA2DeajBlwYk=\ngithub.com/ckaznocha/intrange v0.2.1/go.mod h1:7NEhVyf8fzZO5Ds7CRaqPEm52Ut83hsTiL5zbER/HYk=\ngithub.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=\ngithub.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=\ngithub.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=\ngithub.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=\ngithub.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI=\ngithub.com/cncf/udpa/go v0.0.0-20220112060539-c52dc94e7fbe/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI=\ngithub.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=\ngithub.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=\ngithub.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=\ngithub.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=\ngithub.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=\ngithub.com/cncf/xds/go v0.0.0-20220314180256-7f1daf1720fc/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=\ngithub.com/cncf/xds/go v0.0.0-20230105202645-06c439db220b/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=\ngithub.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=\ngithub.com/cncf/xds/go v0.0.0-20240822171458-6449f94b4d59/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8=\ngithub.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=\ngithub.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=\ngithub.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=\ngithub.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=\ngithub.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=\ngithub.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=\ngithub.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=\ngithub.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=\ngithub.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=\ngithub.com/coreos/go-systemd v0.0.0-20190620071333-e64a0ec8b42a/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=\ngithub.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=\ngithub.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=\ngithub.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=\ngithub.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=\ngithub.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=\ngithub.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=\ngithub.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=\ngithub.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=\ngithub.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=\ngithub.com/cristalhq/acmd v0.12.0/go.mod h1:LG5oa43pE/BbxtfMoImHCQN++0Su7dzipdgBjMCBVDQ=\ngithub.com/curioswitch/go-reassign v0.2.0 h1:G9UZyOcpk/d7Gd6mqYgd8XYWFMw/znxwGDUstnC9DIo=\ngithub.com/curioswitch/go-reassign v0.2.0/go.mod h1:x6OpXuWvgfQaMGks2BZybTngWjT84hqJfKoO8Tt/Roc=\ngithub.com/daixiang0/gci v0.2.8 h1:1mrIGMBQsBu0P7j7m1M8Lb+ZeZxsZL+jyGX4YoMJJpg=\ngithub.com/daixiang0/gci v0.2.8/go.mod h1:+4dZ7TISfSmqfAGv59ePaHfNzgGtIkHAhhdKggP1JAc=\ngithub.com/daixiang0/gci v0.13.5 h1:kThgmH1yBmZSBCh1EJVxQ7JsHpm5Oms0AMed/0LaH4c=\ngithub.com/daixiang0/gci v0.13.5/go.mod h1:12etP2OniiIdP4q+kjUGrC/rUagga7ODbqsom5Eo5Yk=\ngithub.com/davecgh/go-spew v0.0.0-20161028175848-04cdfd42973b/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=\ngithub.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=\ngithub.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=\ngithub.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=\ngithub.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=\ngithub.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=\ngithub.com/denis-tingaikin/go-header v0.5.0 h1:SRdnP5ZKvcO9KKRP1KJrhFR3RrlGuD+42t4429eC9k8=\ngithub.com/denis-tingaikin/go-header v0.5.0/go.mod h1:mMenU5bWrok6Wl2UsZjy+1okegmwQ3UgWl4V1D8gjlY=\ngithub.com/denis-tingajkin/go-header v0.4.2 h1:jEeSF4sdv8/3cT/WY8AgDHUoItNSoEZ7qg9dX7pc218=\ngithub.com/denis-tingajkin/go-header v0.4.2/go.mod h1:eLRHAVXzE5atsKAnNRDB90WHCFFnBUn4RN0nRcs1LJA=\ngithub.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=\ngithub.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=\ngithub.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE=\ngithub.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=\ngithub.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=\ngithub.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=\ngithub.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=\ngithub.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=\ngithub.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=\ngithub.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po=\ngithub.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=\ngithub.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=\ngithub.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ=\ngithub.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0=\ngithub.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE=\ngithub.com/envoyproxy/go-control-plane v0.10.3/go.mod h1:fJJn/j26vwOu972OllsvAgJJM//w9BV6Fxbg2LuVd34=\ngithub.com/envoyproxy/go-control-plane v0.11.1-0.20230524094728-9239064ad72f/go.mod h1:sfYdkwUW4BA3PbKjySwjJy+O4Pu0h62rlqCMHNk+K+Q=\ngithub.com/envoyproxy/go-control-plane v0.13.0/go.mod h1:GRaKG3dwvFoTg4nj7aXdZnvMg4d7nvT/wl9WgVXn3Q8=\ngithub.com/envoyproxy/protoc-gen-validate v0.0.14/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=\ngithub.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=\ngithub.com/envoyproxy/protoc-gen-validate v0.6.7/go.mod h1:dyJXwwfPK2VSqiB9Klm1J6romD608Ba7Hij42vrOBCo=\ngithub.com/envoyproxy/protoc-gen-validate v0.9.1/go.mod h1:OKNgG7TCp5pF4d6XftA0++PMirau2/yoOwVac3AbF2w=\ngithub.com/envoyproxy/protoc-gen-validate v0.10.1/go.mod h1:DRjgyB0I43LtJapqN6NiRwroiAU2PaFuvk/vjgh61ss=\ngithub.com/envoyproxy/protoc-gen-validate v1.1.0/go.mod h1:sXRDRVmzEbkM7CVcM06s9shE/m23dg3wzjl0UWqJ2q4=\ngithub.com/esimonov/ifshort v1.0.1 h1:p7hlWD15c9XwvwxYg3W7f7UZHmwg7l9hC0hBiF95gd0=\ngithub.com/esimonov/ifshort v1.0.1/go.mod h1:yZqNJUrNn20K8Q9n2CrjTKYyVEmX209Hgu+M1LBpeZE=\ngithub.com/esimonov/ifshort v1.0.4 h1:6SID4yGWfRae/M7hkVDVVyppy8q/v9OuxNdmjLQStBA=\ngithub.com/esimonov/ifshort v1.0.4/go.mod h1:Pe8zjlRrJ80+q2CxHLfEOfTwxCZ4O+MuhcHcfgNWTk0=\ngithub.com/ettle/strcase v0.2.0 h1:fGNiVF21fHXpX1niBgk0aROov1LagYsOwV/xqKDKR/Q=\ngithub.com/ettle/strcase v0.2.0/go.mod h1:DajmHElDSaX76ITe3/VHVyMin4LWSJN5Z909Wp+ED1A=\ngithub.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=\ngithub.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU=\ngithub.com/fatih/color v1.10.0 h1:s36xzo75JdqLaaWoiEHk767eHiwo0598uUxyfiPkDsg=\ngithub.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM=\ngithub.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=\ngithub.com/fatih/color v1.17.0 h1:GlRw1BRJxkpqUCBKzKOw098ed57fEsKeNjpTe3cSjK4=\ngithub.com/fatih/color v1.17.0/go.mod h1:YZ7TlrGPkiz6ku9fK3TLD/pl3CpsiFyu8N92HLgmosI=\ngithub.com/fatih/structtag v1.2.0 h1:/OdNE99OxoI/PqaW/SuSK9uxxT3f/tcSZgon/ssNSx4=\ngithub.com/fatih/structtag v1.2.0/go.mod h1:mBJUNpUnHmRKrKlQQlmCrh5PuhftFbNv8Ys4/aAZl94=\ngithub.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=\ngithub.com/firefart/nonamedreturns v1.0.5 h1:tM+Me2ZaXs8tfdDw3X6DOX++wMCOqzYUho6tUTYIdRA=\ngithub.com/firefart/nonamedreturns v1.0.5/go.mod h1:gHJjDqhGM4WyPt639SOZs+G89Ko7QKH5R5BhnO6xJhw=\ngithub.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k=\ngithub.com/fogleman/gg v1.3.0/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k=\ngithub.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=\ngithub.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=\ngithub.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=\ngithub.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=\ngithub.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=\ngithub.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=\ngithub.com/fullstorydev/grpcurl v1.6.0/go.mod h1:ZQ+ayqbKMJNhzLmbpCiurTVlaK2M/3nqZCxaQ2Ze/sM=\ngithub.com/fzipp/gocyclo v0.3.1 h1:A9UeX3HJSXTBzvHzhqoYVuE0eAhe+aM8XBCCwsPMZOc=\ngithub.com/fzipp/gocyclo v0.3.1/go.mod h1:DJHO6AUmbdqj2ET4Z9iArSuwWgYDRryYt2wASxc7x3E=\ngithub.com/fzipp/gocyclo v0.6.0 h1:lsblElZG7d3ALtGMx9fmxeTKZaLLpU8mET09yN4BBLo=\ngithub.com/fzipp/gocyclo v0.6.0/go.mod h1:rXPyn8fnlpa0R2csP/31uerbiVBugk5whMdlyaLkLoA=\ngithub.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=\ngithub.com/ghostiam/protogetter v0.3.8 h1:LYcXbYvybUyTIxN2Mj9h6rHrDZBDwZloPoKctWrFyJY=\ngithub.com/ghostiam/protogetter v0.3.8/go.mod h1:WZ0nw9pfzsgxuRsPOFQomgDVSWtDLJRfQJEhsGbmQMA=\ngithub.com/go-critic/go-critic v0.5.4 h1:fPNMqImVjELN6Du7NVVuvKA4cgASNmc7e4zSYQCOnv8=\ngithub.com/go-critic/go-critic v0.5.4/go.mod h1:cjB4YGw+n/+X8gREApej7150Uyy1Tg8If6F2XOAUXNE=\ngithub.com/go-critic/go-critic v0.11.4 h1:O7kGOCx0NDIni4czrkRIXTnit0mkyKOCePh3My6OyEU=\ngithub.com/go-critic/go-critic v0.11.4/go.mod h1:2QAdo4iuLik5S9YG0rT4wcZ8QxwHYkrr6/2MWAiv/vc=\ngithub.com/go-fonts/dejavu v0.1.0/go.mod h1:4Wt4I4OU2Nq9asgDCteaAaWZOV24E+0/Pwo0gppep4g=\ngithub.com/go-fonts/latin-modern v0.2.0/go.mod h1:rQVLdDMK+mK1xscDwsqM5J8U2jrRa3T0ecnM9pNujks=\ngithub.com/go-fonts/liberation v0.1.1/go.mod h1:K6qoJYypsmfVjWg8KOVDQhLc8UDgIK2HYqyqAO9z7GY=\ngithub.com/go-fonts/liberation v0.2.0/go.mod h1:K6qoJYypsmfVjWg8KOVDQhLc8UDgIK2HYqyqAO9z7GY=\ngithub.com/go-fonts/stix v0.1.0/go.mod h1:w/c1f0ldAUlJmLBvlbkvVXLAD+tAMqobIIQpmnUIzUY=\ngithub.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=\ngithub.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=\ngithub.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=\ngithub.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=\ngithub.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=\ngithub.com/go-kit/log v0.2.1/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0=\ngithub.com/go-latex/latex v0.0.0-20210118124228-b3d85cf34e07/go.mod h1:CO1AlKB2CSIqUrmQPqA0gdRIlnLEY0gK5JGjh37zN5U=\ngithub.com/go-latex/latex v0.0.0-20210823091927-c0d11ff05a81/go.mod h1:SX0U8uGpxhq9o2S/CELCSUxEWWAuoCUcVCQWv7G2OCk=\ngithub.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=\ngithub.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=\ngithub.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=\ngithub.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=\ngithub.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=\ngithub.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=\ngithub.com/go-ole/go-ole v1.2.4/go.mod h1:XCwSNxSkXRo4vlyPy93sltvi/qJq0jqQhjqQNIwKuxM=\ngithub.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=\ngithub.com/go-pdf/fpdf v0.5.0/go.mod h1:HzcnA+A23uwogo0tp9yU+l3V+KXhiESpt1PMayhOh5M=\ngithub.com/go-pdf/fpdf v0.6.0/go.mod h1:HzcnA+A23uwogo0tp9yU+l3V+KXhiESpt1PMayhOh5M=\ngithub.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=\ngithub.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=\ngithub.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA=\ngithub.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4=\ngithub.com/go-quicktest/qt v1.101.0/go.mod h1:14Bz/f7NwaXPtdYEgzsx46kqSxVwTbzVZsDC26tQJow=\ngithub.com/go-redis/redis v6.15.8+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=\ngithub.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=\ngithub.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=\ngithub.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=\ngithub.com/go-sql-driver/mysql v1.7.1/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=\ngithub.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=\ngithub.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=\ngithub.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls=\ngithub.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=\ngithub.com/go-toolsmith/astcast v1.0.0 h1:JojxlmI6STnFVG9yOImLeGREv8W2ocNUM+iOhR6jE7g=\ngithub.com/go-toolsmith/astcast v1.0.0/go.mod h1:mt2OdQTeAQcY4DQgPSArJjHCcOwlX+Wl/kwN+LbLGQ4=\ngithub.com/go-toolsmith/astcast v1.1.0 h1:+JN9xZV1A+Re+95pgnMgDboWNVnIMMQXwfBwLRPgSC8=\ngithub.com/go-toolsmith/astcast v1.1.0/go.mod h1:qdcuFWeGGS2xX5bLM/c3U9lewg7+Zu4mr+xPwZIB4ZU=\ngithub.com/go-toolsmith/astcopy v1.0.0 h1:OMgl1b1MEpjFQ1m5ztEO06rz5CUd3oBv9RF7+DyvdG8=\ngithub.com/go-toolsmith/astcopy v1.0.0/go.mod h1:vrgyG+5Bxrnz4MZWPF+pI4R8h3qKRjjyvV/DSez4WVQ=\ngithub.com/go-toolsmith/astcopy v1.1.0 h1:YGwBN0WM+ekI/6SS6+52zLDEf8Yvp3n2seZITCUBt5s=\ngithub.com/go-toolsmith/astcopy v1.1.0/go.mod h1:hXM6gan18VA1T/daUEHCFcYiW8Ai1tIwIzHY6srfEAw=\ngithub.com/go-toolsmith/astequal v1.0.0 h1:4zxD8j3JRFNyLN46lodQuqz3xdKSrur7U/sr0SDS/gQ=\ngithub.com/go-toolsmith/astequal v1.0.0/go.mod h1:H+xSiq0+LtiDC11+h1G32h7Of5O3CYFJ99GVbS5lDKY=\ngithub.com/go-toolsmith/astequal v1.0.3/go.mod h1:9Ai4UglvtR+4up+bAD4+hCj7iTo4m/OXVTSLnCyTAx4=\ngithub.com/go-toolsmith/astequal v1.1.0/go.mod h1:sedf7VIdCL22LD8qIvv7Nn9MuWJruQA/ysswh64lffQ=\ngithub.com/go-toolsmith/astequal v1.2.0 h1:3Fs3CYZ1k9Vo4FzFhwwewC3CHISHDnVUPC4x0bI2+Cw=\ngithub.com/go-toolsmith/astequal v1.2.0/go.mod h1:c8NZ3+kSFtFY/8lPso4v8LuJjdJiUFVnSuU3s0qrrDY=\ngithub.com/go-toolsmith/astfmt v1.0.0 h1:A0vDDXt+vsvLEdbMFJAUBI/uTbRw1ffOPnxsILnFL6k=\ngithub.com/go-toolsmith/astfmt v1.0.0/go.mod h1:cnWmsOAuq4jJY6Ct5YWlVLmcmLMn1JUPuQIHCY7CJDw=\ngithub.com/go-toolsmith/astfmt v1.1.0 h1:iJVPDPp6/7AaeLJEruMsBUlOYCmvg0MoCfJprsOmcco=\ngithub.com/go-toolsmith/astfmt v1.1.0/go.mod h1:OrcLlRwu0CuiIBp/8b5PYF9ktGVZUjlNMV634mhwuQ4=\ngithub.com/go-toolsmith/astinfo v0.0.0-20180906194353-9809ff7efb21/go.mod h1:dDStQCHtmZpYOmjRP/8gHHnCCch3Zz3oEgCdZVdtweU=\ngithub.com/go-toolsmith/astp v1.0.0 h1:alXE75TXgcmupDsMK1fRAy0YUzLzqPVvBKoyWV+KPXg=\ngithub.com/go-toolsmith/astp v1.0.0/go.mod h1:RSyrtpVlfTFGDYRbrjyWP1pYu//tSFcvdYrA8meBmLI=\ngithub.com/go-toolsmith/astp v1.1.0 h1:dXPuCl6u2llURjdPLLDxJeZInAeZ0/eZwFJmqZMnpQA=\ngithub.com/go-toolsmith/astp v1.1.0/go.mod h1:0T1xFGz9hicKs8Z5MfAqSUitoUYS30pDMsRVIDHs8CA=\ngithub.com/go-toolsmith/pkgload v1.0.0 h1:4DFWWMXVfbcN5So1sBNW9+yeiMqLFGl1wFLTL5R0Tgg=\ngithub.com/go-toolsmith/pkgload v1.0.0/go.mod h1:5eFArkbO80v7Z0kdngIxsRXRMTaX4Ilcwuh3clNrQJc=\ngithub.com/go-toolsmith/pkgload v1.2.2 h1:0CtmHq/02QhxcF7E9N5LIFcYFsMR5rdovfqTtRKkgIk=\ngithub.com/go-toolsmith/pkgload v1.2.2/go.mod h1:R2hxLNRKuAsiXCo2i5J6ZQPhnPMOVtU+f0arbFPWCus=\ngithub.com/go-toolsmith/strparse v1.0.0 h1:Vcw78DnpCAKlM20kSbAyO4mPfJn/lyYA4BJUDxe2Jb4=\ngithub.com/go-toolsmith/strparse v1.0.0/go.mod h1:YI2nUKP9YGZnL/L1/DLFBfixrcjslWct4wyljWhSRy8=\ngithub.com/go-toolsmith/strparse v1.1.0 h1:GAioeZUK9TGxnLS+qfdqNbA4z0SSm5zVNtCQiyP2Bvw=\ngithub.com/go-toolsmith/strparse v1.1.0/go.mod h1:7ksGy58fsaQkGQlY8WVoBFNyEPMGuJin1rfoPS4lBSQ=\ngithub.com/go-toolsmith/typep v1.0.0/go.mod h1:JSQCQMUPdRlMZFswiq3TGpNp1GMktqkR2Ns5AIQkATU=\ngithub.com/go-toolsmith/typep v1.0.2 h1:8xdsa1+FSIH/RhEkgnD1j2CJOy5mNllW1Q9tRiYwvlk=\ngithub.com/go-toolsmith/typep v1.0.2/go.mod h1:JSQCQMUPdRlMZFswiq3TGpNp1GMktqkR2Ns5AIQkATU=\ngithub.com/go-toolsmith/typep v1.1.0 h1:fIRYDyF+JywLfqzyhdiHzRop/GQDxxNhLGQ6gFUNHus=\ngithub.com/go-toolsmith/typep v1.1.0/go.mod h1:fVIw+7zjdsMxDA3ITWnH1yOiw1rnTQKCsF/sk2H/qig=\ngithub.com/go-viper/mapstructure/v2 v2.1.0 h1:gHnMa2Y/pIxElCH2GlZZ1lZSsn6XMtufpGyP1XxdC/w=\ngithub.com/go-viper/mapstructure/v2 v2.1.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=\ngithub.com/go-xmlfmt/xmlfmt v0.0.0-20191208150333-d5b6f63a941b h1:khEcpUM4yFcxg4/FHQWkvVRmgijNXRfzkIDHh23ggEo=\ngithub.com/go-xmlfmt/xmlfmt v0.0.0-20191208150333-d5b6f63a941b/go.mod h1:aUCEOzzezBEjDBbFBoSiya/gduyIiWYRP6CnSFIV8AM=\ngithub.com/go-xmlfmt/xmlfmt v1.1.2 h1:Nea7b4icn8s57fTx1M5AI4qQT5HEM3rVUO8MuE6g80U=\ngithub.com/go-xmlfmt/xmlfmt v1.1.2/go.mod h1:aUCEOzzezBEjDBbFBoSiya/gduyIiWYRP6CnSFIV8AM=\ngithub.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y=\ngithub.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8=\ngithub.com/gobwas/httphead v0.1.0/go.mod h1:O/RXo79gxV8G+RqlR/otEwx4Q36zl9rqC5u12GKvMCM=\ngithub.com/gobwas/pool v0.2.1/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw=\ngithub.com/gobwas/ws v1.2.1/go.mod h1:hRKAFb8wOxFROYNsT1bqfWnhX+b5MFeJM9r2ZSwg/KY=\ngithub.com/goccy/go-json v0.9.11/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=\ngithub.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=\ngithub.com/goccy/go-yaml v1.11.0/go.mod h1:H+mJrWtjPTJAHvRbV09MCK9xYwODM+wRTVFFTWckfng=\ngithub.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=\ngithub.com/gofrs/flock v0.8.0 h1:MSdYClljsF3PbENUUEx85nkWfJSGfzYI9yEBZOJz6CY=\ngithub.com/gofrs/flock v0.8.0/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU=\ngithub.com/gofrs/flock v0.12.1 h1:MTLVXXHf8ekldpJk3AKicLij9MdwOWkZ+a/jHHZby9E=\ngithub.com/gofrs/flock v0.12.1/go.mod h1:9zxTsyu5xtJ9DK+1tFZyibEV7y3uwDxPPfbxeeHCoD0=\ngithub.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=\ngithub.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=\ngithub.com/gogo/protobuf v1.3.0/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=\ngithub.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=\ngithub.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=\ngithub.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=\ngithub.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=\ngithub.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4=\ngithub.com/golang/glog v1.1.0/go.mod h1:pfYeQZ3JWZoXTV5sFc986z3HTpwQs9At6P4ImfuP3NQ=\ngithub.com/golang/glog v1.2.1/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w=\ngithub.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=\ngithub.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=\ngithub.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=\ngithub.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=\ngithub.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=\ngithub.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=\ngithub.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=\ngithub.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=\ngithub.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=\ngithub.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=\ngithub.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=\ngithub.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=\ngithub.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=\ngithub.com/golang/mock v1.5.0 h1:jlYHihg//f7RRwuPfptm04yp4s7O6Kw8EZiVYIGcH0g=\ngithub.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8=\ngithub.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc=\ngithub.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=\ngithub.com/golang/protobuf v1.1.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=\ngithub.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=\ngithub.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=\ngithub.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=\ngithub.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=\ngithub.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=\ngithub.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=\ngithub.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=\ngithub.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=\ngithub.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=\ngithub.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=\ngithub.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=\ngithub.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=\ngithub.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=\ngithub.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=\ngithub.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=\ngithub.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM=\ngithub.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=\ngithub.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=\ngithub.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=\ngithub.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=\ngithub.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=\ngithub.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=\ngithub.com/golangci/check v0.0.0-20180506172741-cfe4005ccda2 h1:23T5iq8rbUYlhpt5DB4XJkc6BU31uODLD1o1gKvZmD0=\ngithub.com/golangci/check v0.0.0-20180506172741-cfe4005ccda2/go.mod h1:k9Qvh+8juN+UKMCS/3jFtGICgW8O96FVaZsaxdzDkR4=\ngithub.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a h1:w8hkcTqaFpzKqonE9uMCefW1WDie15eSP/4MssdenaM=\ngithub.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a/go.mod h1:ryS0uhF+x9jgbj/N71xsEqODy9BN81/GonCZiOzirOk=\ngithub.com/golangci/go-misc v0.0.0-20180628070357-927a3d87b613 h1:9kfjN3AdxcbsZBf8NjltjWihK2QfBBBZuv91cMFfDHw=\ngithub.com/golangci/go-misc v0.0.0-20180628070357-927a3d87b613/go.mod h1:SyvUF2NxV+sN8upjjeVYr5W7tyxaT1JVtvhKhOn2ii8=\ngithub.com/golangci/go-misc v0.0.0-20220329215616-d24fe342adfe h1:6RGUuS7EGotKx6J5HIP8ZtyMdiDscjMLfRBSPuzVVeo=\ngithub.com/golangci/go-misc v0.0.0-20220329215616-d24fe342adfe/go.mod h1:gjqyPShc/m8pEMpk0a3SeagVb0kaqvhscv+i9jI5ZhQ=\ngithub.com/golangci/gofmt v0.0.0-20190930125516-244bba706f1a h1:iR3fYXUjHCR97qWS8ch1y9zPNsgXThGwjKPrYfqMPks=\ngithub.com/golangci/gofmt v0.0.0-20190930125516-244bba706f1a/go.mod h1:9qCChq59u/eW8im404Q2WWTrnBUQKjpNYKMbU4M7EFU=\ngithub.com/golangci/gofmt v0.0.0-20240816233607-d8596aa466a9 h1:/1322Qns6BtQxUZDTAT4SdcoxknUki7IAoK4SAXr8ME=\ngithub.com/golangci/gofmt v0.0.0-20240816233607-d8596aa466a9/go.mod h1:Oesb/0uFAyWoaw1U1qS5zyjCg5NP9C9iwjnI4tIsXEE=\ngithub.com/golangci/golangci-lint v1.38.0 h1:hgZsLRzZrjhpp44Ak+fhXNzgrbDF39ETf22a+Jd3fJQ=\ngithub.com/golangci/golangci-lint v1.38.0/go.mod h1:Knp/sd5ATrVp7EOzWzwIIFH+c8hUfpW+oOQb8NvdZDo=\ngithub.com/golangci/golangci-lint v1.61.0 h1:VvbOLaRVWmyxCnUIMTbf1kDsaJbTzH20FAMXTAlQGu8=\ngithub.com/golangci/golangci-lint v1.61.0/go.mod h1:e4lztIrJJgLPhWvFPDkhiMwEFRrWlmFbrZea3FsJyN8=\ngithub.com/golangci/lint-1 v0.0.0-20191013205115-297bf364a8e0 h1:MfyDlzVjl1hoaPzPD4Gpb/QgoRfSBR0jdhwGyAWwMSA=\ngithub.com/golangci/lint-1 v0.0.0-20191013205115-297bf364a8e0/go.mod h1:66R6K6P6VWk9I95jvqGxkqJxVWGFy9XlDwLwVz1RCFg=\ngithub.com/golangci/maligned v0.0.0-20180506175553-b1d89398deca h1:kNY3/svz5T29MYHubXix4aDDuE3RWHkPvopM/EDv/MA=\ngithub.com/golangci/maligned v0.0.0-20180506175553-b1d89398deca/go.mod h1:tvlJhZqDe4LMs4ZHD0oMUlt9G2LWuDGoisJTBzLMV9o=\ngithub.com/golangci/misspell v0.3.5 h1:pLzmVdl3VxTOncgzHcvLOKirdvcx/TydsClUQXTehjo=\ngithub.com/golangci/misspell v0.3.5/go.mod h1:dEbvlSfYbMQDtrpRMQU675gSDLDNa8sCPPChZ7PhiVA=\ngithub.com/golangci/misspell v0.6.0 h1:JCle2HUTNWirNlDIAUO44hUsKhOFqGPoC4LZxlaSXDs=\ngithub.com/golangci/misspell v0.6.0/go.mod h1:keMNyY6R9isGaSAu+4Q8NMBwMPkh15Gtc8UCVoDtAWo=\ngithub.com/golangci/modinfo v0.3.4 h1:oU5huX3fbxqQXdfspamej74DFX0kyGLkw1ppvXoJ8GA=\ngithub.com/golangci/modinfo v0.3.4/go.mod h1:wytF1M5xl9u0ij8YSvhkEVPP3M5Mc7XLl1pxH3B2aUM=\ngithub.com/golangci/plugin-module-register v0.1.1 h1:TCmesur25LnyJkpsVrupv1Cdzo+2f7zX0H6Jkw1Ol6c=\ngithub.com/golangci/plugin-module-register v0.1.1/go.mod h1:TTpqoB6KkwOJMV8u7+NyXMrkwwESJLOkfl9TxR1DGFc=\ngithub.com/golangci/revgrep v0.0.0-20210208091834-cd28932614b5 h1:c9Mqqrm/Clj5biNaG7rABrmwUq88nHh0uABo2b/WYmc=\ngithub.com/golangci/revgrep v0.0.0-20210208091834-cd28932614b5/go.mod h1:LK+zW4MpyytAWQRz0M4xnzEk50lSvqDQKfx304apFkY=\ngithub.com/golangci/revgrep v0.5.3 h1:3tL7c1XBMtWHHqVpS5ChmiAAoe4PF/d5+ULzV9sLAzs=\ngithub.com/golangci/revgrep v0.5.3/go.mod h1:U4R/s9dlXZsg8uJmaR1GrloUr14D7qDl8gi2iPXJH8k=\ngithub.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4 h1:zwtduBRr5SSWhqsYNgcuWO2kFlpdOZbP0+yRjmvPGys=\ngithub.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4/go.mod h1:Izgrg8RkN3rCIMLGE9CyYmU9pY2Jer6DgANEnZ/L/cQ=\ngithub.com/golangci/unconvert v0.0.0-20240309020433-c5143eacb3ed h1:IURFTjxeTfNFP0hTEi1YKjB/ub8zkpaOqFFMApi2EAs=\ngithub.com/golangci/unconvert v0.0.0-20240309020433-c5143eacb3ed/go.mod h1:XLXN8bNw4CGRPaqgl3bv/lhz7bsGPh4/xSaMTbo2vkQ=\ngithub.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=\ngithub.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=\ngithub.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4=\ngithub.com/google/certificate-transparency-go v1.0.21/go.mod h1:QeJfpSbVSfYc7RgB3gJFj9cbuQMMchQxrWXz8Ruopmg=\ngithub.com/google/certificate-transparency-go v1.1.1/go.mod h1:FDKqPvSXawb2ecErVRrD+nfy23RCzyl7eqVCEmlT1Zs=\ngithub.com/google/flatbuffers v2.0.8+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8=\ngithub.com/google/flatbuffers v23.5.26+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8=\ngithub.com/google/generative-ai-go v0.18.0/go.mod h1:JYolL13VG7j79kM5BtHz4qwONHkeJQzOCkKXnpqtS/E=\ngithub.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=\ngithub.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=\ngithub.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=\ngithub.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=\ngithub.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=\ngithub.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=\ngithub.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=\ngithub.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=\ngithub.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=\ngithub.com/google/go-pkcs11 v0.3.0/go.mod h1:6eQoGcuNJpa7jnd5pMGdkSaQpNDYvPlXWMcjXXThLlY=\ngithub.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=\ngithub.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=\ngithub.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=\ngithub.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=\ngithub.com/google/martian/v3 v3.2.1/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk=\ngithub.com/google/martian/v3 v3.3.2/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk=\ngithub.com/google/martian/v3 v3.3.3/go.mod h1:iEPrYcgCF7jA9OtScMFQyAlZZ4YXTKEtJ1E6RWzmBA0=\ngithub.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=\ngithub.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=\ngithub.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=\ngithub.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=\ngithub.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=\ngithub.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=\ngithub.com/google/pprof v0.0.0-20200507031123-427632fa3b1c/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=\ngithub.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=\ngithub.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=\ngithub.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=\ngithub.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=\ngithub.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=\ngithub.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=\ngithub.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=\ngithub.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=\ngithub.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=\ngithub.com/google/pprof v0.0.0-20240827171923-fa2c70bbbfe5/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144=\ngithub.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=\ngithub.com/google/s2a-go v0.1.8/go.mod h1:6iNWHTpQ+nfNRN5E00MSdfDwVesa8hhS32PhPO8deJA=\ngithub.com/google/trillian v1.3.11/go.mod h1:0tPraVHrSDkA3BO6vKX67zgLXs6SsOAbHEivX+9mPgw=\ngithub.com/google/uuid v0.0.0-20161128191214-064e2069ce9c/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=\ngithub.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=\ngithub.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=\ngithub.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=\ngithub.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=\ngithub.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=\ngithub.com/googleapis/cloud-bigtable-clients-test v0.0.2/go.mod h1:mk3CrkrouRgtnhID6UZQDK3DrFFa7cYCAJcEmNsHYrY=\ngithub.com/googleapis/enterprise-certificate-proxy v0.0.0-20220520183353-fd19c99a87aa/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8=\ngithub.com/googleapis/enterprise-certificate-proxy v0.1.0/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8=\ngithub.com/googleapis/enterprise-certificate-proxy v0.2.0/go.mod h1:8C0jb7/mgJe/9KK8Lm7X9ctZC2t60YyIpYEI16jx0Qg=\ngithub.com/googleapis/enterprise-certificate-proxy v0.2.1/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k=\ngithub.com/googleapis/enterprise-certificate-proxy v0.2.3/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k=\ngithub.com/googleapis/enterprise-certificate-proxy v0.3.4/go.mod h1:YKe7cfqYXjKGpGvmSg28/fFvhNzinZQm8DGnaburhGA=\ngithub.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=\ngithub.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=\ngithub.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0=\ngithub.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0eJc8R6ouapiM=\ngithub.com/googleapis/gax-go/v2 v2.2.0/go.mod h1:as02EH8zWkzwUoLbBaFeQ+arQaj/OthfcblKl4IGNaM=\ngithub.com/googleapis/gax-go/v2 v2.3.0/go.mod h1:b8LNqSzNabLiUpXKkY7HAR5jr6bIT99EXz9pXxye9YM=\ngithub.com/googleapis/gax-go/v2 v2.4.0/go.mod h1:XOTVJ59hdnfJLIP/dh8n5CGryZR2LxK9wbMD5+iXC6c=\ngithub.com/googleapis/gax-go/v2 v2.5.1/go.mod h1:h6B0KMMFNtI2ddbGJn3T3ZbwkeT6yqEF02fYlzkUCyo=\ngithub.com/googleapis/gax-go/v2 v2.6.0/go.mod h1:1mjbznJAPHFpesgE5ucqfYEscaz5kMdcIDwU/6+DDoY=\ngithub.com/googleapis/gax-go/v2 v2.7.0/go.mod h1:TEop28CZZQ2y+c0VxMUmu1lV+fQx57QpBWsYpwqHJx8=\ngithub.com/googleapis/gax-go/v2 v2.7.1/go.mod h1:4orTrqY6hXxxaUL4LHIPl6lGo8vAE38/qKbhSAKP6QI=\ngithub.com/googleapis/gax-go/v2 v2.13.0/go.mod h1:Z/fvTZXF8/uw7Xu5GuslPw+bplx6SS338j1Is2S+B7A=\ngithub.com/googleapis/go-type-adapters v1.0.0/go.mod h1:zHW75FOG2aur7gAO2B+MLby+cLsWGBF62rFAi7WjWO4=\ngithub.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g=\ngithub.com/googleapis/google-cloud-go-testing v0.0.0-20210719221736-1c9a4c676720/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g=\ngithub.com/gookit/color v1.3.6/go.mod h1:R3ogXq2B9rTbXoSHJ1HyUVAZ3poOJHpd9nQmyGZsfvQ=\ngithub.com/gookit/color v1.3.8/go.mod h1:R3ogXq2B9rTbXoSHJ1HyUVAZ3poOJHpd9nQmyGZsfvQ=\ngithub.com/gookit/color v1.5.4/go.mod h1:pZJOeOS8DM43rXbp4AZo1n9zCU2qjpcRko0b6/QJi9w=\ngithub.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=\ngithub.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=\ngithub.com/gordonklaus/ineffassign v0.0.0-20200309095847-7953dde2c7bf/go.mod h1:cuNKsD1zp2v6XfE/orVX2QE1LC+i254ceGcVeDT3pTU=\ngithub.com/gordonklaus/ineffassign v0.0.0-20210225214923-2e10b2664254 h1:Nb2aRlC404yz7gQIfRZxX9/MLvQiqXyiBTJtgAy6yrI=\ngithub.com/gordonklaus/ineffassign v0.0.0-20210225214923-2e10b2664254/go.mod h1:M9mZEtGIsR1oDaZagNPNG9iq9n2HrhZ17dsXk73V3Lw=\ngithub.com/gordonklaus/ineffassign v0.1.0 h1:y2Gd/9I7MdY1oEIt+n+rowjBNDcLQq3RsH5hwJd0f9s=\ngithub.com/gordonklaus/ineffassign v0.1.0/go.mod h1:Qcp2HIAYhR7mNUVSIxZww3Guk4it82ghYcEXIAk+QT0=\ngithub.com/gorhill/cronexpr v0.0.0-20180427100037-88b0669f7d75/go.mod h1:g2644b03hfBX9Ov0ZBDgXXens4rxSxmqFBbhvKv2yVA=\ngithub.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=\ngithub.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=\ngithub.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=\ngithub.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=\ngithub.com/gostaticanalysis/analysisutil v0.0.0-20190318220348-4088753ea4d3/go.mod h1:eEOZF4jCKGi+aprrirO9e7WKB3beBRtWgqGunKl6pKE=\ngithub.com/gostaticanalysis/analysisutil v0.0.3/go.mod h1:eEOZF4jCKGi+aprrirO9e7WKB3beBRtWgqGunKl6pKE=\ngithub.com/gostaticanalysis/analysisutil v0.1.0/go.mod h1:dMhHRU9KTiDcuLGdy87/2gTR8WruwYZrKdRq9m1O6uw=\ngithub.com/gostaticanalysis/analysisutil v0.4.1/go.mod h1:18U/DLpRgIUd459wGxVHE0fRgmo1UgHDcbw7F5idXu0=\ngithub.com/gostaticanalysis/analysisutil v0.6.1 h1:/1JkoHe4DVxur+0wPvi26FoQfe1E3ZGqIXS3aaSLiaw=\ngithub.com/gostaticanalysis/analysisutil v0.6.1/go.mod h1:18U/DLpRgIUd459wGxVHE0fRgmo1UgHDcbw7F5idXu0=\ngithub.com/gostaticanalysis/analysisutil v0.7.1 h1:ZMCjoue3DtDWQ5WyU16YbjbQEQ3VuzwxALrpYd+HeKk=\ngithub.com/gostaticanalysis/analysisutil v0.7.1/go.mod h1:v21E3hY37WKMGSnbsw2S/ojApNWb6C1//mXO48CXbVc=\ngithub.com/gostaticanalysis/comment v1.3.0/go.mod h1:xMicKDx7XRXYdVwY9f9wQpDJVnqWxw9wCauCMKp+IBI=\ngithub.com/gostaticanalysis/comment v1.4.1 h1:xHopR5L2lRz6OsjH4R2HG5wRhW9ySl3FsHIvi5pcXwc=\ngithub.com/gostaticanalysis/comment v1.4.1/go.mod h1:ih6ZxzTHLdadaiSnF5WY3dxUoXfXAlTaRzuaNDlSado=\ngithub.com/gostaticanalysis/comment v1.4.2 h1:hlnx5+S2fY9Zo9ePo4AhgYsYHbM2+eAv8m/s1JiCd6Q=\ngithub.com/gostaticanalysis/comment v1.4.2/go.mod h1:KLUTGDv6HOCotCH8h2erHKmpci2ZoR8VPu34YA2uzdM=\ngithub.com/gostaticanalysis/forcetypeassert v0.0.0-20200621232751-01d4955beaa5 h1:rx8127mFPqXXsfPSo8BwnIU97MKFZc89WHAHt8PwDVY=\ngithub.com/gostaticanalysis/forcetypeassert v0.0.0-20200621232751-01d4955beaa5/go.mod h1:qZEedyP/sY1lTGV1uJ3VhWZ2mqag3IkWsDHVbplHXak=\ngithub.com/gostaticanalysis/forcetypeassert v0.1.0 h1:6eUflI3DiGusXGK6X7cCcIgVCpZ2CiZ1Q7jl6ZxNV70=\ngithub.com/gostaticanalysis/forcetypeassert v0.1.0/go.mod h1:qZEedyP/sY1lTGV1uJ3VhWZ2mqag3IkWsDHVbplHXak=\ngithub.com/gostaticanalysis/nilerr v0.1.1 h1:ThE+hJP0fEp4zWLkWHWcRyI2Od0p7DlgYG3Uqrmrcpk=\ngithub.com/gostaticanalysis/nilerr v0.1.1/go.mod h1:wZYb6YI5YAxxq0i1+VJbY0s2YONW0HU0GPE3+5PWN4A=\ngithub.com/gostaticanalysis/testutil v0.3.1-0.20210208050101-bfb5c8eec0e4/go.mod h1:D+FIZ+7OahH3ePw/izIEeH5I06eKs1IKI4Xr64/Am3M=\ngithub.com/gostaticanalysis/testutil v0.4.0/go.mod h1:bLIoPefWXrRi/ssLFWX1dx7Repi5x3CuviD3dgAZaBU=\ngithub.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=\ngithub.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=\ngithub.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=\ngithub.com/grpc-ecosystem/go-grpc-middleware v1.2.2/go.mod h1:EaizFBKfUKtMIF5iaDEhniwNedqGo9FuLFzppDr3uwI=\ngithub.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=\ngithub.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=\ngithub.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=\ngithub.com/grpc-ecosystem/grpc-gateway v1.12.1/go.mod h1:8XEsbTttt/W+VvjtQhLACqCisSPWTxCZ7sBRjU6iH9c=\ngithub.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=\ngithub.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0/go.mod h1:hgWBS7lorOAVIJEQMi4ZsPv9hVvWI6+ch50m39Pf2Ks=\ngithub.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3/go.mod h1:o//XUCC/F+yRGJoPO/VU0GSB0f8Nhgmxx0VIRUvaC0w=\ngithub.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0/go.mod h1:YN5jB8ie0yfIUg6VvR9Kz84aCaG7AsGZnLjhHbUqwPg=\ngithub.com/hamba/avro/v2 v2.17.2/go.mod h1:Q9YK+qxAhtVrNqOhwlZTATLgLA8qxG2vtvkhK8fJ7Jo=\ngithub.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q=\ngithub.com/hashicorp/consul/api v1.28.2/go.mod h1:KyzqzgMEya+IZPcD65YFoOVAgPpbfERu4I/tzG6/ueE=\ngithub.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=\ngithub.com/hashicorp/consul/sdk v0.16.0/go.mod h1:7pxqqhqoaPqnBnzXD1StKed62LqJeClzVsUEy85Zr0A=\ngithub.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=\ngithub.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=\ngithub.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=\ngithub.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=\ngithub.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48=\ngithub.com/hashicorp/go-hclog v1.5.0/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M=\ngithub.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=\ngithub.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=\ngithub.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=\ngithub.com/hashicorp/go-msgpack v0.5.5/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=\ngithub.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=\ngithub.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA=\ngithub.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=\ngithub.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs=\ngithub.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU=\ngithub.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8=\ngithub.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU=\ngithub.com/hashicorp/go-sockaddr v1.0.2/go.mod h1:rB4wwRAUzs07qva3c5SdrY/NEtAUjGlgmH/UkBUC97A=\ngithub.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4=\ngithub.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=\ngithub.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=\ngithub.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=\ngithub.com/hashicorp/go-version v1.2.1/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=\ngithub.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY=\ngithub.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=\ngithub.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90=\ngithub.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=\ngithub.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=\ngithub.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=\ngithub.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=\ngithub.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=\ngithub.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=\ngithub.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ=\ngithub.com/hashicorp/mdns v1.0.4/go.mod h1:mtBihi+LeNXGtG8L9dX59gAEa12BDtBQSp4v/YAJqrc=\ngithub.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=\ngithub.com/hashicorp/memberlist v0.5.0/go.mod h1:yvyXLpo0QaGE59Y7hDTsTzDD25JYBZ4mHgHUZ8lrOI0=\ngithub.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=\ngithub.com/hashicorp/serf v0.10.1/go.mod h1:yL2t6BqATOLGc5HF7qbFkTfXoPIY0WZdWHfEvMqbG+4=\ngithub.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM=\ngithub.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg=\ngithub.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=\ngithub.com/huandu/xstrings v1.0.0/go.mod h1:4qWG/gcEcfX4z/mBDHJ++3ReCw9ibxbsNJbcucJdbSo=\ngithub.com/huandu/xstrings v1.2.0/go.mod h1:DvyZB1rfVYsBIigL8HwpZgxHwXozlTgGqn63UyNX5k4=\ngithub.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho=\ngithub.com/iancoleman/strcase v0.3.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho=\ngithub.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=\ngithub.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=\ngithub.com/ianlancetaylor/demangle v0.0.0-20240312041847-bd984b5ce465/go.mod h1:gx7rwoVhcfuVKG5uya9Hs3Sxj7EIvldVofAWIUtGouw=\ngithub.com/imdario/mergo v0.3.4/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=\ngithub.com/imdario/mergo v0.3.8/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=\ngithub.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=\ngithub.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=\ngithub.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=\ngithub.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=\ngithub.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=\ngithub.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=\ngithub.com/jackc/pgx/v5 v5.4.3/go.mod h1:Ig06C2Vu0t5qXC60W8sqIthScaEnFvojjj9dSljmHRA=\ngithub.com/jackc/puddle/v2 v2.2.1/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=\ngithub.com/jgautheron/goconst v1.4.0 h1:hp9XKUpe/MPyDamUbfsrGpe+3dnY2whNK4EtB86dvLM=\ngithub.com/jgautheron/goconst v1.4.0/go.mod h1:aAosetZ5zaeC/2EfMeRswtxUFBpe2Hr7HzkgX4fanO4=\ngithub.com/jgautheron/goconst v1.7.1 h1:VpdAG7Ca7yvvJk5n8dMwQhfEZJh95kl/Hl9S1OI5Jkk=\ngithub.com/jgautheron/goconst v1.7.1/go.mod h1:aAosetZ5zaeC/2EfMeRswtxUFBpe2Hr7HzkgX4fanO4=\ngithub.com/jhump/protoreflect v1.6.1/go.mod h1:RZQ/lnuN+zqeRVpQigTwO6o0AJUkxbnSnpuG7toUTG4=\ngithub.com/jingyugao/rowserrcheck v0.0.0-20210130005344-c6a0c12dd98d h1:BYDZtm80MLJpTWalkwHxNnIbO/2akQHERcfLq4TbIWE=\ngithub.com/jingyugao/rowserrcheck v0.0.0-20210130005344-c6a0c12dd98d/go.mod h1:/EZlaYCnEX24i7qdVhT9du5JrtFWYRQr67bVgR7JJC8=\ngithub.com/jingyugao/rowserrcheck v1.1.1 h1:zibz55j/MJtLsjP1OF4bSdgXxwL1b+Vn7Tjzq7gFzUs=\ngithub.com/jingyugao/rowserrcheck v1.1.1/go.mod h1:4yvlZSDb3IyDTUZJUmpZfm2Hwok+Dtp+nu2qOq+er9c=\ngithub.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af h1:KA9BjwUk7KlCh6S9EAGWBt1oExIUv9WyNCiRz5amv48=\ngithub.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af/go.mod h1:HEWGJkRDzjJY2sqdDwxccsGicWEf9BQOZsq2tV+xzM0=\ngithub.com/jjti/go-spancheck v0.6.2 h1:iYtoxqPMzHUPp7St+5yA8+cONdyXD3ug6KK15n7Pklk=\ngithub.com/jjti/go-spancheck v0.6.2/go.mod h1:+X7lvIrR5ZdUTkxFYqzJ0abr8Sb5LOo80uOhWNqIrYA=\ngithub.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=\ngithub.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=\ngithub.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=\ngithub.com/jmoiron/sqlx v1.2.0/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks=\ngithub.com/jmoiron/sqlx v1.3.5/go.mod h1:nRVWtLre0KfCLJvgxzCsLVMogSvQ1zNJtpYr2Ccp0mQ=\ngithub.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=\ngithub.com/jonboulle/clockwork v0.2.0/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8=\ngithub.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=\ngithub.com/josharian/txtarfs v0.0.0-20210218200122-0702f000015a/go.mod h1:izVPOvVRsHiKkeGCT6tYBNWyDVuzj9wAaBb5R9qamfw=\ngithub.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=\ngithub.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=\ngithub.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=\ngithub.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=\ngithub.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=\ngithub.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=\ngithub.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=\ngithub.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=\ngithub.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=\ngithub.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=\ngithub.com/juju/ratelimit v1.0.1/go.mod h1:qapgC/Gy+xNh9UxzV13HGGl/6UXNN+ct+vwSgWNm/qk=\ngithub.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=\ngithub.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=\ngithub.com/julz/importas v0.0.0-20210226073942-60b4fa260dd0/go.mod h1:oSFU2R4XK/P7kNBrnL/FEQlDGN1/6WoxXEjSSXO0DV0=\ngithub.com/julz/importas v0.0.0-20210228071311-d0bf5cb4e1db h1:ZmwBthGFMVAieuVpLzuedUH9l4pY/0iFG16DN9dS38o=\ngithub.com/julz/importas v0.0.0-20210228071311-d0bf5cb4e1db/go.mod h1:oSFU2R4XK/P7kNBrnL/FEQlDGN1/6WoxXEjSSXO0DV0=\ngithub.com/julz/importas v0.1.0 h1:F78HnrsjY3cR7j0etXy5+TU1Zuy7Xt08X/1aJnH5xXY=\ngithub.com/julz/importas v0.1.0/go.mod h1:oSFU2R4XK/P7kNBrnL/FEQlDGN1/6WoxXEjSSXO0DV0=\ngithub.com/jung-kurt/gofpdf v1.0.0/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes=\ngithub.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes=\ngithub.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k=\ngithub.com/karamaru-alpha/copyloopvar v1.1.0 h1:x7gNyKcC2vRBO1H2Mks5u1VxQtYvFiym7fCjIP8RPos=\ngithub.com/karamaru-alpha/copyloopvar v1.1.0/go.mod h1:u7CIfztblY0jZLOQZgH3oYsJzpC2A7S6u/lfgSXHy0k=\ngithub.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=\ngithub.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=\ngithub.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=\ngithub.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=\ngithub.com/kisielk/errcheck v1.6.0 h1:YTDO4pNy7AUN/021p+JGHycQyYNIyMoenM1YDVK6RlY=\ngithub.com/kisielk/errcheck v1.6.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=\ngithub.com/kisielk/errcheck v1.7.0 h1:+SbscKmWJ5mOK/bO1zS60F5I9WwZDWOfRsC4RwfwRV0=\ngithub.com/kisielk/errcheck v1.7.0/go.mod h1:1kLL+jV4e+CFfueBmI1dSK2ADDyQnlrnrY/FqKluHJQ=\ngithub.com/kisielk/gotool v1.0.0 h1:AV2c/EiW3KqPNT9ZKl07ehoAGi4C5/01Cfbblndcapg=\ngithub.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=\ngithub.com/kkHAIKE/contextcheck v1.1.5 h1:CdnJh63tcDe53vG+RebdpdXJTc9atMgGqdx8LXxiilg=\ngithub.com/kkHAIKE/contextcheck v1.1.5/go.mod h1:O930cpht4xb1YQpK+1+AgoM3mFsvxr7uyFptcnWTYUA=\ngithub.com/klauspost/asmfmt v1.3.2/go.mod h1:AG8TuvYojzulgDAMCnYn50l/5QV3Bs/tp6j0HLHbNSE=\ngithub.com/klauspost/compress v1.10.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=\ngithub.com/klauspost/compress v1.11.0/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=\ngithub.com/klauspost/compress v1.15.9/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU=\ngithub.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=\ngithub.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=\ngithub.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=\ngithub.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=\ngithub.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=\ngithub.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=\ngithub.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=\ngithub.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=\ngithub.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=\ngithub.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=\ngithub.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=\ngithub.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=\ngithub.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=\ngithub.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=\ngithub.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=\ngithub.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=\ngithub.com/kulti/thelper v0.4.0 h1:2Nx7XbdbE/BYZeoip2mURKUdtHQRuy6Ug+wR7K9ywNM=\ngithub.com/kulti/thelper v0.4.0/go.mod h1:vMu2Cizjy/grP+jmsvOFDx1kYP6+PD1lqg4Yu5exl2U=\ngithub.com/kulti/thelper v0.6.3 h1:ElhKf+AlItIu+xGnI990no4cE2+XaSu1ULymV2Yulxs=\ngithub.com/kulti/thelper v0.6.3/go.mod h1:DsqKShOvP40epevkFrvIwkCMNYxMeTNjdWL4dqWHZ6I=\ngithub.com/kunwardeep/paralleltest v1.0.2 h1:/jJRv0TiqPoEy/Y8dQxCFJhD56uS/pnvtatgTZBHokU=\ngithub.com/kunwardeep/paralleltest v1.0.2/go.mod h1:ZPqNm1fVHPllh5LPVujzbVz1JN2GhLxSfY+oqUsvG30=\ngithub.com/kunwardeep/paralleltest v1.0.10 h1:wrodoaKYzS2mdNVnc4/w31YaXFtsc21PCTdvWJ/lDDs=\ngithub.com/kunwardeep/paralleltest v1.0.10/go.mod h1:2C7s65hONVqY7Q5Efj5aLzRCNLjw2h4eMc9EcypGjcY=\ngithub.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=\ngithub.com/kyoh86/exportloopref v0.1.8 h1:5Ry/at+eFdkX9Vsdw3qU4YkvGtzuVfzT4X7S77LoN/M=\ngithub.com/kyoh86/exportloopref v0.1.8/go.mod h1:1tUcJeiioIs7VWe5gcOObrux3lb66+sBqGZrRkMwPgg=\ngithub.com/kyoh86/exportloopref v0.1.11 h1:1Z0bcmTypkL3Q4k+IDHMWTcnCliEZcaPiIe0/ymEyhQ=\ngithub.com/kyoh86/exportloopref v0.1.11/go.mod h1:qkV4UF1zGl6EkF1ox8L5t9SwyeBAZ3qLMd6up458uqA=\ngithub.com/lasiar/canonicalheader v1.1.1 h1:wC+dY9ZfiqiPwAexUApFush/csSPXeIi4QqyxXmng8I=\ngithub.com/lasiar/canonicalheader v1.1.1/go.mod h1:cXkb3Dlk6XXy+8MVQnF23CYKWlyA7kfQhSw2CcZtZb0=\ngithub.com/ldez/gomoddirectives v0.2.4 h1:j3YjBIjEBbqZ0NKtBNzr8rtMHTOrLPeiwTkfUJZ3alg=\ngithub.com/ldez/gomoddirectives v0.2.4/go.mod h1:oWu9i62VcQDYp9EQ0ONTfqLNh+mDLWWDO+SO0qSQw5g=\ngithub.com/ldez/tagliatelle v0.5.0 h1:epgfuYt9v0CG3fms0pEgIMNPuFf/LpPIfjk4kyqSioo=\ngithub.com/ldez/tagliatelle v0.5.0/go.mod h1:rj1HmWiL1MiKQuOONhd09iySTEkUuE/8+5jtPYz9xa4=\ngithub.com/ledongthuc/pdf v0.0.0-20220302134840-0c2507a12d80/go.mod h1:imJHygn/1yfhB7XSJJKlFZKl/J+dCPAknuiaGOshXAs=\ngithub.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=\ngithub.com/leonklingele/grouper v1.1.2 h1:o1ARBDLOmmasUaNDesWqWCIFH3u7hoFlM84YrjT3mIY=\ngithub.com/leonklingele/grouper v1.1.2/go.mod h1:6D0M/HVkhs2yRKRFZUoGjeDy7EZTfFBE9gl4kjmIGkA=\ngithub.com/letsencrypt/pkcs11key/v4 v4.0.0/go.mod h1:EFUvBDay26dErnNb70Nd0/VW3tJiIbETBPTl9ATXQag=\ngithub.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=\ngithub.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=\ngithub.com/lib/pq v1.8.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=\ngithub.com/lib/pq v1.9.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=\ngithub.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=\ngithub.com/logrusorgru/aurora v0.0.0-20181002194514-a7b3b318ed4e/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4=\ngithub.com/lufeee/execinquery v1.2.1 h1:hf0Ems4SHcUGBxpGN7Jz78z1ppVkP/837ZlETPCEtOM=\ngithub.com/lufeee/execinquery v1.2.1/go.mod h1:EC7DrEKView09ocscGHC+apXMIaorh4xqSxS/dy8SbM=\ngithub.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I=\ngithub.com/lyft/protoc-gen-star v0.6.0/go.mod h1:TGAoBVkt8w7MPG72TrKIu85MIdXwDuzJYeZuUPFPNwA=\ngithub.com/lyft/protoc-gen-star v0.6.1/go.mod h1:TGAoBVkt8w7MPG72TrKIu85MIdXwDuzJYeZuUPFPNwA=\ngithub.com/lyft/protoc-gen-star/v2 v2.0.1/go.mod h1:RcCdONR2ScXaYnQC5tUzxzlpA3WVYF7/opLeUgcQs/o=\ngithub.com/lyft/protoc-gen-star/v2 v2.0.4-0.20230330145011-496ad1ac90a4/go.mod h1:amey7yeodaJhXSbf/TlLvWiqQfLOSpEk//mLlc+axEk=\ngithub.com/macabu/inamedparam v0.1.3 h1:2tk/phHkMlEL/1GNe/Yf6kkR/hkcUdAEY3L0hjYV1Mk=\ngithub.com/macabu/inamedparam v0.1.3/go.mod h1:93FLICAIk/quk7eaPPQvbzihUdn/QkGDwIZEoLtpH6I=\ngithub.com/magefile/mage v1.10.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A=\ngithub.com/magefile/mage v1.11.0 h1:C/55Ywp9BpgVVclD3lRnSYCwXTYxmSppIgLeDYlNuls=\ngithub.com/magefile/mage v1.11.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A=\ngithub.com/magefile/mage v1.15.0 h1:BvGheCMAsG3bWUDbZ8AyXXpCNwU9u5CB6sM+HNb9HYg=\ngithub.com/magefile/mage v1.15.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A=\ngithub.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=\ngithub.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=\ngithub.com/magiconair/properties v1.8.4 h1:8KGKTcQQGm0Kv7vEbKFErAoAOFyyacLStRtQSeYtvkY=\ngithub.com/magiconair/properties v1.8.4/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=\ngithub.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY=\ngithub.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=\ngithub.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=\ngithub.com/maratori/testableexamples v1.0.0 h1:dU5alXRrD8WKSjOUnmJZuzdxWOEQ57+7s93SLMxb2vI=\ngithub.com/maratori/testableexamples v1.0.0/go.mod h1:4rhjL1n20TUTT4vdh3RDqSizKLyXp7K2u6HgraZCGzE=\ngithub.com/maratori/testpackage v1.0.1 h1:QtJ5ZjqapShm0w5DosRjg0PRlSdAdlx+W6cCKoALdbQ=\ngithub.com/maratori/testpackage v1.0.1/go.mod h1:ddKdw+XG0Phzhx8BFDTKgpWP4i7MpApTE5fXSKAqwDU=\ngithub.com/maratori/testpackage v1.1.1 h1:S58XVV5AD7HADMmD0fNnziNHqKvSdDuEKdPD1rNTU04=\ngithub.com/maratori/testpackage v1.1.1/go.mod h1:s4gRK/ym6AMrqpOa/kEbQTV4Q4jb7WeLZzVhVVVOQMc=\ngithub.com/matm/gocov-html v0.0.0-20200509184451-71874e2e203b h1:5Wc/N1FIBnExmX0/SEdKe0A0COvdJc3rCGHQ7s1oBPQ=\ngithub.com/matm/gocov-html v0.0.0-20200509184451-71874e2e203b/go.mod h1:zha4ZSIA/qviBBKx3j6tJG/Lx6aIdjOXPWuKAcJchQM=\ngithub.com/matoous/godox v0.0.0-20210227103229-6504466cf951 h1:pWxk9e//NbPwfxat7RXkts09K+dEBJWakUWwICVqYbA=\ngithub.com/matoous/godox v0.0.0-20210227103229-6504466cf951/go.mod h1:1BELzlh859Sh1c6+90blK8lbYy0kwQf1bYlBhBysy1s=\ngithub.com/matoous/godox v0.0.0-20240105082147-c5b5e0e7c0c0 h1:Ny7cm4KSWceJLYyI1sm+aFIVDWSGXLcOJ0O0UaS5wdU=\ngithub.com/matoous/godox v0.0.0-20240105082147-c5b5e0e7c0c0/go.mod h1:jgE/3fUXiTurkdHOLT5WEkThTSuE7yxHv5iWPa80afs=\ngithub.com/matryer/is v1.4.0/go.mod h1:8I/i5uYgLzgsgEloJE1U6xx5HkBQpAZvepWuujKwMRU=\ngithub.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=\ngithub.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=\ngithub.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=\ngithub.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ0s8=\ngithub.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=\ngithub.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=\ngithub.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=\ngithub.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=\ngithub.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=\ngithub.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=\ngithub.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=\ngithub.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=\ngithub.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84=\ngithub.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE=\ngithub.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=\ngithub.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=\ngithub.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=\ngithub.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=\ngithub.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=\ngithub.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=\ngithub.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=\ngithub.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=\ngithub.com/mattn/go-runewidth v0.0.6/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=\ngithub.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=\ngithub.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=\ngithub.com/mattn/go-runewidth v0.0.10 h1:CoZ3S2P7pvtP45xOtBw+/mDL2z0RKI576gSkzRRpdGg=\ngithub.com/mattn/go-runewidth v0.0.10/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=\ngithub.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc=\ngithub.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=\ngithub.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=\ngithub.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=\ngithub.com/mattn/go-sqlite3 v1.14.14/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=\ngithub.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=\ngithub.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw=\ngithub.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=\ngithub.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo=\ngithub.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=\ngithub.com/mbilski/exhaustivestruct v1.2.0 h1:wCBmUnSYufAHO6J4AVWY6ff+oxWxsVFrwgOdMUQePUo=\ngithub.com/mbilski/exhaustivestruct v1.2.0/go.mod h1:OeTBVxQWoEmB2J2JCHmXWPJ0aksxSUOUy+nvtVEfzXc=\ngithub.com/mgechev/dots v0.0.0-20190921121421-c36f7dcfbb81 h1:QASJXOGm2RZ5Ardbc86qNFvby9AqkLDibfChMtAg5QM=\ngithub.com/mgechev/dots v0.0.0-20190921121421-c36f7dcfbb81/go.mod h1:KQ7+USdGKfpPjXk4Ga+5XxQM4Lm4e3gAogrreFAYpOg=\ngithub.com/mgechev/dots v0.0.0-20210922191527-e955255bf517 h1:zpIH83+oKzcpryru8ceC6BxnoG8TBrhgAvRg8obzup0=\ngithub.com/mgechev/dots v0.0.0-20210922191527-e955255bf517/go.mod h1:KQ7+USdGKfpPjXk4Ga+5XxQM4Lm4e3gAogrreFAYpOg=\ngithub.com/mgechev/revive v1.0.3 h1:z3FL6IFFN3JKzHYHD8O1ExH9g/4lAGJ5x1+9rPZgsFg=\ngithub.com/mgechev/revive v1.0.3/go.mod h1:POGGZagSo/0frdr7VeAifzS5Uka0d0GPiM35MsTO8nE=\ngithub.com/mgechev/revive v1.3.9 h1:18Y3R4a2USSBF+QZKFQwVkBROUda7uoBlkEuBD+YD1A=\ngithub.com/mgechev/revive v1.3.9/go.mod h1:+uxEIr5UH0TjXWHTno3xh4u7eg6jDpXKzQccA9UGhHU=\ngithub.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=\ngithub.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso=\ngithub.com/miekg/dns v1.1.35/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM=\ngithub.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI=\ngithub.com/miekg/pkcs11 v1.0.2/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs=\ngithub.com/miekg/pkcs11 v1.0.3/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs=\ngithub.com/minio/asm2plan9s v0.0.0-20200509001527-cdd76441f9d8/go.mod h1:mC1jAcsrzbxHt8iiaC+zU4b1ylILSosueou12R++wfY=\ngithub.com/minio/c2goasm v0.0.0-20190812172519-36a3d3bbc4f3/go.mod h1:RagcQ7I8IeTMnF8JTXieKnO4Z6JCsikNEzj0DwauVzE=\ngithub.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=\ngithub.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI=\ngithub.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw=\ngithub.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=\ngithub.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=\ngithub.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=\ngithub.com/mitchellh/go-ps v1.0.0/go.mod h1:J4lOc8z8yJs6vUwklHw2XEIiT4z4C40KtWVN3nvg8Pg=\ngithub.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=\ngithub.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo=\ngithub.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg=\ngithub.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY=\ngithub.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=\ngithub.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=\ngithub.com/mitchellh/mapstructure v1.4.1 h1:CpVNEelQCZBooIPDn+AR3NpivK/TIKU8bDxdASFVQag=\ngithub.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=\ngithub.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=\ngithub.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=\ngithub.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=\ngithub.com/mitchellh/reflectwalk v1.0.1/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=\ngithub.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=\ngithub.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=\ngithub.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=\ngithub.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=\ngithub.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=\ngithub.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8=\ngithub.com/moricho/tparallel v0.2.1 h1:95FytivzT6rYzdJLdtfn6m1bfFJylOJK41+lgv/EHf4=\ngithub.com/moricho/tparallel v0.2.1/go.mod h1:fXEIZxG2vdfl0ZF8b42f5a78EhjjD5mX8qUplsoSU4k=\ngithub.com/moricho/tparallel v0.3.2 h1:odr8aZVFA3NZrNybggMkYO3rgPRcqjeQUlBBFVxKHTI=\ngithub.com/moricho/tparallel v0.3.2/go.mod h1:OQ+K3b4Ln3l2TZveGCywybl68glfLEwFGqvnjok8b+U=\ngithub.com/mozilla/scribe v0.0.0-20180711195314-fb71baf557c1/go.mod h1:FIczTrinKo8VaLxe6PWTPEXRXDIHz2QAwiaBaP5/4a8=\ngithub.com/mozilla/tls-observatory v0.0.0-20201209171846-0547674fceff/go.mod h1:SrKMQvPiws7F7iqYp8/TX+IhxCYhzr6N/1yb8cwHsGk=\ngithub.com/mozilla/tls-observatory v0.0.0-20210209181001-cf43108d6880/go.mod h1:FUqVoUPHSEdDR0MnFM3Dh8AU0pZHLXUD127SAJGER/s=\ngithub.com/mozilla/tls-observatory v0.0.0-20210609171429-7bc42856d2e5/go.mod h1:FUqVoUPHSEdDR0MnFM3Dh8AU0pZHLXUD127SAJGER/s=\ngithub.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=\ngithub.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=\ngithub.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=\ngithub.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=\ngithub.com/mwitkow/go-proto-validators v0.0.0-20180403085117-0950a7990007/go.mod h1:m2XC9Qq0AlmmVksL6FktJCdTYyLk7V3fKyp0sl1yWQo=\ngithub.com/mwitkow/go-proto-validators v0.2.0/go.mod h1:ZfA1hW+UH/2ZHOWvQ3HnQaU0DtnpXu850MZiy+YUgcc=\ngithub.com/nakabonne/nestif v0.3.0 h1:+yOViDGhg8ygGrmII72nV9B/zGxY188TYpfolntsaPw=\ngithub.com/nakabonne/nestif v0.3.0/go.mod h1:dI314BppzXjJ4HsCnbo7XzrJHPszZsjnk5wEBSYHI2c=\ngithub.com/nakabonne/nestif v0.3.1 h1:wm28nZjhQY5HyYPx+weN3Q65k6ilSBxDb8v5S81B81U=\ngithub.com/nakabonne/nestif v0.3.1/go.mod h1:9EtoZochLn5iUprVDmDjqGKPofoUEBL8U4Ngq6aY7OE=\ngithub.com/nats-io/nats.go v1.34.0/go.mod h1:Ubdu4Nh9exXdSz0RVWRFBbRfrbSxOYd26oF0wkWclB8=\ngithub.com/nats-io/nkeys v0.4.7/go.mod h1:kqXRgRDPlGy7nGaEDMuYzmiJCIAAWDK0IMBtDmGD0nc=\ngithub.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c=\ngithub.com/nbutton23/zxcvbn-go v0.0.0-20201221231540-e56b841a3c88/go.mod h1:KSVJerMDfblTH7p5MZaTt+8zaT2iEk3AkVb9PQdZuE8=\ngithub.com/nbutton23/zxcvbn-go v0.0.0-20210217022336-fa2cb2858354 h1:4kuARK6Y6FxaNu/BnU2OAaLF86eTVhP2hjTB6iMvItA=\ngithub.com/nbutton23/zxcvbn-go v0.0.0-20210217022336-fa2cb2858354/go.mod h1:KSVJerMDfblTH7p5MZaTt+8zaT2iEk3AkVb9PQdZuE8=\ngithub.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=\ngithub.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=\ngithub.com/nishanths/exhaustive v0.1.0 h1:kVlMw8h2LHPMGUVqUj6230oQjjTMFjwcZrnkhXzFfl8=\ngithub.com/nishanths/exhaustive v0.1.0/go.mod h1:S1j9110vxV1ECdCudXRkeMnFQ/DQk9ajLT0Uf2MYZQQ=\ngithub.com/nishanths/exhaustive v0.12.0 h1:vIY9sALmw6T/yxiASewa4TQcFsVYZQQRUQJhKRf3Swg=\ngithub.com/nishanths/exhaustive v0.12.0/go.mod h1:mEZ95wPIZW+x8kC4TgC+9YCUgiST7ecevsVDTgc2obs=\ngithub.com/nishanths/predeclared v0.0.0-20190419143655-18a43bb90ffc/go.mod h1:62PewwiQTlm/7Rj+cxVYqZvDIUc+JjZq6GHAC1fsObQ=\ngithub.com/nishanths/predeclared v0.2.1 h1:1TXtjmy4f3YCFjTxRd8zcFHOmoUir+gp0ESzjFzG2sw=\ngithub.com/nishanths/predeclared v0.2.1/go.mod h1:HvkGJcA3naj4lOwnFXFDkFxVtSqQMB9sbB1usJ+xjQE=\ngithub.com/nishanths/predeclared v0.2.2 h1:V2EPdZPliZymNAn79T8RkNApBjMmVKh5XRpLm/w98Vk=\ngithub.com/nishanths/predeclared v0.2.2/go.mod h1:RROzoN6TnGQupbC+lqggsOlcgysk3LMK/HI84Mp280c=\ngithub.com/nunnatsa/ginkgolinter v0.16.2 h1:8iLqHIZvN4fTLDC0Ke9tbSZVcyVHoBs0HIbnVSxfHJk=\ngithub.com/nunnatsa/ginkgolinter v0.16.2/go.mod h1:4tWRinDN1FeJgU+iJANW/kz7xKN5nYRAOfJDQUS9dOQ=\ngithub.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=\ngithub.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=\ngithub.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=\ngithub.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=\ngithub.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=\ngithub.com/olekukonko/tablewriter v0.0.1/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=\ngithub.com/olekukonko/tablewriter v0.0.2/go.mod h1:rSAaSIOAGT9odnlyGlUfAJaoc5w2fSBUmeGDbRWPxyQ=\ngithub.com/olekukonko/tablewriter v0.0.4/go.mod h1:zq6QwlOf5SlnkVbMSr5EoBv3636FWnp+qbPhuoO21uA=\ngithub.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=\ngithub.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=\ngithub.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=\ngithub.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=\ngithub.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=\ngithub.com/onsi/ginkgo v1.14.2/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY=\ngithub.com/onsi/ginkgo v1.15.0 h1:1V1NfVQR87RtWAgp1lv9JZJ5Jap+XFGKPi00andXGi4=\ngithub.com/onsi/ginkgo v1.15.0/go.mod h1:hF8qUzuuC8DJGygJH3726JnCZX4MYbRB8yFfISqnKUg=\ngithub.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc=\ngithub.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0=\ngithub.com/onsi/ginkgo/v2 v2.20.2/go.mod h1:K9gyxPIlb+aIvnZ8bd9Ak+YP18w3APlR+5coaZoE2ag=\ngithub.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=\ngithub.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=\ngithub.com/onsi/gomega v1.10.4/go.mod h1:g/HbgYopi++010VEqkFgJHKC09uJiW9UkXvMUuKHUCQ=\ngithub.com/onsi/gomega v1.10.5 h1:7n6FEkpFmfCoo2t+YYqXH0evK+a9ICQz0xcAy9dYcaQ=\ngithub.com/onsi/gomega v1.10.5/go.mod h1:gza4q3jKQJijlu05nKWRCW/GavJumGt8aNRxWg7mt48=\ngithub.com/onsi/gomega v1.34.2 h1:pNCwDkzrsv7MS9kpaQvVb1aVLahQXyJ/Tv5oAZMI3i8=\ngithub.com/onsi/gomega v1.34.2/go.mod h1:v1xfxRgk0KIsG+QOdm7p8UosrOzPYRo60fd3B/1Dukc=\ngithub.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=\ngithub.com/orisano/pixelmatch v0.0.0-20220722002657-fb0b55479cde/go.mod h1:nZgzbfBr3hhjoZnS66nKrHmduYNpc34ny7RK4z5/HM0=\ngithub.com/otiai10/copy v1.2.0/go.mod h1:rrF5dJ5F0t/EWSYODDu4j9/vEeYHMkc8jt0zJChqQWw=\ngithub.com/otiai10/copy v1.14.0/go.mod h1:ECfuL02W+/FkTWZWgQqXPWZgW9oeKCSQ5qVfSc4qc4w=\ngithub.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE=\ngithub.com/otiai10/curr v1.0.0/go.mod h1:LskTG5wDwr8Rs+nNQ+1LlxRjAtTZZjtJW4rMXl6j4vs=\ngithub.com/otiai10/mint v1.3.0/go.mod h1:F5AjcsTsWUqX+Na9fpHb52P8pcRX2CI6A3ctIT91xUo=\ngithub.com/otiai10/mint v1.3.1/go.mod h1:/yxELlJQ0ufhjUwhshSj+wFjZ78CnZ48/1wtmBH1OTc=\ngithub.com/otiai10/mint v1.5.1/go.mod h1:MJm72SBthJjz8qhefc4z1PYEieWmy8Bku7CjcAqyUSM=\ngithub.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=\ngithub.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=\ngithub.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=\ngithub.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=\ngithub.com/pelletier/go-toml v1.8.1 h1:1Nf83orprkJyknT6h7zbuEGUEjcyVlCxSUGTENmNCRM=\ngithub.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc=\ngithub.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8=\ngithub.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=\ngithub.com/pelletier/go-toml/v2 v2.2.3 h1:YmeHyLY8mFWbdkNWwpr+qIL2bEqT0o95WSdkNHvL12M=\ngithub.com/pelletier/go-toml/v2 v2.2.3/go.mod h1:MfCQTFTvCcUyyvvwm1+G6H/jORL20Xlb6rzQu9GuUkc=\ngithub.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=\ngithub.com/phayes/checkstyle v0.0.0-20170904204023-bfd46e6a821d h1:CdDQnGF8Nq9ocOS/xlSptM1N3BbrA6/kmaep5ggwaIA=\ngithub.com/phayes/checkstyle v0.0.0-20170904204023-bfd46e6a821d/go.mod h1:3OzsM7FXDQlpCiw2j81fOmAwQLnZnLGXVKUzeKQXIAw=\ngithub.com/phpdave11/gofpdf v1.4.2/go.mod h1:zpO6xFn9yxo3YLyMvW8HcKWVdbNqgIfOOp2dXMnm1mY=\ngithub.com/phpdave11/gofpdi v1.0.12/go.mod h1:vBmVV0Do6hSBHC8uKUQ71JGW+ZGQq74llk/7bXwjDoI=\ngithub.com/phpdave11/gofpdi v1.0.13/go.mod h1:vBmVV0Do6hSBHC8uKUQ71JGW+ZGQq74llk/7bXwjDoI=\ngithub.com/pierrec/lz4/v4 v4.1.15/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=\ngithub.com/pierrec/lz4/v4 v4.1.18/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=\ngithub.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=\ngithub.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=\ngithub.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=\ngithub.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=\ngithub.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=\ngithub.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI=\ngithub.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg=\ngithub.com/pkg/sftp v1.13.6/go.mod h1:tz1ryNURKu77RL+GuCzmoJYxQczL3wLNNpPWagdg4Qk=\ngithub.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10/go.mod h1:t/avpk3KcrXxUnYOhZhMXJlSEyie6gQbtLq5NM3loB8=\ngithub.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=\ngithub.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=\ngithub.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=\ngithub.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=\ngithub.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=\ngithub.com/polyfloyd/go-errorlint v0.0.0-20201127212506-19bd8db6546f h1:xAw10KgJqG5NJDfmRqJ05Z0IFblKumjtMeyiOLxj3+4=\ngithub.com/polyfloyd/go-errorlint v0.0.0-20201127212506-19bd8db6546f/go.mod h1:wi9BfjxjF/bwiZ701TzmfKu6UKC357IOAtNr0Td0Lvw=\ngithub.com/polyfloyd/go-errorlint v1.6.0 h1:tftWV9DE7txiFzPpztTAwyoRLKNj9gpVm2cg8/OwcYY=\ngithub.com/polyfloyd/go-errorlint v1.6.0/go.mod h1:HR7u8wuP1kb1NeN1zqTd1ZMlqUKPPHF+Id4vIPvDqVw=\ngithub.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=\ngithub.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s=\ngithub.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=\ngithub.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U=\ngithub.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=\ngithub.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=\ngithub.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=\ngithub.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU=\ngithub.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=\ngithub.com/prometheus/client_golang v1.20.4 h1:Tgh3Yr67PaOv/uTqloMsCEdeuFTatm5zIq5+qNN23vI=\ngithub.com/prometheus/client_golang v1.20.4/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE=\ngithub.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=\ngithub.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=\ngithub.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=\ngithub.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=\ngithub.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w=\ngithub.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=\ngithub.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=\ngithub.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=\ngithub.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=\ngithub.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=\ngithub.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4=\ngithub.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=\ngithub.com/prometheus/common v0.59.1 h1:LXb1quJHWm1P6wq/U824uxYi4Sg0oGvNeUm1z5dJoX0=\ngithub.com/prometheus/common v0.59.1/go.mod h1:GpWM7dewqmVYcd7SmRaiWVe9SSqjf0UrwnYnpEZNuT0=\ngithub.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=\ngithub.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=\ngithub.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=\ngithub.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=\ngithub.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=\ngithub.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc=\ngithub.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=\ngithub.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=\ngithub.com/pseudomuto/protoc-gen-doc v1.3.2/go.mod h1:y5+P6n3iGrbKG+9O04V5ld71in3v/bX88wUwgt+U8EA=\ngithub.com/pseudomuto/protokit v0.2.0/go.mod h1:2PdH30hxVHsup8KpBTOXTBeMVhJZVio3Q8ViKSAXT0Q=\ngithub.com/quasilyte/go-consistent v0.0.0-20190521200055-c6f3937de18c/go.mod h1:5STLWrekHfjyYwxBRVRXNOSewLJ3PWfDJd1VyTS21fI=\ngithub.com/quasilyte/go-ruleguard v0.3.0/go.mod h1:p2miAhLp6fERzFNbcuQ4bevXs8rgK//uCHsUDkumITg=\ngithub.com/quasilyte/go-ruleguard v0.3.1-0.20210203134552-1b5a410e1cc8/go.mod h1:KsAh3x0e7Fkpgs+Q9pNLS5XpFSvYCEVl5gP9Pp1xp30=\ngithub.com/quasilyte/go-ruleguard v0.3.1 h1:2KTXnHBCR4BUl8UAL2bCUorOBGC8RsmYncuDA9NEFW4=\ngithub.com/quasilyte/go-ruleguard v0.3.1/go.mod h1:s41wdpioTcgelE3dlTUgK57UaUxjihg/DBGUccoN5IU=\ngithub.com/quasilyte/go-ruleguard v0.4.3-0.20240823090925-0fe6f58b47b1 h1:+Wl/0aFp0hpuHM3H//KMft64WQ1yX9LdJY64Qm/gFCo=\ngithub.com/quasilyte/go-ruleguard v0.4.3-0.20240823090925-0fe6f58b47b1/go.mod h1:GJLgqsLeo4qgavUoL8JeGFNS7qcisx3awV/w9eWTmNI=\ngithub.com/quasilyte/go-ruleguard/dsl v0.0.0-20210106184943-e47d54850b18/go.mod h1:KeCP03KrjuSO0H1kTuZQCWlQPulDV6YMIXmpQss17rU=\ngithub.com/quasilyte/go-ruleguard/dsl v0.0.0-20210115110123-c73ee1cbff1f/go.mod h1:KeCP03KrjuSO0H1kTuZQCWlQPulDV6YMIXmpQss17rU=\ngithub.com/quasilyte/go-ruleguard/dsl v0.3.0/go.mod h1:KeCP03KrjuSO0H1kTuZQCWlQPulDV6YMIXmpQss17rU=\ngithub.com/quasilyte/go-ruleguard/dsl v0.3.1/go.mod h1:KeCP03KrjuSO0H1kTuZQCWlQPulDV6YMIXmpQss17rU=\ngithub.com/quasilyte/go-ruleguard/dsl v0.3.22 h1:wd8zkOhSNr+I+8Qeciml08ivDt1pSXe60+5DqOpCjPE=\ngithub.com/quasilyte/go-ruleguard/dsl v0.3.22/go.mod h1:KeCP03KrjuSO0H1kTuZQCWlQPulDV6YMIXmpQss17rU=\ngithub.com/quasilyte/go-ruleguard/rules v0.0.0-20201231183845-9e62ed36efe1/go.mod h1:7JTjp89EGyU1d6XfBiXihJNG37wB2VRkd125Q1u7Plc=\ngithub.com/quasilyte/go-ruleguard/rules v0.0.0-20210203162857-b223e0831f88/go.mod h1:4cgAphtvu7Ftv7vOT2ZOYhC6CvBxZixcasr8qIOTA50=\ngithub.com/quasilyte/go-ruleguard/rules v0.0.0-20211022131956-028d6511ab71/go.mod h1:4cgAphtvu7Ftv7vOT2ZOYhC6CvBxZixcasr8qIOTA50=\ngithub.com/quasilyte/gogrep v0.5.0 h1:eTKODPXbI8ffJMN+W2aE0+oL0z/nh8/5eNdiO34SOAo=\ngithub.com/quasilyte/gogrep v0.5.0/go.mod h1:Cm9lpz9NZjEoL1tgZ2OgeUKPIxL1meE7eo60Z6Sk+Ng=\ngithub.com/quasilyte/regex/syntax v0.0.0-20200407221936-30656e2c4a95/go.mod h1:rlzQ04UMyJXu/aOvhd8qT+hvDrFpiwqp8MRXDY9szc0=\ngithub.com/quasilyte/regex/syntax v0.0.0-20200805063351-8f842688393c h1:+gtJ/Pwj2dgUGlZgTrNFqajGYKZQc7Piqus/S6DK9CE=\ngithub.com/quasilyte/regex/syntax v0.0.0-20200805063351-8f842688393c/go.mod h1:rlzQ04UMyJXu/aOvhd8qT+hvDrFpiwqp8MRXDY9szc0=\ngithub.com/quasilyte/regex/syntax v0.0.0-20210819130434-b3f0c404a727 h1:TCg2WBOl980XxGFEZSS6KlBGIV0diGdySzxATTWoqaU=\ngithub.com/quasilyte/regex/syntax v0.0.0-20210819130434-b3f0c404a727/go.mod h1:rlzQ04UMyJXu/aOvhd8qT+hvDrFpiwqp8MRXDY9szc0=\ngithub.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567 h1:M8mH9eK4OUR4lu7Gd+PU1fV2/qnDNfzT635KRSObncs=\ngithub.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567/go.mod h1:DWNGW8A4Y+GyBgPuaQJuWiy0XYftx4Xm/y5Jqk9I6VQ=\ngithub.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=\ngithub.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=\ngithub.com/remyoudompheng/go-dbus v0.0.0-20121104212943-b7232d34b1d5/go.mod h1:+u151txRmLpwxBmpYn9z3d1sdJdjRPQpsXuYeY9jNls=\ngithub.com/remyoudompheng/go-liblzma v0.0.0-20190506200333-81bf2d431b96/go.mod h1:90HvCY7+oHHUKkbeMCiHt1WuFR2/hPJ9QrljDG+v6ls=\ngithub.com/remyoudompheng/go-misc v0.0.0-20190427085024-2d6ac652a50e/go.mod h1:80FQABjoFzZ2M5uEa6FUaJYEmqU2UOKojlFVak1UAwI=\ngithub.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=\ngithub.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=\ngithub.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=\ngithub.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=\ngithub.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=\ngithub.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=\ngithub.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=\ngithub.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=\ngithub.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=\ngithub.com/rogpeppe/go-internal v1.6.2/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=\ngithub.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=\ngithub.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4=\ngithub.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=\ngithub.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=\ngithub.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=\ngithub.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=\ngithub.com/ruudk/golang-pdf417 v0.0.0-20181029194003-1af4ab5afa58/go.mod h1:6lfFZQK844Gfx8o5WFuvpxWRwnSoipWe/p622j1v06w=\ngithub.com/ruudk/golang-pdf417 v0.0.0-20201230142125-a7e3863a1245/go.mod h1:pQAZKsJ8yyVxGRWYNEm9oFB8ieLgKFnamEyDmSA0BRk=\ngithub.com/ryancurrah/gomodguard v1.2.0 h1:YWfhGOrXwLGiqcC/u5EqG6YeS8nh+1fw0HEc85CVZro=\ngithub.com/ryancurrah/gomodguard v1.2.0/go.mod h1:rNqbC4TOIdUDcVMSIpNNAzTbzXAZa6W5lnUepvuMMgQ=\ngithub.com/ryancurrah/gomodguard v1.3.5 h1:cShyguSwUEeC0jS7ylOiG/idnd1TpJ1LfHGpV3oJmPU=\ngithub.com/ryancurrah/gomodguard v1.3.5/go.mod h1:MXlEPQRxgfPQa62O8wzK3Ozbkv9Rkqr+wKjSxTdsNJE=\ngithub.com/ryanrolds/sqlclosecheck v0.3.0 h1:AZx+Bixh8zdUBxUA1NxbxVAS78vTPq4rCb8OUZI9xFw=\ngithub.com/ryanrolds/sqlclosecheck v0.3.0/go.mod h1:1gREqxyTGR3lVtpngyFo3hZAgk0KCtEdgEkHwDbigdA=\ngithub.com/ryanrolds/sqlclosecheck v0.5.1 h1:dibWW826u0P8jNLsLN+En7+RqWWTYrjCB9fJfSfdyCU=\ngithub.com/ryanrolds/sqlclosecheck v0.5.1/go.mod h1:2g3dUjoS6AL4huFdv6wn55WpLIDjY7ZgUR4J8HOO/XQ=\ngithub.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=\ngithub.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=\ngithub.com/sagikazarmark/crypt v0.19.0/go.mod h1:c6vimRziqqERhtSe0MhIvzE1w54FrCHtrXb5NH/ja78=\ngithub.com/sagikazarmark/locafero v0.6.0 h1:ON7AQg37yzcRPU69mt7gwhFEBwxI6P9T4Qu3N51bwOk=\ngithub.com/sagikazarmark/locafero v0.6.0/go.mod h1:77OmuIc6VTraTXKXIs/uvUxKGUXjE1GbemJYHqdNjX0=\ngithub.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE=\ngithub.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ=\ngithub.com/sanposhiho/wastedassign v0.1.3/go.mod h1:LGpq5Hsv74QaqM47WtIsRSF/ik9kqk07kchgv66tLVE=\ngithub.com/sanposhiho/wastedassign v0.2.0 h1:0vycy8D/Ky55U5ub8oJFqyDv9M4ICM/wte9sAp2/7Mc=\ngithub.com/sanposhiho/wastedassign v0.2.0/go.mod h1:LGpq5Hsv74QaqM47WtIsRSF/ik9kqk07kchgv66tLVE=\ngithub.com/sanposhiho/wastedassign v1.0.0 h1:dB+7OV0iJ5b0SpGwKjKlPCr8GDZJX6Ylm3YG+66xGpc=\ngithub.com/sanposhiho/wastedassign v1.0.0/go.mod h1:LGpq5Hsv74QaqM47WtIsRSF/ik9kqk07kchgv66tLVE=\ngithub.com/sanposhiho/wastedassign/v2 v2.0.7 h1:J+6nrY4VW+gC9xFzUc+XjPD3g3wF3je/NsJFwFK7Uxc=\ngithub.com/sanposhiho/wastedassign/v2 v2.0.7/go.mod h1:KyZ0MWTwxxBmfwn33zh3k1dmsbF2ud9pAAGfoLfjhtI=\ngithub.com/santhosh-tekuri/jsonschema/v5 v5.3.1 h1:lZUw3E0/J3roVtGQ+SCrUrg3ON6NgVqpn3+iol9aGu4=\ngithub.com/santhosh-tekuri/jsonschema/v5 v5.3.1/go.mod h1:uToXkOrWAZ6/Oc07xWQrPOhJotwFIyu2bBVN41fcDUY=\ngithub.com/sashamelentyev/interfacebloat v1.1.0 h1:xdRdJp0irL086OyW1H/RTZTr1h/tMEOsumirXcOJqAw=\ngithub.com/sashamelentyev/interfacebloat v1.1.0/go.mod h1:+Y9yU5YdTkrNvoX0xHc84dxiN1iBi9+G8zZIhPVoNjQ=\ngithub.com/sashamelentyev/usestdlibvars v1.27.0 h1:t/3jZpSXtRPRf2xr0m63i32ZrusyurIGT9E5wAvXQnI=\ngithub.com/sashamelentyev/usestdlibvars v1.27.0/go.mod h1:9nl0jgOfHKWNFS43Ojw0i7aRoS4j6EBye3YBhmAIRF8=\ngithub.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=\ngithub.com/securego/gosec/v2 v2.6.1/go.mod h1:I76p3NTHBXsGhybUW+cEQ692q2Vp+A0Z6ZLzDIZy+Ao=\ngithub.com/securego/gosec/v2 v2.7.0 h1:mOhJv5w6UyNLpSssQOQCc7eGkKLuicAxvf66Ey/X4xk=\ngithub.com/securego/gosec/v2 v2.7.0/go.mod h1:xNbGArrGUspJLuz3LS5XCY1EBW/0vABAl/LWfSklmiM=\ngithub.com/securego/gosec/v2 v2.21.3 h1:EZJttSs3Kw57Ap6EwMBjmFql8ARsIsWYP2pd+FNAoCg=\ngithub.com/securego/gosec/v2 v2.21.3/go.mod h1:xSEd+rXbCjjinAofXTWh3Z7hkpBJdUwKTt2as7tKOF0=\ngithub.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=\ngithub.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c h1:W65qqJCIOVP4jpqPQ0YvHYKwcMEMVWIzWC5iNQQfBTU=\ngithub.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c/go.mod h1:/PevMnwAxekIXwN8qQyfc5gl2NlkB3CQlkizAbOkeBs=\ngithub.com/shirou/gopsutil/v3 v3.21.1/go.mod h1:igHnfak0qnw1biGeI2qKQvu0ZkwvEkUcCLlYhZzdr/4=\ngithub.com/shirou/gopsutil/v3 v3.24.5/go.mod h1:bsoOS1aStSs9ErQ1WWfxllSeS1K5D+U30r2NfcubMVk=\ngithub.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ=\ngithub.com/shoenig/test v0.6.4/go.mod h1:byHiCGXqrVaflBLAMq/srcZIHynQPQgeyvkvXnjqq0k=\ngithub.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk=\ngithub.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ=\ngithub.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=\ngithub.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=\ngithub.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=\ngithub.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=\ngithub.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=\ngithub.com/sirupsen/logrus v1.8.0 h1:nfhvjKcUMhBMVqbKHJlk5RPrrfYr/NMo3692g0dwfWU=\ngithub.com/sirupsen/logrus v1.8.0/go.mod h1:4GuYW9TZmE769R5STWrRakJc4UqQ3+QQ95fyz7ENv1A=\ngithub.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=\ngithub.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=\ngithub.com/sivchari/containedctx v1.0.3 h1:x+etemjbsh2fB5ewm5FeLNi5bUjK0V8n0RB+Wwfd0XE=\ngithub.com/sivchari/containedctx v1.0.3/go.mod h1:c1RDvCbnJLtH4lLcYD/GqwiBSSf4F5Qk0xld2rBqzJ4=\ngithub.com/sivchari/tenv v1.10.0 h1:g/hzMA+dBCKqGXgW8AV/1xIWhAvDrx0zFKNR48NFMg0=\ngithub.com/sivchari/tenv v1.10.0/go.mod h1:tdY24masnVoZFxYrHv/nD6Tc8FbkEtAQEEziXpyMgqY=\ngithub.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=\ngithub.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=\ngithub.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s=\ngithub.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=\ngithub.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=\ngithub.com/sonatard/noctx v0.0.1 h1:VC1Qhl6Oxx9vvWo3UDgrGXYCeKCe3Wbw7qAWL6FrmTY=\ngithub.com/sonatard/noctx v0.0.1/go.mod h1:9D2D/EoULe8Yy2joDHJj7bv3sZoq9AaSb8B4lqBjiZI=\ngithub.com/sonatard/noctx v0.1.0 h1:JjqOc2WN16ISWAjAk8M5ej0RfExEXtkEyExl2hLW+OM=\ngithub.com/sonatard/noctx v0.1.0/go.mod h1:0RvBxqY8D4j9cTTTWE8ylt2vqj2EPI8fHmrxHdsaZ2c=\ngithub.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo=\ngithub.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0=\ngithub.com/sourcegraph/go-diff v0.6.1 h1:hmA1LzxW0n1c3Q4YbrFgg4P99GSnebYa3x8gr0HZqLQ=\ngithub.com/sourcegraph/go-diff v0.6.1/go.mod h1:iBszgVvyxdc8SFZ7gm69go2KDdt3ag071iBaWPF6cjs=\ngithub.com/sourcegraph/go-diff v0.7.0 h1:9uLlrd5T46OXs5qpp8L/MTltk0zikUGi0sNNyCpA8G0=\ngithub.com/sourcegraph/go-diff v0.7.0/go.mod h1:iBszgVvyxdc8SFZ7gm69go2KDdt3ag071iBaWPF6cjs=\ngithub.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=\ngithub.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=\ngithub.com/spf13/afero v1.3.3/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4=\ngithub.com/spf13/afero v1.5.1 h1:VHu76Lk0LSP1x254maIu2bplkWpfBWI+B+6fdoZprcg=\ngithub.com/spf13/afero v1.5.1/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I=\ngithub.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I=\ngithub.com/spf13/afero v1.9.2/go.mod h1:iUV7ddyEEZPO5gA3zD4fJt6iStLlL+Lg4m2cihcDf8Y=\ngithub.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8=\ngithub.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY=\ngithub.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=\ngithub.com/spf13/cast v1.3.1 h1:nFm6S0SMdyzrzcmThSipiEubIDy8WEXKNZ0UOgiRpng=\ngithub.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=\ngithub.com/spf13/cast v1.7.0 h1:ntdiHjuueXFgm5nzDRdOS4yfT43P5Fnud6DH50rz/7w=\ngithub.com/spf13/cast v1.7.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo=\ngithub.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=\ngithub.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=\ngithub.com/spf13/cobra v1.1.3 h1:xghbfqPkxzxP3C/f3n5DdpAbdKLj4ZE4BWQI362l53M=\ngithub.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSWzOo=\ngithub.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM=\ngithub.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y=\ngithub.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=\ngithub.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk=\ngithub.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=\ngithub.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=\ngithub.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=\ngithub.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=\ngithub.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=\ngithub.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=\ngithub.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg=\ngithub.com/spf13/viper v1.7.1 h1:pM5oEahlgWv/WnHXpgbKz7iLIxRf65tye2Ci+XFK5sk=\ngithub.com/spf13/viper v1.7.1/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg=\ngithub.com/spf13/viper v1.19.0 h1:RWq5SEjt8o25SROyN3z2OrDB9l7RPd3lwTWU8EcEdcI=\ngithub.com/spf13/viper v1.19.0/go.mod h1:GQUN9bilAbhU/jgc1bKs99f/suXKeUMct8Adx5+Ntkg=\ngithub.com/ssgreg/nlreturn/v2 v2.1.0 h1:6/s4Rc49L6Uo6RLjhWZGBpWWjfzk2yrf1nIW8m4wgVA=\ngithub.com/ssgreg/nlreturn/v2 v2.1.0/go.mod h1:E/iiPB78hV7Szg2YfRgyIrk1AD6JVMTRkkxBiELzh2I=\ngithub.com/ssgreg/nlreturn/v2 v2.2.1 h1:X4XDI7jstt3ySqGU86YGAURbxw3oTDPK9sPEi6YEwQ0=\ngithub.com/ssgreg/nlreturn/v2 v2.2.1/go.mod h1:E/iiPB78hV7Szg2YfRgyIrk1AD6JVMTRkkxBiELzh2I=\ngithub.com/stbenjam/no-sprintf-host-port v0.1.1 h1:tYugd/yrm1O0dV+ThCbaKZh195Dfm07ysF0U6JQXczc=\ngithub.com/stbenjam/no-sprintf-host-port v0.1.1/go.mod h1:TLhvtIvONRzdmkFiio4O8LHsN9N74I+PhRquPsxpL0I=\ngithub.com/stoewer/go-strcase v1.3.0/go.mod h1:fAH5hQ5pehh+j3nZfvwdk2RgEgQjAoM8wodgtPmh1xo=\ngithub.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=\ngithub.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=\ngithub.com/stretchr/objx v0.3.0 h1:NGXK3lHquSN08v5vWalVI/L8XU9hdzE/G6xsrze47As=\ngithub.com/stretchr/objx v0.3.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=\ngithub.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=\ngithub.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=\ngithub.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=\ngithub.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=\ngithub.com/stretchr/testify v0.0.0-20170130113145-4d4bfba8f1d1/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=\ngithub.com/stretchr/testify v1.1.4/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=\ngithub.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=\ngithub.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=\ngithub.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=\ngithub.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=\ngithub.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=\ngithub.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=\ngithub.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=\ngithub.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=\ngithub.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals=\ngithub.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=\ngithub.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=\ngithub.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=\ngithub.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=\ngithub.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=\ngithub.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=\ngithub.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s=\ngithub.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=\ngithub.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8=\ngithub.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU=\ngithub.com/substrait-io/substrait-go v0.4.2/go.mod h1:qhpnLmrcvAnlZsUyPXZRqldiHapPTXC3t7xFgDi3aQg=\ngithub.com/tdakkota/asciicheck v0.0.0-20200416200610-e657995f937b h1:HxLVTlqcHhFAz3nWUcuvpH7WuOMv8LQoCWmruLfFH2U=\ngithub.com/tdakkota/asciicheck v0.0.0-20200416200610-e657995f937b/go.mod h1:yHp0ai0Z9gUljN3o0xMhYJnH/IcvkdTBOX2fmJ93JEM=\ngithub.com/tdakkota/asciicheck v0.2.0 h1:o8jvnUANo0qXtnslk2d3nMKTFNlOnJjRrNcj0j9qkHM=\ngithub.com/tdakkota/asciicheck v0.2.0/go.mod h1:Qb7Y9EgjCLJGup51gDHFzbI08/gbGhL/UVhYIPWG2rg=\ngithub.com/tenntenn/modver v1.0.1/go.mod h1:bePIyQPb7UeioSRkw3Q0XeMhYZSMx9B8ePqg6SAMGH0=\ngithub.com/tenntenn/text/transform v0.0.0-20200319021203-7eef512accb3/go.mod h1:ON8b8w4BN/kE1EOhwT0o+d62W65a6aPw1nouo9LMgyY=\ngithub.com/tetafro/godot v1.4.4 h1:VAtLEoAMmopIzHVWVBrztjVWDeYm1OD/DKqhqXR4828=\ngithub.com/tetafro/godot v1.4.4/go.mod h1:FVDd4JuKliW3UgjswZfJfHq4vAx0bD/Jd5brJjGeaz4=\ngithub.com/tetafro/godot v1.4.18 h1:ouX3XGiziKDypbpXqShBfnNLTSjR8r3/HVzrtJ+bHlI=\ngithub.com/tetafro/godot v1.4.18/go.mod h1:2oVxTBSftRTh4+MVfUaUXR6bn2GDXCaMcOG4Dk3rfio=\ngithub.com/tidwall/gjson v1.14.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=\ngithub.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=\ngithub.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=\ngithub.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28=\ngithub.com/timakin/bodyclose v0.0.0-20200424151742-cb6215831a94 h1:ig99OeTyDwQWhPe2iw9lwfQVF1KB3Q4fpP3X7/2VBG8=\ngithub.com/timakin/bodyclose v0.0.0-20200424151742-cb6215831a94/go.mod h1:Qimiffbc6q9tBWlVV6x0P9sat/ao1xEkREYPPj9hphk=\ngithub.com/timakin/bodyclose v0.0.0-20240125160201-f835fa56326a h1:A6uKudFIfAEpoPdaal3aSqGxBzLyU8TqyXImLwo6dIo=\ngithub.com/timakin/bodyclose v0.0.0-20240125160201-f835fa56326a/go.mod h1:mkjARE7Yr8qU23YcGMSALbIxTQ9r9QBVahQOBRfU460=\ngithub.com/timonwong/loggercheck v0.9.4 h1:HKKhqrjcVj8sxL7K77beXh0adEm6DLjV/QOGeMXEVi4=\ngithub.com/timonwong/loggercheck v0.9.4/go.mod h1:caz4zlPcgvpEkXgVnAJGowHAMW2NwHaNlpS8xDbVhTg=\ngithub.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI=\ngithub.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY=\ngithub.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=\ngithub.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=\ngithub.com/tmc/grpc-websocket-proxy v0.0.0-20200427203606-3cfed13b9966/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=\ngithub.com/tomarrell/wrapcheck v0.0.0-20201130113247-1683564d9756 h1:zV5mu0ESwb+WnzqVaW2z1DdbAP0S46UtjY8DHQupQP4=\ngithub.com/tomarrell/wrapcheck v0.0.0-20201130113247-1683564d9756/go.mod h1:yiFB6fFoV7saXirUGfuK+cPtUh4NX/Hf5y2WC2lehu0=\ngithub.com/tomarrell/wrapcheck v1.2.0 h1:N1PWGT8l+6jZVTcm00kGjx9IEA8oDMSjipqY73ye5c0=\ngithub.com/tomarrell/wrapcheck v1.2.0/go.mod h1:Bd3i1FaEKe3XmcPoHhNQ+HM0S8P6eIXoQIoGj/ndJkU=\ngithub.com/tomarrell/wrapcheck/v2 v2.9.0 h1:801U2YCAjLhdN8zhZ/7tdjB3EnAoRlJHt/s+9hijLQ4=\ngithub.com/tomarrell/wrapcheck/v2 v2.9.0/go.mod h1:g9vNIyhb5/9TQgumxQyOEqDHsmGYcGsVMOx/xGkqdMo=\ngithub.com/tomasen/realip v0.0.0-20180522021738-f0c99a92ddce/go.mod h1:o8v6yHRoik09Xen7gje4m9ERNah1d1PPsVq1VEx9vE4=\ngithub.com/tommy-muehle/go-mnd/v2 v2.3.1 h1:a1S4+4HSXDJMgeODJH/t0EEKxcVla6Tasw+Zx9JJMog=\ngithub.com/tommy-muehle/go-mnd/v2 v2.3.1/go.mod h1:WsUAkMJMYww6l/ufffCD3m+P7LEvr8TnZn9lwVDlgzw=\ngithub.com/tommy-muehle/go-mnd/v2 v2.5.1 h1:NowYhSdyE/1zwK9QCLeRb6USWdoif80Ie+v+yU8u1Zw=\ngithub.com/tommy-muehle/go-mnd/v2 v2.5.1/go.mod h1:WsUAkMJMYww6l/ufffCD3m+P7LEvr8TnZn9lwVDlgzw=\ngithub.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM=\ngithub.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=\ngithub.com/ultraware/funlen v0.0.3 h1:5ylVWm8wsNwH5aWo9438pwvsK0QiqVuUrt9bn7S/iLA=\ngithub.com/ultraware/funlen v0.0.3/go.mod h1:Dp4UiAus7Wdb9KUZsYWZEWiRzGuM2kXM1lPbfaF6xhA=\ngithub.com/ultraware/funlen v0.1.0 h1:BuqclbkY6pO+cvxoq7OsktIXZpgBSkYTQtmwhAK81vI=\ngithub.com/ultraware/funlen v0.1.0/go.mod h1:XJqmOQja6DpxarLj6Jj1U7JuoS8PvL4nEqDaQhy22p4=\ngithub.com/ultraware/whitespace v0.0.4 h1:If7Va4cM03mpgrNH9k49/VOicWpGoG70XPBFFODYDsg=\ngithub.com/ultraware/whitespace v0.0.4/go.mod h1:aVMh/gQve5Maj9hQ/hg+F75lr/X5A89uZnzAmWSineA=\ngithub.com/ultraware/whitespace v0.1.1 h1:bTPOGejYFulW3PkcrqkeQwOd6NKOOXvmGD9bo/Gk8VQ=\ngithub.com/ultraware/whitespace v0.1.1/go.mod h1:XcP1RLD81eV4BW8UhQlpaR+SDc2givTvyI8a586WjW8=\ngithub.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=\ngithub.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=\ngithub.com/uudashr/gocognit v1.0.1 h1:MoG2fZ0b/Eo7NXoIwCVFLG5JED3qgQz5/NEE+rOsjPs=\ngithub.com/uudashr/gocognit v1.0.1/go.mod h1:j44Ayx2KW4+oB6SWMv8KsmHzZrOInQav7D3cQMJ5JUM=\ngithub.com/uudashr/gocognit v1.1.3 h1:l+a111VcDbKfynh+airAy/DJQKaXh2m9vkoysMPSZyM=\ngithub.com/uudashr/gocognit v1.1.3/go.mod h1:aKH8/e8xbTRBwjbCkwZ8qt4l2EpKXl31KMHgSS+lZ2U=\ngithub.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=\ngithub.com/valyala/fasthttp v1.16.0/go.mod h1:YOKImeEosDdBPnxc0gy7INqi3m1zK6A+xl6TwOBhHCA=\ngithub.com/valyala/fasthttp v1.55.0/go.mod h1:NkY9JtkrpPKmgwV3HTaS2HWaJss9RSIsRVfcxxoHiOM=\ngithub.com/valyala/quicktemplate v1.6.3/go.mod h1:fwPzK2fHuYEODzJ9pkw0ipCPNHZ2tD5KW4lOuSdPKzY=\ngithub.com/valyala/quicktemplate v1.8.0/go.mod h1:qIqW8/igXt8fdrUln5kOSb+KWMaJ4Y8QUsfd1k6L2jM=\ngithub.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio=\ngithub.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc=\ngithub.com/viki-org/dnscache v0.0.0-20130720023526-c70c1f23c5d8/go.mod h1:dniwbG03GafCjFohMDmz6Zc6oCuiqgH6tGNyXTkHzXE=\ngithub.com/wadey/gocovmerge v0.0.0-20160331181800-b5bfa59ec0ad h1:W0LEBv82YCGEtcmPA3uNZBI33/qF//HAAs3MawDjRa0=\ngithub.com/wadey/gocovmerge v0.0.0-20160331181800-b5bfa59ec0ad/go.mod h1:Hy8o65+MXnS6EwGElrSRjUzQDLXreJlzYLlWiHtt8hM=\ngithub.com/xen0n/gosmopolitan v1.2.2 h1:/p2KTnMzwRexIW8GlKawsTWOxn7UHA+jCMF/V8HHtvU=\ngithub.com/xen0n/gosmopolitan v1.2.2/go.mod h1:7XX7Mj61uLYrj0qmeN0zi7XDon9JRAEhYQqAPLVNTeg=\ngithub.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=\ngithub.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778/go.mod h1:2MuV+tbUrU1zIOPMxZ5EncGwgmMJsa+9ucAQZXxsObs=\ngithub.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=\ngithub.com/yagipy/maintidx v1.0.0 h1:h5NvIsCz+nRDapQ0exNv4aJ0yXSI0420omVANTv3GJM=\ngithub.com/yagipy/maintidx v1.0.0/go.mod h1:0qNf/I/CCZXSMhsRsrEPDZ+DkekpKLXAJfsTACwgXLk=\ngithub.com/yeya24/promlinter v0.3.0 h1:JVDbMp08lVCP7Y6NP3qHroGAO6z2yGKQtS5JsjqtoFs=\ngithub.com/yeya24/promlinter v0.3.0/go.mod h1:cDfJQQYv9uYciW60QT0eeHlFodotkYZlL+YcPQN+mW4=\ngithub.com/ykadowak/zerologlint v0.1.5 h1:Gy/fMz1dFQN9JZTPjv1hxEk+sRWm05row04Yoolgdiw=\ngithub.com/ykadowak/zerologlint v0.1.5/go.mod h1:KaUskqF3e/v59oPmdq1U1DnKcuHokl2/K1U4pmIELKg=\ngithub.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg=\ngithub.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM=\ngithub.com/yudai/pp v2.0.1+incompatible/go.mod h1:PuxR/8QJ7cyCkFp/aUDS+JY727OFEZkTdatxwunjIkc=\ngithub.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=\ngithub.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=\ngithub.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=\ngithub.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=\ngithub.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=\ngithub.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=\ngithub.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=\ngithub.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=\ngithub.com/zeebo/assert v1.3.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0=\ngithub.com/zeebo/xxh3 v1.0.2/go.mod h1:5NWz9Sef7zIDm2JHfFlcQvNekmcEl9ekUZQQKCYaDcA=\ngitlab.com/bosi/decorder v0.4.2 h1:qbQaV3zgwnBZ4zPMhGLW4KZe7A7NwxEhJx39R3shffo=\ngitlab.com/bosi/decorder v0.4.2/go.mod h1:muuhHoaJkA9QLcYHq4Mj8FJUwDZ+EirSHRiaTcTf6T8=\ngo-simpler.org/assert v0.9.0/go.mod h1:74Eqh5eI6vCK6Y5l3PI8ZYFXG4Sa+tkr70OIPJAUr28=\ngo-simpler.org/musttag v0.12.2 h1:J7lRc2ysXOq7eM8rwaTYnNrHd5JwjppzB6mScysB2Cs=\ngo-simpler.org/musttag v0.12.2/go.mod h1:uN1DVIasMTQKk6XSik7yrJoEysGtR2GRqvWnI9S7TYM=\ngo-simpler.org/sloglint v0.7.2 h1:Wc9Em/Zeuu7JYpl+oKoYOsQSy2X560aVueCW/m6IijY=\ngo-simpler.org/sloglint v0.7.2/go.mod h1:US+9C80ppl7VsThQclkM7BkCHQAzuz8kHLsW3ppuluo=\ngo.einride.tech/aip v0.67.1/go.mod h1:ZGX4/zKw8dcgzdLsrvpOOGxfxI2QSk12SlP7d6c0/XI=\ngo.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=\ngo.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=\ngo.etcd.io/bbolt v1.3.4/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ=\ngo.etcd.io/etcd v0.0.0-20200513171258-e048e166ab9c/go.mod h1:xCI7ZzBfRuGgBXyXO6yfWfDmlWd35khcWpUa4L0xI/k=\ngo.etcd.io/etcd/api/v3 v3.5.12/go.mod h1:Ot+o0SWSyT6uHhA56al1oCED0JImsRiU9Dc26+C2a+4=\ngo.etcd.io/etcd/client/pkg/v3 v3.5.12/go.mod h1:seTzl2d9APP8R5Y2hFL3NVlD6qC/dOT+3kvrqPyTas4=\ngo.etcd.io/etcd/client/v2 v2.305.12/go.mod h1:aQ/yhsxMu+Oht1FOupSr60oBvcS9cKXHrzBpDsPTf9E=\ngo.etcd.io/etcd/client/v3 v3.5.12/go.mod h1:tSbBCakoWmmddL+BKVAJHa9km+O/E+bumDe9mSbPiqw=\ngo.mozilla.org/mozlog v0.0.0-20170222151521-4bb13139d403/go.mod h1:jHoPAGnDrCy6kaI2tAze5Prf0Nr0w/oNkROt2lw3n3o=\ngo.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=\ngo.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=\ngo.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=\ngo.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=\ngo.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=\ngo.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk=\ngo.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E=\ngo.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=\ngo.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.54.0/go.mod h1:B9yO6b04uB80CzjedvewuqDhxJxi11s7/GtiGa8bAjI=\ngo.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0/go.mod h1:L7UH0GbB0p47T4Rri3uHjbpCFYrVrwc1I25QhNPiGK8=\ngo.opentelemetry.io/otel v1.29.0/go.mod h1:N/WtXPs1CNCUEx+Agz5uouwCba+i+bJGFicT8SR4NP8=\ngo.opentelemetry.io/otel/metric v1.29.0/go.mod h1:auu/QWieFVWx+DmQOUMgj0F8LHWdgalxXqvp7BII/W8=\ngo.opentelemetry.io/otel/sdk v1.29.0/go.mod h1:pM8Dx5WKnvxLCb+8lG1PRNIDxu9g9b9g59Qr7hfAAok=\ngo.opentelemetry.io/otel/sdk/metric v1.29.0/go.mod h1:6zZLdCl2fkauYoZIOn/soQIDSWFmNSRcICarHfuhNJQ=\ngo.opentelemetry.io/otel/trace v1.29.0/go.mod h1:eHl3w0sp3paPkYstJOmAimxhiFXPg+MMTlEh3nsQgWQ=\ngo.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=\ngo.opentelemetry.io/proto/otlp v0.15.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U=\ngo.opentelemetry.io/proto/otlp v0.19.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U=\ngo.opentelemetry.io/proto/otlp v1.0.0/go.mod h1:Sy6pihPLfYHkr3NkUbEhGHFhINUSI/v80hjKIs5JXpM=\ngo.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=\ngo.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=\ngo.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=\ngo.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE=\ngo.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=\ngo.uber.org/automaxprocs v1.5.3 h1:kWazyxZUrS3Gs4qUpbwo5kEIMGe/DAvi5Z4tl2NW4j8=\ngo.uber.org/automaxprocs v1.5.3/go.mod h1:eRbA25aqJrxAbsLO0xy5jVwPt7FQnRgjW+efnwa1WM0=\ngo.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=\ngo.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=\ngo.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=\ngo.uber.org/multierr v1.4.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=\ngo.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=\ngo.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=\ngo.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=\ngo.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=\ngo.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM=\ngo.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=\ngo.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=\ngolang.org/x/crypto v0.0.0-20180501155221-613d6eafa307/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=\ngolang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=\ngolang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=\ngolang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=\ngolang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=\ngolang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=\ngolang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=\ngolang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=\ngolang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY=\ngolang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=\ngolang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=\ngolang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=\ngolang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=\ngolang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=\ngolang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=\ngolang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=\ngolang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw=\ngolang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=\ngolang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=\ngolang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70=\ngolang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=\ngolang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=\ngolang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=\ngolang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=\ngolang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=\ngolang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=\ngolang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=\ngolang.org/x/exp v0.0.0-20191002040644-a1355ae1e2c3/go.mod h1:NOZ3BPKG0ec/BKJQgnvsSFpcKLM5xXVWnvZS97DWHgE=\ngolang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=\ngolang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=\ngolang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=\ngolang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=\ngolang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=\ngolang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=\ngolang.org/x/exp v0.0.0-20200331195152-e8c3332aa8e5/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw=\ngolang.org/x/exp v0.0.0-20220827204233-334a2380cb91/go.mod h1:cyybsKvd6eL0RnXn6p/Grxp8F5bW7iYuBgsNCOHpMYE=\ngolang.org/x/exp v0.0.0-20240909161429-701f63a606c0 h1:e66Fs6Z+fZTbFBAxKfP3PALWBtpfqks2bwGcexMxgtk=\ngolang.org/x/exp v0.0.0-20240909161429-701f63a606c0/go.mod h1:2TbTHSBQa924w8M6Xs1QcRcFwyucIwBGpK1p2f1YFFY=\ngolang.org/x/exp/typeparams v0.0.0-20220428152302-39d4317da171/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk=\ngolang.org/x/exp/typeparams v0.0.0-20230203172020-98cc5a0785f9/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk=\ngolang.org/x/exp/typeparams v0.0.0-20240909161429-701f63a606c0 h1:bVwtbF629Xlyxk6xLQq2TDYmqP0uiWaet5LwRebuY0k=\ngolang.org/x/exp/typeparams v0.0.0-20240909161429-701f63a606c0/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk=\ngolang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs=\ngolang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=\ngolang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=\ngolang.org/x/image v0.0.0-20190910094157-69e4b8554b2a/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=\ngolang.org/x/image v0.0.0-20200119044424-58c23975cae1/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=\ngolang.org/x/image v0.0.0-20200430140353-33d19683fad8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=\ngolang.org/x/image v0.0.0-20200618115811-c13761719519/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=\ngolang.org/x/image v0.0.0-20201208152932-35266b937fa6/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=\ngolang.org/x/image v0.0.0-20210216034530-4410531fe030/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=\ngolang.org/x/image v0.0.0-20210607152325-775e3b0c77b9/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM=\ngolang.org/x/image v0.0.0-20210628002857-a66eb6448b8d/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM=\ngolang.org/x/image v0.0.0-20211028202545-6944b10bf410/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM=\ngolang.org/x/image v0.0.0-20220302094943-723b81ca9867/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM=\ngolang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=\ngolang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=\ngolang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=\ngolang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=\ngolang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=\ngolang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=\ngolang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=\ngolang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=\ngolang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=\ngolang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=\ngolang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=\ngolang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=\ngolang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=\ngolang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=\ngolang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=\ngolang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=\ngolang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=\ngolang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=\ngolang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=\ngolang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=\ngolang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=\ngolang.org/x/mod v0.4.1 h1:Kvvh58BN8Y9/lBi7hTekvtMpm07eUZ0ck5pRHpsMWrY=\ngolang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=\ngolang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=\ngolang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=\ngolang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=\ngolang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY=\ngolang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=\ngolang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=\ngolang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=\ngolang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=\ngolang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=\ngolang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=\ngolang.org/x/mod v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0=\ngolang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=\ngolang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=\ngolang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=\ngolang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=\ngolang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=\ngolang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=\ngolang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20191002035440-2ec189313ef0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=\ngolang.org/x/net v0.0.0-20200421231249-e086a090c8fd/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=\ngolang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=\ngolang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=\ngolang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=\ngolang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=\ngolang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=\ngolang.org/x/net v0.0.0-20200602114024-627f9648deb9/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=\ngolang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=\ngolang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=\ngolang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=\ngolang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=\ngolang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=\ngolang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=\ngolang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=\ngolang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=\ngolang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=\ngolang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=\ngolang.org/x/net v0.0.0-20210226172049-e18ecbb05110 h1:qWPm9rbaAMKs8Bq/9LRpbMqxWRVUAQwMI9fVrssnTfw=\ngolang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=\ngolang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc=\ngolang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=\ngolang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8=\ngolang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=\ngolang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=\ngolang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=\ngolang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=\ngolang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=\ngolang.org/x/net v0.0.0-20220325170049-de3da57026de/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=\ngolang.org/x/net v0.0.0-20220412020605-290c469a71a5/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=\ngolang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=\ngolang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=\ngolang.org/x/net v0.0.0-20220617184016-355a448f1bc9/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=\ngolang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=\ngolang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=\ngolang.org/x/net v0.0.0-20220909164309-bea034e7d591/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=\ngolang.org/x/net v0.0.0-20221012135044-0b7e1fb9d458/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=\ngolang.org/x/net v0.0.0-20221014081412-f15817d10f9b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=\ngolang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco=\ngolang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=\ngolang.org/x/net v0.4.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE=\ngolang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws=\ngolang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=\ngolang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=\ngolang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=\ngolang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=\ngolang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=\ngolang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=\ngolang.org/x/net v0.16.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=\ngolang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo=\ngolang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0=\ngolang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=\ngolang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=\ngolang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=\ngolang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=\ngolang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=\ngolang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=\ngolang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=\ngolang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=\ngolang.org/x/oauth2 v0.0.0-20220608161450-d0670ef3b1eb/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE=\ngolang.org/x/oauth2 v0.0.0-20220622183110-fd043fe589d2/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE=\ngolang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg=\ngolang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg=\ngolang.org/x/oauth2 v0.0.0-20221006150949-b44042a4b9c1/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg=\ngolang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg=\ngolang.org/x/oauth2 v0.4.0/go.mod h1:RznEsdpjGAINPTOF0UH/t+xJ75L18YO3Ho6Pyn+uRec=\ngolang.org/x/oauth2 v0.5.0/go.mod h1:9/XBHVqLaWO3/BRHs5jbpYCnOZVjj5V0ndyaAM7KB4I=\ngolang.org/x/oauth2 v0.6.0/go.mod h1:ycmewcwgD4Rpr3eZJLSB4Kyyljb3qDh40vJ8STE5HKw=\ngolang.org/x/oauth2 v0.7.0/go.mod h1:hPLQkd9LyjfXTiRohC/41GhcFqxisoUQ99sCUOHO9x4=\ngolang.org/x/oauth2 v0.23.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=\ngolang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20190412183630-56d357773e84/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20220819030929-7fc1605a5dde/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20220929204114-8fcdb60fdcc0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=\ngolang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=\ngolang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=\ngolang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=\ngolang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200420163511-1957bb5e6d1f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20201024232916-9f70ab9862d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210228012217-479acdf4ea46/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210304124612-50617c2ba197/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210309074719-68d13333faf2 h1:46ULzRKLh1CwgRq2dC5SlBzEqqNCi8rreOZnNrbqcIY=\ngolang.org/x/sys v0.0.0-20210309074719-68d13333faf2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210816183151-1e6c022a8912/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20211105183446-c75c47738b0c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220328115105-d36c6a25d886/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220502124256-b6088ccd6cba/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220610221304-9f5ed59c137d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220615213510-4f61da869c0c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220624220833-87e55d714810/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220829200755-d48e67d00261/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34=\ngolang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=\ngolang.org/x/telemetry v0.0.0-20240521205824-bda55230c457/go.mod h1:pRgIJT+bRLFKnoM1ldnzKoxTIn14Yxz928LQRYYgIN0=\ngolang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=\ngolang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=\ngolang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=\ngolang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=\ngolang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=\ngolang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA=\ngolang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ=\ngolang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=\ngolang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=\ngolang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY=\ngolang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=\ngolang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU=\ngolang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U=\ngolang.org/x/term v0.24.0/go.mod h1:lOBK/LVxemqiMij05LGJ0tzNr8xlmwBRJ81PX6wVLH8=\ngolang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=\ngolang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=\ngolang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=\ngolang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=\ngolang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=\ngolang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=\ngolang.org/x/text v0.3.5 h1:i6eZZ+zk0SOf0xgBpEpPD18qWcJda6q1sxt3S0kzyUQ=\ngolang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=\ngolang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=\ngolang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=\ngolang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=\ngolang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=\ngolang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=\ngolang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=\ngolang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=\ngolang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=\ngolang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=\ngolang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=\ngolang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224=\ngolang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=\ngolang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=\ngolang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=\ngolang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=\ngolang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=\ngolang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=\ngolang.org/x/time v0.0.0-20220922220347-f3bd1da661af/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=\ngolang.org/x/time v0.1.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=\ngolang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=\ngolang.org/x/time v0.6.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=\ngolang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=\ngolang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=\ngolang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=\ngolang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=\ngolang.org/x/tools v0.0.0-20190110163146-51295c7ec13a/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=\ngolang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=\ngolang.org/x/tools v0.0.0-20190206041539-40960b6deb8e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=\ngolang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=\ngolang.org/x/tools v0.0.0-20190228203856-589c23e65e65/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=\ngolang.org/x/tools v0.0.0-20190307163923-6a08e3108db3/go.mod h1:25r3+/G6/xytQM8iWZKq3Hn0kr0rgFKPUNVEL/dr3z4=\ngolang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=\ngolang.org/x/tools v0.0.0-20190311215038-5c2858a9cfe5/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=\ngolang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=\ngolang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=\ngolang.org/x/tools v0.0.0-20190321232350-e250d351ecad/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=\ngolang.org/x/tools v0.0.0-20190322203728-c1a832b0ad89/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=\ngolang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=\ngolang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=\ngolang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=\ngolang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=\ngolang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=\ngolang.org/x/tools v0.0.0-20190617190820-da514acc4774/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=\ngolang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=\ngolang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=\ngolang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20190907020128-2ca718005c18/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20190910044552-dd2b5c81c578/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20190916130336-e45ffcd953cc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20190927191325-030b2cf1153e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191010075000-0337d82405ff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191216052735-49a3e744a425/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200117220505-0cba7a3a9ee9/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=\ngolang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=\ngolang.org/x/tools v0.0.0-20200324003944-a576cf524670/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=\ngolang.org/x/tools v0.0.0-20200329025819-fd4102a86c65/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=\ngolang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=\ngolang.org/x/tools v0.0.0-20200414032229-332987a829c3/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=\ngolang.org/x/tools v0.0.0-20200422022333-3d57cf2e726e/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=\ngolang.org/x/tools v0.0.0-20200426102838-f3a5411a4c3b/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=\ngolang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=\ngolang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=\ngolang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=\ngolang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=\ngolang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=\ngolang.org/x/tools v0.0.0-20200622203043-20e05c1c8ffa/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=\ngolang.org/x/tools v0.0.0-20200624225443-88f3c62a19ff/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=\ngolang.org/x/tools v0.0.0-20200625211823-6506e20df31f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=\ngolang.org/x/tools v0.0.0-20200626171337-aa94e735be7f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=\ngolang.org/x/tools v0.0.0-20200630154851-b2d8b0336632/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=\ngolang.org/x/tools v0.0.0-20200706234117-b22de6825cf7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=\ngolang.org/x/tools v0.0.0-20200724022722-7017fd6b1305/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=\ngolang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=\ngolang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=\ngolang.org/x/tools v0.0.0-20200812195022-5ae4c3c160a0/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=\ngolang.org/x/tools v0.0.0-20200820010801-b793a1359eac/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=\ngolang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=\ngolang.org/x/tools v0.0.0-20200831203904-5a2aa26beb65/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE=\ngolang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE=\ngolang.org/x/tools v0.0.0-20201001104356-43ebab892c4c/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU=\ngolang.org/x/tools v0.0.0-20201002184944-ecd9fd270d5d/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU=\ngolang.org/x/tools v0.0.0-20201011145850-ed2f50202694/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU=\ngolang.org/x/tools v0.0.0-20201023174141-c8cfbd0f21e6/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=\ngolang.org/x/tools v0.0.0-20201028025901-8cd080b735b3/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=\ngolang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=\ngolang.org/x/tools v0.0.0-20201114224030-61ea331ec02b/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=\ngolang.org/x/tools v0.0.0-20201118003311-bd56c0adb394/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=\ngolang.org/x/tools v0.0.0-20201124115921-2c860bdd6e78/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=\ngolang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=\ngolang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=\ngolang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=\ngolang.org/x/tools v0.0.0-20201230224404-63754364767c/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=\ngolang.org/x/tools v0.0.0-20210101214203-2dba1e4ea05c/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=\ngolang.org/x/tools v0.0.0-20210102185154-773b96fafca2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=\ngolang.org/x/tools v0.0.0-20210104081019-d8d6ddbec6ee/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=\ngolang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=\ngolang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=\ngolang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=\ngolang.org/x/tools v0.1.0 h1:po9/4sTYwZU9lPhi1tOrb4hCv3qrhiQ77LZfGa2OjwY=\ngolang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=\ngolang.org/x/tools v0.1.1-0.20210205202024-ef80cdb6ec6d/go.mod h1:9bzcO0MWcOuT0tm1iBGzDVPshzfwoVvREIui8C+MHqU=\ngolang.org/x/tools v0.1.1-0.20210302220138-2ac05c832e1a/go.mod h1:9bzcO0MWcOuT0tm1iBGzDVPshzfwoVvREIui8C+MHqU=\ngolang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=\ngolang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=\ngolang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=\ngolang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=\ngolang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=\ngolang.org/x/tools v0.1.9/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU=\ngolang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E=\ngolang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=\ngolang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k=\ngolang.org/x/tools v0.5.0/go.mod h1:N+Kgy78s5I24c24dU8OfWNEotWjutIs8SnJvn5IDq+k=\ngolang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=\ngolang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s=\ngolang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58=\ngolang.org/x/tools v0.14.0/go.mod h1:uYBEerGOWcJyEORxN+Ek8+TT266gXkNlHdJBwexUsBg=\ngolang.org/x/tools v0.25.0 h1:oFU9pkj/iJgs+0DT+VMHrx+oBKs/LJMV+Uvg78sl+fE=\ngolang.org/x/tools v0.25.0/go.mod h1:/vtpO8WL1N9cQC3FN5zPqb//fRXskFHbLKk4OW1Q7rg=\ngolang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngolang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngolang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngolang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=\ngolang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngolang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngolang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8=\ngolang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8=\ngolang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8=\ngolang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da h1:noIWHXmPHxILtqtCOPIhSt0ABwskkZKjD3bXGnZGpNY=\ngolang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90=\ngonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo=\ngonum.org/v1/gonum v0.8.2/go.mod h1:oe/vMfY3deqTw+1EZJhuvEW2iwGF1bW9wwu7XCu0+v0=\ngonum.org/v1/gonum v0.9.3/go.mod h1:TZumC3NeyVQskjXqmyWt4S3bINhy7B4eYwW69EbyX+0=\ngonum.org/v1/gonum v0.11.0/go.mod h1:fSG4YDCxxUZQJ7rKsQrj0gMOg00Il0Z96/qMA4bVQhA=\ngonum.org/v1/gonum v0.12.0/go.mod h1:73TDxJfAAHeA8Mk9mf8NlIppyhQNo5GLTcYeqgo2lvY=\ngonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw=\ngonum.org/v1/plot v0.0.0-20190515093506-e2840ee46a6b/go.mod h1:Wt8AAjI+ypCyYX3nZBvf6cAIx93T+c/OS2HFAYskSZc=\ngonum.org/v1/plot v0.9.0/go.mod h1:3Pcqqmp6RHvJI72kgb8fThyUnav364FOsdDo2aGW5lY=\ngonum.org/v1/plot v0.10.1/go.mod h1:VZW5OlhkL1mysU9vaqNHnsy86inf6Ot+jB3r+BczCEo=\ngoogle.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=\ngoogle.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=\ngoogle.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=\ngoogle.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=\ngoogle.golang.org/api v0.10.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=\ngoogle.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=\ngoogle.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=\ngoogle.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=\ngoogle.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=\ngoogle.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=\ngoogle.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=\ngoogle.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=\ngoogle.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=\ngoogle.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=\ngoogle.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=\ngoogle.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=\ngoogle.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=\ngoogle.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg=\ngoogle.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE=\ngoogle.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8=\ngoogle.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU=\ngoogle.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94=\ngoogle.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo=\ngoogle.golang.org/api v0.48.0/go.mod h1:71Pr1vy+TAZRPkPs/xlCf5SsU8WjuAWv1Pfjbtukyy4=\ngoogle.golang.org/api v0.50.0/go.mod h1:4bNT5pAuq5ji4SRZm+5QIkjny9JAyVD/3gaSihNefaw=\ngoogle.golang.org/api v0.51.0/go.mod h1:t4HdrdoNgyN5cbEfm7Lum0lcLDLiise1F8qDKX00sOU=\ngoogle.golang.org/api v0.54.0/go.mod h1:7C4bFFOvVDGXjfDTAsgGwDgAxRDeQ4X8NvUedIt6z3k=\ngoogle.golang.org/api v0.55.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE=\ngoogle.golang.org/api v0.56.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE=\ngoogle.golang.org/api v0.57.0/go.mod h1:dVPlbZyBo2/OjBpmvNdpn2GRm6rPy75jyU7bmhdrMgI=\ngoogle.golang.org/api v0.61.0/go.mod h1:xQRti5UdCmoCEqFxcz93fTl338AVqDgyaDRuOZ3hg9I=\ngoogle.golang.org/api v0.63.0/go.mod h1:gs4ij2ffTRXwuzzgJl/56BdwJaA194ijkfn++9tDuPo=\ngoogle.golang.org/api v0.67.0/go.mod h1:ShHKP8E60yPsKNw/w8w+VYaj9H6buA5UqDp8dhbQZ6g=\ngoogle.golang.org/api v0.70.0/go.mod h1:Bs4ZM2HGifEvXwd50TtW70ovgJffJYw2oRCOFU/SkfA=\ngoogle.golang.org/api v0.71.0/go.mod h1:4PyU6e6JogV1f9eA4voyrTY2batOLdgZ5qZ5HOCc4j8=\ngoogle.golang.org/api v0.74.0/go.mod h1:ZpfMZOVRMywNyvJFeqL9HRWBgAuRfSjJFpe9QtRRyDs=\ngoogle.golang.org/api v0.75.0/go.mod h1:pU9QmyHLnzlpar1Mjt4IbapUCy8J+6HD6GeELN69ljA=\ngoogle.golang.org/api v0.77.0/go.mod h1:pU9QmyHLnzlpar1Mjt4IbapUCy8J+6HD6GeELN69ljA=\ngoogle.golang.org/api v0.78.0/go.mod h1:1Sg78yoMLOhlQTeF+ARBoytAcH1NNyyl390YMy6rKmw=\ngoogle.golang.org/api v0.80.0/go.mod h1:xY3nI94gbvBrE0J6NHXhxOmW97HG7Khjkku6AFB3Hyg=\ngoogle.golang.org/api v0.84.0/go.mod h1:NTsGnUFJMYROtiquksZHBWtHfeMC7iYthki7Eq3pa8o=\ngoogle.golang.org/api v0.85.0/go.mod h1:AqZf8Ep9uZ2pyTvgL+x0D3Zt0eoT9b5E8fmzfu6FO2g=\ngoogle.golang.org/api v0.90.0/go.mod h1:+Sem1dnrKlrXMR/X0bPnMWyluQe4RsNoYfmNLhOIkzw=\ngoogle.golang.org/api v0.93.0/go.mod h1:+Sem1dnrKlrXMR/X0bPnMWyluQe4RsNoYfmNLhOIkzw=\ngoogle.golang.org/api v0.95.0/go.mod h1:eADj+UBuxkh5zlrSntJghuNeg8HwQ1w5lTKkuqaETEI=\ngoogle.golang.org/api v0.96.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s=\ngoogle.golang.org/api v0.97.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s=\ngoogle.golang.org/api v0.98.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s=\ngoogle.golang.org/api v0.99.0/go.mod h1:1YOf74vkVndF7pG6hIHuINsM7eWwpVTAfNMNiL91A08=\ngoogle.golang.org/api v0.100.0/go.mod h1:ZE3Z2+ZOr87Rx7dqFsdRQkRBk36kDtp/h+QpHbB7a70=\ngoogle.golang.org/api v0.102.0/go.mod h1:3VFl6/fzoA+qNuS1N1/VfXY4LjoXN/wzeIp7TweWwGo=\ngoogle.golang.org/api v0.103.0/go.mod h1:hGtW6nK1AC+d9si/UBhw8Xli+QMOf6xyNAyJw4qU9w0=\ngoogle.golang.org/api v0.106.0/go.mod h1:2Ts0XTHNVWxypznxWOYUeI4g3WdP9Pk2Qk58+a/O9MY=\ngoogle.golang.org/api v0.107.0/go.mod h1:2Ts0XTHNVWxypznxWOYUeI4g3WdP9Pk2Qk58+a/O9MY=\ngoogle.golang.org/api v0.108.0/go.mod h1:2Ts0XTHNVWxypznxWOYUeI4g3WdP9Pk2Qk58+a/O9MY=\ngoogle.golang.org/api v0.110.0/go.mod h1:7FC4Vvx1Mooxh8C5HWjzZHcavuS2f6pmJpZx60ca7iI=\ngoogle.golang.org/api v0.111.0/go.mod h1:qtFHvU9mhgTJegR31csQ+rwxyUTHOKFqCKWp1J0fdw0=\ngoogle.golang.org/api v0.114.0/go.mod h1:ifYI2ZsFK6/uGddGfAD5BMxlnkBqCmqHSDUVi45N5Yg=\ngoogle.golang.org/api v0.197.0/go.mod h1:AuOuo20GoQ331nq7DquGHlU6d+2wN2fZ8O0ta60nRNw=\ngoogle.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=\ngoogle.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=\ngoogle.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=\ngoogle.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=\ngoogle.golang.org/appengine v1.6.2/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=\ngoogle.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=\ngoogle.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=\ngoogle.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=\ngoogle.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds=\ngoogle.golang.org/genproto v0.0.0-20170818010345-ee236bd376b0/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=\ngoogle.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=\ngoogle.golang.org/genproto v0.0.0-20181107211654-5fc9ac540362/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=\ngoogle.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=\ngoogle.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=\ngoogle.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=\ngoogle.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=\ngoogle.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=\ngoogle.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=\ngoogle.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=\ngoogle.golang.org/genproto v0.0.0-20190927181202-20e1ac93f88c/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=\ngoogle.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=\ngoogle.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=\ngoogle.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=\ngoogle.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=\ngoogle.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=\ngoogle.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=\ngoogle.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA=\ngoogle.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U=\ngoogle.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=\ngoogle.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=\ngoogle.golang.org/genproto v0.0.0-20200626011028-ee7919e894b5/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20200707001353-8e8330bf89df/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20210329143202-679c6ae281ee/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A=\ngoogle.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A=\ngoogle.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A=\ngoogle.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=\ngoogle.golang.org/genproto v0.0.0-20210604141403-392c879c8b08/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=\ngoogle.golang.org/genproto v0.0.0-20210608205507-b6d2f5bf0d7d/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=\ngoogle.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24=\ngoogle.golang.org/genproto v0.0.0-20210713002101-d411969a0d9a/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k=\ngoogle.golang.org/genproto v0.0.0-20210716133855-ce7ef5c701ea/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k=\ngoogle.golang.org/genproto v0.0.0-20210728212813-7823e685a01f/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48=\ngoogle.golang.org/genproto v0.0.0-20210805201207-89edb61ffb67/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48=\ngoogle.golang.org/genproto v0.0.0-20210813162853-db860fec028c/go.mod h1:cFeNkxwySK631ADgubI+/XFU/xp8FD5KIVV4rj8UC5w=\ngoogle.golang.org/genproto v0.0.0-20210821163610-241b8fcbd6c8/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=\ngoogle.golang.org/genproto v0.0.0-20210828152312-66f60bf46e71/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=\ngoogle.golang.org/genproto v0.0.0-20210831024726-fe130286e0e2/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=\ngoogle.golang.org/genproto v0.0.0-20210903162649-d08c68adba83/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=\ngoogle.golang.org/genproto v0.0.0-20210909211513-a8c4777a87af/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=\ngoogle.golang.org/genproto v0.0.0-20210924002016-3dee208752a0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=\ngoogle.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=\ngoogle.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=\ngoogle.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=\ngoogle.golang.org/genproto v0.0.0-20211221195035-429b39de9b1c/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=\ngoogle.golang.org/genproto v0.0.0-20220126215142-9970aeb2e350/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=\ngoogle.golang.org/genproto v0.0.0-20220207164111-0872dc986b00/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=\ngoogle.golang.org/genproto v0.0.0-20220218161850-94dd64e39d7c/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI=\ngoogle.golang.org/genproto v0.0.0-20220222213610-43724f9ea8cf/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI=\ngoogle.golang.org/genproto v0.0.0-20220304144024-325a89244dc8/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI=\ngoogle.golang.org/genproto v0.0.0-20220310185008-1973136f34c6/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI=\ngoogle.golang.org/genproto v0.0.0-20220324131243-acbaeb5b85eb/go.mod h1:hAL49I2IFola2sVEjAn7MEwsja0xp51I0tlGAf9hz4E=\ngoogle.golang.org/genproto v0.0.0-20220329172620-7be39ac1afc7/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo=\ngoogle.golang.org/genproto v0.0.0-20220407144326-9054f6ed7bac/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo=\ngoogle.golang.org/genproto v0.0.0-20220413183235-5e96e2839df9/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo=\ngoogle.golang.org/genproto v0.0.0-20220414192740-2d67ff6cf2b4/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo=\ngoogle.golang.org/genproto v0.0.0-20220421151946-72621c1f0bd3/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo=\ngoogle.golang.org/genproto v0.0.0-20220429170224-98d788798c3e/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo=\ngoogle.golang.org/genproto v0.0.0-20220502173005-c8bf987b8c21/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4=\ngoogle.golang.org/genproto v0.0.0-20220505152158-f39f71e6c8f3/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4=\ngoogle.golang.org/genproto v0.0.0-20220518221133-4f43b3371335/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4=\ngoogle.golang.org/genproto v0.0.0-20220523171625-347a074981d8/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4=\ngoogle.golang.org/genproto v0.0.0-20220608133413-ed9918b62aac/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA=\ngoogle.golang.org/genproto v0.0.0-20220616135557-88e70c0c3a90/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA=\ngoogle.golang.org/genproto v0.0.0-20220617124728-180714bec0ad/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA=\ngoogle.golang.org/genproto v0.0.0-20220624142145-8cd45d7dbd1f/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA=\ngoogle.golang.org/genproto v0.0.0-20220628213854-d9e0b6570c03/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA=\ngoogle.golang.org/genproto v0.0.0-20220722212130-b98a9ff5e252/go.mod h1:GkXuJDJ6aQ7lnJcRF+SJVgFdQhypqgl3LB1C9vabdRE=\ngoogle.golang.org/genproto v0.0.0-20220801145646-83ce21fca29f/go.mod h1:iHe1svFLAZg9VWz891+QbRMwUv9O/1Ww+/mngYeThbc=\ngoogle.golang.org/genproto v0.0.0-20220815135757-37a418bb8959/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk=\ngoogle.golang.org/genproto v0.0.0-20220817144833-d7fd3f11b9b1/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk=\ngoogle.golang.org/genproto v0.0.0-20220822174746-9e6da59bd2fc/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk=\ngoogle.golang.org/genproto v0.0.0-20220829144015-23454907ede3/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk=\ngoogle.golang.org/genproto v0.0.0-20220829175752-36a9c930ecbf/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk=\ngoogle.golang.org/genproto v0.0.0-20220913154956-18f8339a66a5/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo=\ngoogle.golang.org/genproto v0.0.0-20220914142337-ca0e39ece12f/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo=\ngoogle.golang.org/genproto v0.0.0-20220915135415-7fd63a7952de/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo=\ngoogle.golang.org/genproto v0.0.0-20220916172020-2692e8806bfa/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo=\ngoogle.golang.org/genproto v0.0.0-20220919141832-68c03719ef51/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo=\ngoogle.golang.org/genproto v0.0.0-20220920201722-2b89144ce006/go.mod h1:ht8XFiar2npT/g4vkk7O0WYS1sHOHbdujxbEp7CJWbw=\ngoogle.golang.org/genproto v0.0.0-20220926165614-551eb538f295/go.mod h1:woMGP53BroOrRY3xTxlbr8Y3eB/nzAvvFM83q7kG2OI=\ngoogle.golang.org/genproto v0.0.0-20220926220553-6981cbe3cfce/go.mod h1:woMGP53BroOrRY3xTxlbr8Y3eB/nzAvvFM83q7kG2OI=\ngoogle.golang.org/genproto v0.0.0-20221010155953-15ba04fc1c0e/go.mod h1:3526vdqwhZAwq4wsRUaVG555sVgsNmIjRtO7t/JH29U=\ngoogle.golang.org/genproto v0.0.0-20221014173430-6e2ab493f96b/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM=\ngoogle.golang.org/genproto v0.0.0-20221014213838-99cd37c6964a/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM=\ngoogle.golang.org/genproto v0.0.0-20221024153911-1573dae28c9c/go.mod h1:9qHF0xnpdSfF6knlcsnpzUu5y+rpwgbvsyGAZPBMg4s=\ngoogle.golang.org/genproto v0.0.0-20221024183307-1bc688fe9f3e/go.mod h1:9qHF0xnpdSfF6knlcsnpzUu5y+rpwgbvsyGAZPBMg4s=\ngoogle.golang.org/genproto v0.0.0-20221027153422-115e99e71e1c/go.mod h1:CGI5F/G+E5bKwmfYo09AXuVN4dD894kIKUFmVbP2/Fo=\ngoogle.golang.org/genproto v0.0.0-20221109142239-94d6d90a7d66/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg=\ngoogle.golang.org/genproto v0.0.0-20221114212237-e4508ebdbee1/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg=\ngoogle.golang.org/genproto v0.0.0-20221117204609-8f9c96812029/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg=\ngoogle.golang.org/genproto v0.0.0-20221118155620-16455021b5e6/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg=\ngoogle.golang.org/genproto v0.0.0-20221201164419-0e50fba7f41c/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg=\ngoogle.golang.org/genproto v0.0.0-20221201204527-e3fa12d562f3/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg=\ngoogle.golang.org/genproto v0.0.0-20221202195650-67e5cbc046fd/go.mod h1:cTsE614GARnxrLsqKREzmNYJACSWWpAWdNMwnD7c2BE=\ngoogle.golang.org/genproto v0.0.0-20221227171554-f9683d7f8bef/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM=\ngoogle.golang.org/genproto v0.0.0-20230110181048-76db0878b65f/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM=\ngoogle.golang.org/genproto v0.0.0-20230112194545-e10362b5ecf9/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM=\ngoogle.golang.org/genproto v0.0.0-20230113154510-dbe35b8444a5/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM=\ngoogle.golang.org/genproto v0.0.0-20230123190316-2c411cf9d197/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM=\ngoogle.golang.org/genproto v0.0.0-20230124163310-31e0e69b6fc2/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM=\ngoogle.golang.org/genproto v0.0.0-20230125152338-dcaf20b6aeaa/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM=\ngoogle.golang.org/genproto v0.0.0-20230127162408-596548ed4efa/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM=\ngoogle.golang.org/genproto v0.0.0-20230209215440-0dfe4f8abfcc/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM=\ngoogle.golang.org/genproto v0.0.0-20230216225411-c8e22ba71e44/go.mod h1:8B0gmkoRebU8ukX6HP+4wrVQUY1+6PkQ44BSyIlflHA=\ngoogle.golang.org/genproto v0.0.0-20230222225845-10f96fb3dbec/go.mod h1:3Dl5ZL0q0isWJt+FVcfpQyirqemEuLAK/iFvg1UP1Hw=\ngoogle.golang.org/genproto v0.0.0-20230223222841-637eb2293923/go.mod h1:3Dl5ZL0q0isWJt+FVcfpQyirqemEuLAK/iFvg1UP1Hw=\ngoogle.golang.org/genproto v0.0.0-20230303212802-e74f57abe488/go.mod h1:TvhZT5f700eVlTNwND1xoEZQeWTB2RY/65kplwl/bFA=\ngoogle.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4/go.mod h1:NWraEVixdDnqcqQ30jipen1STv2r/n24Wb7twVTGR4s=\ngoogle.golang.org/genproto v0.0.0-20230320184635-7606e756e683/go.mod h1:NWraEVixdDnqcqQ30jipen1STv2r/n24Wb7twVTGR4s=\ngoogle.golang.org/genproto v0.0.0-20230323212658-478b75c54725/go.mod h1:UUQDJDOlWu4KYeJZffbWgBkS1YFobzKbLVfK69pe0Ak=\ngoogle.golang.org/genproto v0.0.0-20230330154414-c0448cd141ea/go.mod h1:UUQDJDOlWu4KYeJZffbWgBkS1YFobzKbLVfK69pe0Ak=\ngoogle.golang.org/genproto v0.0.0-20230331144136-dcfb400f0633/go.mod h1:UUQDJDOlWu4KYeJZffbWgBkS1YFobzKbLVfK69pe0Ak=\ngoogle.golang.org/genproto v0.0.0-20230410155749-daa745c078e1/go.mod h1:nKE/iIaLqn2bQwXBg8f1g2Ylh6r5MN5CmZvuzZCgsCU=\ngoogle.golang.org/genproto v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:hL97c3SYopEHblzpxRL4lSs523++l8DYxGM1FQiYmb4=\ngoogle.golang.org/genproto/googleapis/api v0.0.0-20240827150818-7e3bb234dfed/go.mod h1:OCdP9MfskevB/rbYvHTsXTtKC+3bHWajPdoKgjcYkfo=\ngoogle.golang.org/genproto/googleapis/bytestream v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:q0eWNnCW04EJlyrmLT+ZHsjuoUiZ36/eAEdCCezZoco=\ngoogle.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU=\ngoogle.golang.org/grpc v1.8.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=\ngoogle.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=\ngoogle.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=\ngoogle.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=\ngoogle.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=\ngoogle.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=\ngoogle.golang.org/grpc v1.24.0/go.mod h1:XDChyiUovWa60DnaeDeZmSW86xtLtjtZbwvSiRnRtcA=\ngoogle.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=\ngoogle.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=\ngoogle.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=\ngoogle.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=\ngoogle.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=\ngoogle.golang.org/grpc v1.29.0/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=\ngoogle.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=\ngoogle.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=\ngoogle.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=\ngoogle.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=\ngoogle.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=\ngoogle.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=\ngoogle.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8=\ngoogle.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=\ngoogle.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=\ngoogle.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=\ngoogle.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=\ngoogle.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=\ngoogle.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=\ngoogle.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE=\ngoogle.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE=\ngoogle.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=\ngoogle.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=\ngoogle.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU=\ngoogle.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU=\ngoogle.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ=\ngoogle.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=\ngoogle.golang.org/grpc v1.46.2/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=\ngoogle.golang.org/grpc v1.47.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=\ngoogle.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=\ngoogle.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI=\ngoogle.golang.org/grpc v1.50.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI=\ngoogle.golang.org/grpc v1.50.1/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI=\ngoogle.golang.org/grpc v1.51.0/go.mod h1:wgNDFcnuBGmxLKI/qn4T+m5BtEBYXJPvibbUPsAIPww=\ngoogle.golang.org/grpc v1.52.3/go.mod h1:pu6fVzoFb+NBYNAvQL08ic+lvB2IojljRYuun5vorUY=\ngoogle.golang.org/grpc v1.53.0/go.mod h1:OnIrk0ipVdj4N5d9IUoFUx72/VlD7+jUsHwZgwSMQpw=\ngoogle.golang.org/grpc v1.54.0/go.mod h1:PUSEXI6iWghWaB6lXM4knEgpJNu2qUcKfDtNci3EC2g=\ngoogle.golang.org/grpc v1.56.3/go.mod h1:I9bI3vqKfayGqPUAwGdOSu7kt6oIJLixfffKrpXqQ9s=\ngoogle.golang.org/grpc v1.66.1/go.mod h1:s3/l6xSSCURdVfAnL+TqCNMyTDAGN6+lZeVxnZR128Y=\ngoogle.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw=\ngoogle.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=\ngoogle.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=\ngoogle.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=\ngoogle.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=\ngoogle.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=\ngoogle.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=\ngoogle.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=\ngoogle.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=\ngoogle.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=\ngoogle.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=\ngoogle.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=\ngoogle.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=\ngoogle.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=\ngoogle.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=\ngoogle.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=\ngoogle.golang.org/protobuf v1.29.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=\ngoogle.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=\ngoogle.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=\ngoogle.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=\ngopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=\ngopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=\ngopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=\ngopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=\ngopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=\ngopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=\ngopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=\ngopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=\ngopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=\ngopkg.in/cheggaaa/pb.v1 v1.0.28/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=\ngopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=\ngopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=\ngopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o=\ngopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=\ngopkg.in/ini.v1 v1.62.0 h1:duBzk771uxoUuOlyRLkHsygud9+5lrlGjdFBb4mSKDU=\ngopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=\ngopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=\ngopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=\ngopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=\ngopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=\ngopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=\ngopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=\ngopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=\ngopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=\ngopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=\ngopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=\ngopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=\ngopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=\ngopkg.in/yaml.v2 v2.2.6/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=\ngopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=\ngopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=\ngopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=\ngopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=\ngopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=\ngopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=\ngopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=\ngopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=\ngopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=\ngotest.tools/v3 v3.5.1/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU=\nhonnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=\nhonnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=\nhonnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=\nhonnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=\nhonnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=\nhonnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=\nhonnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=\nhonnef.co/go/tools v0.1.2 h1:SMdYLJl312RXuxXziCCHhRsp/tvct9cGKey0yv95tZM=\nhonnef.co/go/tools v0.1.2/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las=\nhonnef.co/go/tools v0.1.3/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las=\nhonnef.co/go/tools v0.5.1 h1:4bH5o3b5ZULQ4UrBmP+63W9r7qIkqJClEA9ko5YKx+I=\nhonnef.co/go/tools v0.5.1/go.mod h1:e9irvo83WDG9/irijV44wr3tbhcFeRnfpVlRqVwpzMs=\nlukechampine.com/uint128 v1.1.1/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk=\nlukechampine.com/uint128 v1.2.0/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk=\nlukechampine.com/uint128 v1.3.0/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk=\nmodernc.org/cc/v3 v3.36.0/go.mod h1:NFUHyPn4ekoC/JHeZFfZurN6ixxawE1BnVonP/oahEI=\nmodernc.org/cc/v3 v3.36.2/go.mod h1:NFUHyPn4ekoC/JHeZFfZurN6ixxawE1BnVonP/oahEI=\nmodernc.org/cc/v3 v3.36.3/go.mod h1:NFUHyPn4ekoC/JHeZFfZurN6ixxawE1BnVonP/oahEI=\nmodernc.org/cc/v3 v3.40.0/go.mod h1:/bTg4dnWkSXowUO6ssQKnOV0yMVxDYNIsIrzqTFDGH0=\nmodernc.org/ccgo/v3 v3.0.0-20220428102840-41399a37e894/go.mod h1:eI31LL8EwEBKPpNpA4bU1/i+sKOwOrQy8D87zWUcRZc=\nmodernc.org/ccgo/v3 v3.0.0-20220430103911-bc99d88307be/go.mod h1:bwdAnOoaIt8Ax9YdWGjxWsdkPcZyRPHqrOvJxaKAKGw=\nmodernc.org/ccgo/v3 v3.16.4/go.mod h1:tGtX0gE9Jn7hdZFeU88slbTh1UtCYKusWOoCJuvkWsQ=\nmodernc.org/ccgo/v3 v3.16.6/go.mod h1:tGtX0gE9Jn7hdZFeU88slbTh1UtCYKusWOoCJuvkWsQ=\nmodernc.org/ccgo/v3 v3.16.8/go.mod h1:zNjwkizS+fIFDrDjIAgBSCLkWbJuHF+ar3QRn+Z9aws=\nmodernc.org/ccgo/v3 v3.16.9/go.mod h1:zNMzC9A9xeNUepy6KuZBbugn3c0Mc9TeiJO4lgvkJDo=\nmodernc.org/ccgo/v3 v3.16.13/go.mod h1:2Quk+5YgpImhPjv2Qsob1DnZ/4som1lJTodubIcoUkY=\nmodernc.org/ccorpus v1.11.6/go.mod h1:2gEUTrWqdpH2pXsmTM1ZkjeSrUWDpjMu2T6m29L/ErQ=\nmodernc.org/httpfs v1.0.6/go.mod h1:7dosgurJGp0sPaRanU53W4xZYKh14wfzX420oZADeHM=\nmodernc.org/libc v0.0.0-20220428101251-2d5f3daf273b/go.mod h1:p7Mg4+koNjc8jkqwcoFBJx7tXkpj00G77X7A72jXPXA=\nmodernc.org/libc v1.16.0/go.mod h1:N4LD6DBE9cf+Dzf9buBlzVJndKr/iJHG97vGLHYnb5A=\nmodernc.org/libc v1.16.1/go.mod h1:JjJE0eu4yeK7tab2n4S1w8tlWd9MxXLRzheaRnAKymU=\nmodernc.org/libc v1.16.17/go.mod h1:hYIV5VZczAmGZAnG15Vdngn5HSF5cSkbvfz2B7GRuVU=\nmodernc.org/libc v1.16.19/go.mod h1:p7Mg4+koNjc8jkqwcoFBJx7tXkpj00G77X7A72jXPXA=\nmodernc.org/libc v1.17.0/go.mod h1:XsgLldpP4aWlPlsjqKRdHPqCxCjISdHfM/yeWC5GyW0=\nmodernc.org/libc v1.17.1/go.mod h1:FZ23b+8LjxZs7XtFMbSzL/EhPxNbfZbErxEHc7cbD9s=\nmodernc.org/libc v1.22.4/go.mod h1:jj+Z7dTNX8fBScMVNRAYZ/jF91K8fdT2hYMThc3YjBY=\nmodernc.org/mathutil v1.2.2/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=\nmodernc.org/mathutil v1.4.1/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=\nmodernc.org/mathutil v1.5.0/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=\nmodernc.org/memory v1.1.1/go.mod h1:/0wo5ibyrQiaoUoH7f9D8dnglAmILJ5/cxZlRECf+Nw=\nmodernc.org/memory v1.2.0/go.mod h1:/0wo5ibyrQiaoUoH7f9D8dnglAmILJ5/cxZlRECf+Nw=\nmodernc.org/memory v1.2.1/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU=\nmodernc.org/memory v1.5.0/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU=\nmodernc.org/opt v0.1.1/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0=\nmodernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0=\nmodernc.org/sqlite v1.18.1/go.mod h1:6ho+Gow7oX5V+OiOQ6Tr4xeqbx13UZ6t+Fw9IRUG4d4=\nmodernc.org/sqlite v1.21.2/go.mod h1:cxbLkB5WS32DnQqeH4h4o1B0eMr8W/y8/RGuxQ3JsC0=\nmodernc.org/strutil v1.1.1/go.mod h1:DE+MQQ/hjKBZS2zNInV5hhcipt5rLPWkmpbGeW5mmdw=\nmodernc.org/strutil v1.1.3/go.mod h1:MEHNA7PdEnEwLvspRMtWTNnp2nnyvMfkimT1NKNAGbw=\nmodernc.org/tcl v1.13.1/go.mod h1:XOLfOwzhkljL4itZkK6T72ckMgvj0BDsnKNdZVUOecw=\nmodernc.org/tcl v1.15.1/go.mod h1:aEjeGJX2gz1oWKOLDVZ2tnEWLUrIn8H+GFu+akoDhqs=\nmodernc.org/token v1.0.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM=\nmodernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM=\nmodernc.org/z v1.5.1/go.mod h1:eWFB510QWW5Th9YGZT81s+LwvaAs3Q2yr4sP0rmLkv8=\nmodernc.org/z v1.7.0/go.mod h1:hVdgNMh8ggTuRG1rGU8x+xGRFfiQUIAw0ZqlPy8+HyQ=\nmvdan.cc/gofumpt v0.1.0 h1:hsVv+Y9UsZ/mFZTxJZuHVI6shSQCtzZ11h1JEFPAZLw=\nmvdan.cc/gofumpt v0.1.0/go.mod h1:yXG1r1WqZVKWbVRtBWKWX9+CxGYfA51nSomhM0woR48=\nmvdan.cc/gofumpt v0.7.0 h1:bg91ttqXmi9y2xawvkuMXyvAA/1ZGJqYAEGjXuP0JXU=\nmvdan.cc/gofumpt v0.7.0/go.mod h1:txVFJy/Sc/mvaycET54pV8SW8gWxTlUuGHVEcncmNUo=\nmvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed h1:WX1yoOaKQfddO/mLzdV4wptyWgoH/6hwLs7QHTixo0I=\nmvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed/go.mod h1:Xkxe497xwlCKkIaQYRfC7CSLworTXY9RMqwhhCm+8Nc=\nmvdan.cc/lint v0.0.0-20170908181259-adc824a0674b h1:DxJ5nJdkhDlLok9K6qO+5290kphDJbHOQO1DFFFTeBo=\nmvdan.cc/lint v0.0.0-20170908181259-adc824a0674b/go.mod h1:2odslEg/xrtNQqCYg2/jCoyKnw3vv5biOc3JnIcYfL4=\nmvdan.cc/unparam v0.0.0-20210104141923-aac4ce9116a7 h1:HT3e4Krq+IE44tiN36RvVEb6tvqeIdtsVSsxmNPqlFU=\nmvdan.cc/unparam v0.0.0-20210104141923-aac4ce9116a7/go.mod h1:hBpJkZE8H/sb+VRFvw2+rBpHNsTBcvSpk61hr8mzXZE=\nmvdan.cc/unparam v0.0.0-20240917084806-57a3b4290ba3 h1:YkmTN1n5U60NM02j7TCSWRlW3fqNiuXe/eVXf0dLFN8=\nmvdan.cc/unparam v0.0.0-20240917084806-57a3b4290ba3/go.mod h1:z5yboO1sP1Q9pcfvS597TpfbNXQjphDlkCJHzt13ybc=\nrsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=\nrsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=\nrsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=\nrsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=\nsigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=\nsigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=\n"
  },
  {
    "path": "tools/tools.go",
    "content": "package tools\n\nimport (\n\t_ \"github.com/AlekSi/gocov-xml\"\n\t_ \"github.com/axw/gocov/gocov\"\n\t_ \"github.com/golang/mock/mockgen\"\n\t_ \"github.com/golangci/golangci-lint/cmd/golangci-lint\"\n\t_ \"github.com/matm/gocov-html\"\n\t_ \"github.com/wadey/gocovmerge\"\n\t_ \"golang.org/x/tools/cmd/goimports\"\n)\n"
  }
]