forked from lug/matterbridge
		
	Compare commits
	
		
			93 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					2bb21262d4 | ||
| 
						 | 
					3188a9ffe6 | ||
| 
						 | 
					61569a8610 | ||
| 
						 | 
					075a84427f | ||
| 
						 | 
					950f2759bd | ||
| 
						 | 
					25c82ddf02 | ||
| 
						 | 
					2d98df6122 | ||
| 
						 | 
					219a5453f9 | ||
| 
						 | 
					214a6a1386 | ||
| 
						 | 
					e7781dc79c | ||
| 
						 | 
					10c4bd1ac8 | ||
| 
						 | 
					a42e488e58 | ||
| 
						 | 
					06eb89b05b | ||
| 
						 | 
					91c58ec027 | ||
| 
						 | 
					8b26e42a3a | ||
| 
						 | 
					acca011f15 | ||
| 
						 | 
					2f59abdda7 | ||
| 
						 | 
					17747a5c88 | ||
| 
						 | 
					cec63546ff | ||
| 
						 | 
					75f67d2de4 | ||
| 
						 | 
					712385ffd5 | ||
| 
						 | 
					ad90cf09fe | ||
| 
						 | 
					f9928c9e25 | ||
| 
						 | 
					a0741d99b8 | ||
| 
						 | 
					c63f08c811 | ||
| 
						 | 
					58b6c4d277 | ||
| 
						 | 
					27c02549c8 | ||
| 
						 | 
					88d371c71c | ||
| 
						 | 
					b339524613 | ||
| 
						 | 
					d5feda5c8a | ||
| 
						 | 
					2f506425c2 | ||
| 
						 | 
					e8167ee3d7 | ||
| 
						 | 
					2f5e211065 | ||
| 
						 | 
					39f4fb3446 | ||
| 
						 | 
					56159b9bce | ||
| 
						 | 
					b2af76e7dc | ||
| 
						 | 
					491fe35397 | ||
| 
						 | 
					b451285af7 | ||
| 
						 | 
					63a1847cdc | ||
| 
						 | 
					4e50fd8649 | ||
| 
						 | 
					dfdffa0027 | ||
| 
						 | 
					ebd2073144 | ||
| 
						 | 
					1e94b716fb | ||
| 
						 | 
					2a41abb3d1 | ||
| 
						 | 
					2d2bebe976 | ||
| 
						 | 
					e1629994bd | ||
| 
						 | 
					e3d8fe4fd8 | ||
| 
						 | 
					23d8742f0d | ||
| 
						 | 
					3b6a8be07b | ||
| 
						 | 
					71a5b72aff | ||
| 
						 | 
					213bf349c3 | ||
| 
						 | 
					a94fe55886 | ||
| 
						 | 
					9b22f16497 | ||
| 
						 | 
					2977a5957e | ||
| 
						 | 
					f70d1c897a | ||
| 
						 | 
					a4a3525265 | ||
| 
						 | 
					a6dd8446e4 | ||
| 
						 | 
					7bf9e1cfb3 | ||
| 
						 | 
					f291832a77 | ||
| 
						 | 
					1fee323247 | ||
| 
						 | 
					a41accd033 | ||
| 
						 | 
					37f7caf7f3 | ||
| 
						 | 
					5847f7758c | ||
| 
						 | 
					bce736993e | ||
| 
						 | 
					5636992446 | ||
| 
						 | 
					f996a2b7ae | ||
| 
						 | 
					587de96ab3 | ||
| 
						 | 
					80eb1cd202 | ||
| 
						 | 
					bbf594c815 | ||
| 
						 | 
					2f0f2ee40d | ||
| 
						 | 
					96022d3aaf | ||
| 
						 | 
					8eb5e3cbf8 | ||
| 
						 | 
					ddc2625934 | ||
| 
						 | 
					7f7ca697a0 | ||
| 
						 | 
					900375679b | ||
| 
						 | 
					9440b9e313 | ||
| 
						 | 
					393f9e998b | ||
| 
						 | 
					ba0bfe70a8 | ||
| 
						 | 
					3c4a3e3f75 | ||
| 
						 | 
					274fb09ed4 | ||
| 
						 | 
					d44598a900 | ||
| 
						 | 
					c9cfa59f54 | ||
| 
						 | 
					7062234331 | ||
| 
						 | 
					9754569525 | ||
| 
						 | 
					52a071e34d | ||
| 
						 | 
					2d8f749e36 | ||
| 
						 | 
					a18cb74f03 | ||
| 
						 | 
					6c442e239d | ||
| 
						 | 
					eaf92fca4d | ||
| 
						 | 
					06b7bad714 | ||
| 
						 | 
					19eec2ed03 | ||
| 
						 | 
					d99c54343a | ||
| 
						 | 
					308a110000 | 
							
								
								
									
										2
									
								
								.dockerignore
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								.dockerignore
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,2 @@
 | 
			
		||||
Dockerfile
 | 
			
		||||
tgs.Dockerfile
 | 
			
		||||
							
								
								
									
										71
									
								
								.github/workflows/codeql-analysis.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								.github/workflows/codeql-analysis.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,71 @@
 | 
			
		||||
# For most projects, this workflow file will not need changing; you simply need
 | 
			
		||||
# to commit it to your repository.
 | 
			
		||||
#
 | 
			
		||||
# You may wish to alter this file to override the set of languages analyzed,
 | 
			
		||||
# or to provide custom queries or build logic.
 | 
			
		||||
name: "CodeQL"
 | 
			
		||||
 | 
			
		||||
on:
 | 
			
		||||
  push:
 | 
			
		||||
    branches: [master]
 | 
			
		||||
  pull_request:
 | 
			
		||||
    # The branches below must be a subset of the branches above
 | 
			
		||||
    branches: [master]
 | 
			
		||||
  schedule:
 | 
			
		||||
    - cron: '0 16 * * 1'
 | 
			
		||||
 | 
			
		||||
jobs:
 | 
			
		||||
  analyze:
 | 
			
		||||
    name: Analyze
 | 
			
		||||
    runs-on: ubuntu-latest
 | 
			
		||||
 | 
			
		||||
    strategy:
 | 
			
		||||
      fail-fast: false
 | 
			
		||||
      matrix:
 | 
			
		||||
        # Override automatic language detection by changing the below list
 | 
			
		||||
        # Supported options are ['csharp', 'cpp', 'go', 'java', 'javascript', 'python']
 | 
			
		||||
        language: ['go']
 | 
			
		||||
        # Learn more...
 | 
			
		||||
        # https://docs.github.com/en/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#overriding-automatic-language-detection
 | 
			
		||||
 | 
			
		||||
    steps:
 | 
			
		||||
    - name: Checkout repository
 | 
			
		||||
      uses: actions/checkout@v2
 | 
			
		||||
      with:
 | 
			
		||||
        # We must fetch at least the immediate parents so that if this is
 | 
			
		||||
        # a pull request then we can checkout the head.
 | 
			
		||||
        fetch-depth: 2
 | 
			
		||||
 | 
			
		||||
    # If this run was triggered by a pull request event, then checkout
 | 
			
		||||
    # the head of the pull request instead of the merge commit.
 | 
			
		||||
    - run: git checkout HEAD^2
 | 
			
		||||
      if: ${{ github.event_name == 'pull_request' }}
 | 
			
		||||
 | 
			
		||||
    # Initializes the CodeQL tools for scanning.
 | 
			
		||||
    - name: Initialize CodeQL
 | 
			
		||||
      uses: github/codeql-action/init@v1
 | 
			
		||||
      with:
 | 
			
		||||
        languages: ${{ matrix.language }}
 | 
			
		||||
        # If you wish to specify custom queries, you can do so here or in a config file.
 | 
			
		||||
        # By default, queries listed here will override any specified in a config file. 
 | 
			
		||||
        # Prefix the list here with "+" to use these queries and those in the config file.
 | 
			
		||||
        # queries: ./path/to/local/query, your-org/your-repo/queries@main
 | 
			
		||||
 | 
			
		||||
    # Autobuild attempts to build any compiled languages  (C/C++, C#, or Java).
 | 
			
		||||
    # If this step fails, then you should remove it and run the build manually (see below)
 | 
			
		||||
    - name: Autobuild
 | 
			
		||||
      uses: github/codeql-action/autobuild@v1
 | 
			
		||||
 | 
			
		||||
    # ℹ️ Command-line programs to run using the OS shell.
 | 
			
		||||
    # 📚 https://git.io/JvXDl
 | 
			
		||||
 | 
			
		||||
    # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
 | 
			
		||||
    #    and modify them (or add more) to build your code if your project
 | 
			
		||||
    #    uses a compiled language
 | 
			
		||||
 | 
			
		||||
    #- run: |
 | 
			
		||||
    #   make bootstrap
 | 
			
		||||
    #   make release
 | 
			
		||||
 | 
			
		||||
    - name: Perform CodeQL Analysis
 | 
			
		||||
      uses: github/codeql-action/analyze@v1
 | 
			
		||||
							
								
								
									
										57
									
								
								.github/workflows/development.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								.github/workflows/development.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,57 @@
 | 
			
		||||
name: Development
 | 
			
		||||
on: [push, pull_request]
 | 
			
		||||
jobs:
 | 
			
		||||
  lint:
 | 
			
		||||
    name: golangci-lint
 | 
			
		||||
    runs-on: ubuntu-latest
 | 
			
		||||
    steps:
 | 
			
		||||
      - uses: actions/checkout@v2
 | 
			
		||||
        with:
 | 
			
		||||
          fetch-depth: 20
 | 
			
		||||
      - name: Run golangci-lint
 | 
			
		||||
        uses: golangci/golangci-lint-action@v2
 | 
			
		||||
        with:
 | 
			
		||||
          version: v1.29
 | 
			
		||||
          args: "-v --new-from-rev HEAD~5"
 | 
			
		||||
  test-build-upload:
 | 
			
		||||
    strategy:
 | 
			
		||||
      matrix:
 | 
			
		||||
        go-version: [1.14.x, 1.15.x]
 | 
			
		||||
        platform: [ubuntu-latest]
 | 
			
		||||
    runs-on: ${{ matrix.platform }}
 | 
			
		||||
    steps:
 | 
			
		||||
    - name: Install Go
 | 
			
		||||
      uses: actions/setup-go@v2
 | 
			
		||||
      with:
 | 
			
		||||
        go-version: ${{ matrix.go-version }}
 | 
			
		||||
    - name: Checkout code
 | 
			
		||||
      uses: actions/checkout@v2
 | 
			
		||||
      with:
 | 
			
		||||
          fetch-depth: 0
 | 
			
		||||
    - name: Test
 | 
			
		||||
      run: go test ./... -mod=vendor
 | 
			
		||||
    - name: Build
 | 
			
		||||
      run: |
 | 
			
		||||
        mkdir -p output/{win,lin,arm,mac}
 | 
			
		||||
        VERSION=$(git describe --tags)
 | 
			
		||||
        GOOS=linux GOARCH=amd64 go build -mod=vendor -ldflags "-s -X main.githash=$(git log --pretty=format:'%h' -n 1)" -o output/lin/matterbridge-$VERSION-linux-amd64
 | 
			
		||||
        GOOS=windows GOARCH=amd64 go build -mod=vendor -ldflags "-s -X main.githash=$(git log --pretty=format:'%h' -n 1)" -o output/win/matterbridge-$VERSION-windows-amd64.exe
 | 
			
		||||
        GOOS=darwin GOARCH=amd64 go build -mod=vendor -ldflags "-s -X main.githash=$(git log --pretty=format:'%h' -n 1)" -o output/mac/matterbridge-$VERSION-darwin-amd64
 | 
			
		||||
    - name: Upload linux 64-bit
 | 
			
		||||
      if: startsWith(matrix.go-version,'1.15')
 | 
			
		||||
      uses: actions/upload-artifact@v2
 | 
			
		||||
      with:
 | 
			
		||||
        name: matterbridge-linux-64bit
 | 
			
		||||
        path: output/lin
 | 
			
		||||
    - name: Upload windows 64-bit
 | 
			
		||||
      if: startsWith(matrix.go-version,'1.15')
 | 
			
		||||
      uses: actions/upload-artifact@v2
 | 
			
		||||
      with:
 | 
			
		||||
        name: matterbridge-windows-64bit
 | 
			
		||||
        path: output/win
 | 
			
		||||
    - name: Upload darwin 64-bit
 | 
			
		||||
      if: startsWith(matrix.go-version,'1.15')
 | 
			
		||||
      uses: actions/upload-artifact@v2
 | 
			
		||||
      with:
 | 
			
		||||
        name: matterbridge-darwin-64bit
 | 
			
		||||
        path: output/mac
 | 
			
		||||
@@ -176,7 +176,13 @@ linters:
 | 
			
		||||
    - prealloc
 | 
			
		||||
    - wsl
 | 
			
		||||
    - gomnd
 | 
			
		||||
 | 
			
		||||
    - godox
 | 
			
		||||
    - goerr113
 | 
			
		||||
    - testpackage
 | 
			
		||||
    - godot
 | 
			
		||||
    - interfacer
 | 
			
		||||
    - goheader
 | 
			
		||||
    - noctx
 | 
			
		||||
 | 
			
		||||
# rules to deal with reported isues
 | 
			
		||||
issues:
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										56
									
								
								.travis.yml
									
									
									
									
									
								
							
							
						
						
									
										56
									
								
								.travis.yml
									
									
									
									
									
								
							@@ -1,56 +0,0 @@
 | 
			
		||||
language: go
 | 
			
		||||
go_import_path: github.com/42wim/matterbridge
 | 
			
		||||
 | 
			
		||||
# We have everything vendored so this helps TravisCI not run `go get ...`.
 | 
			
		||||
install: true
 | 
			
		||||
 | 
			
		||||
git:
 | 
			
		||||
  depth: 200
 | 
			
		||||
 | 
			
		||||
notifications:
 | 
			
		||||
  email: false
 | 
			
		||||
 | 
			
		||||
branches:
 | 
			
		||||
  only:
 | 
			
		||||
  - master
 | 
			
		||||
  - /.*/
 | 
			
		||||
 | 
			
		||||
jobs:
 | 
			
		||||
  include:
 | 
			
		||||
  - stage: lint
 | 
			
		||||
    # Run linting in one Go environment only.
 | 
			
		||||
    script: ./ci/lint.sh
 | 
			
		||||
    go: 1.14.x
 | 
			
		||||
    env:
 | 
			
		||||
    - GO111MODULE=on
 | 
			
		||||
    - GOLANGCI_VERSION="v1.23.7"
 | 
			
		||||
  - stage: test
 | 
			
		||||
    # Run tests in a combination of Go environments.
 | 
			
		||||
    script: ./ci/test.sh
 | 
			
		||||
    go: 1.13.x
 | 
			
		||||
    env:
 | 
			
		||||
    - GOFLAGS=-mod=vendor
 | 
			
		||||
  - script: ./ci/test.sh
 | 
			
		||||
    go: 1.13.x
 | 
			
		||||
    env:
 | 
			
		||||
    - GO111MODULE=on
 | 
			
		||||
  - script: ./ci/test.sh
 | 
			
		||||
    go: 1.14.x
 | 
			
		||||
    env:
 | 
			
		||||
    - GO111MODULE=on
 | 
			
		||||
    - REPORT_COVERAGE=1
 | 
			
		||||
    - BINDEPLOY=1
 | 
			
		||||
 | 
			
		||||
before_deploy: /bin/bash ci/bintray.sh
 | 
			
		||||
 | 
			
		||||
deploy:
 | 
			
		||||
  on:
 | 
			
		||||
    all_branches: true
 | 
			
		||||
    condition: $BINDEPLOY = 1
 | 
			
		||||
  provider: bintray
 | 
			
		||||
  edge:
 | 
			
		||||
    branch: v1.8.47
 | 
			
		||||
  file: ci/deploy.json
 | 
			
		||||
  user: 42wim
 | 
			
		||||
  key:
 | 
			
		||||
    secure: "CeXXe6JOmt7HYR81MdWLua0ltQHhDdkIeRGBFbgd7hkb1wi8eF9DgpAcQrTso8NIlHNZmSAP46uhFgsRvkuezzX0ygalZ7DCJyAyn3sAMEh+UQSHV1WGThRehTtidqRGjetzsIGSwdrJOWil+XTfbO1Z8DGzfakhSuAZka8CM4BAoe3YeP9rYK8h+84x0GHfczvsLtXZ3mWLvQuwe4pK6+ItBCUg0ae7O7ZUpWHy0xQQkkWztY/6RAzXfaG7DuGjIw+20fhx3WOXRNpHCtZ6Bc3qERCpk0s1HhlQWlrN9wDaFTBWYwlvSnNgvxxMbNXJ6RrRJ0l0bA7FUswYwyroxhzrGLdzWDg8dHaQkypocngdalfhpsnoO9j3ApJhomUFJ3UoEq5nOGRUrKn8MPi+dP0zE4kNQ3e4VNa1ufNrvfpWolMg3xh8OXuhQdD5wIM5zFAbRJLqWSCVAjPq4DDPecmvXBOlIial7oa312lN5qnBnUjvAcxszZ+FUyDHT1Grxzna4tMwxY9obPzZUzm7359AOCCwIQFVB8GLqD2nwIstcXS0zGRz+fhviPipHuBa02q5bGUZwmkvrSNab0s8Jo7pCrel2Rz3nWPKaiCfq2WjbW1CLheSMkOQrjsdUd1hhbqNWFPUjJPInTc77NAKCfm5runv5uyowRLh4NNd0sI="
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
FROM alpine:edge AS builder
 | 
			
		||||
FROM alpine AS builder
 | 
			
		||||
 | 
			
		||||
COPY . /go/src/github.com/42wim/matterbridge
 | 
			
		||||
RUN apk update && apk add go git gcc musl-dev \
 | 
			
		||||
@@ -7,7 +7,10 @@ RUN apk update && apk add go git gcc musl-dev \
 | 
			
		||||
        && go get \
 | 
			
		||||
        && go build -x -ldflags "-X main.githash=$(git log --pretty=format:'%h' -n 1)" -o /bin/matterbridge
 | 
			
		||||
 | 
			
		||||
FROM alpine:edge
 | 
			
		||||
FROM alpine
 | 
			
		||||
RUN apk --no-cache add ca-certificates mailcap
 | 
			
		||||
COPY --from=builder /bin/matterbridge /bin/matterbridge
 | 
			
		||||
ENTRYPOINT ["/bin/matterbridge"]
 | 
			
		||||
RUN mkdir /etc/matterbridge \
 | 
			
		||||
  && touch /etc/matterbridge/matterbridge.toml \
 | 
			
		||||
  && ln -sf /matterbridge.toml /etc/matterbridge/matterbridge.toml
 | 
			
		||||
ENTRYPOINT ["/bin/matterbridge", "-conf", "/etc/matterbridge/matterbridge.toml"]
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										73
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										73
									
								
								README.md
									
									
									
									
									
								
							@@ -29,7 +29,6 @@ And more...
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
[](https://github.com/42wim/matterbridge/releases/latest)
 | 
			
		||||
[](https://bintray.com/42wim/nightly/Matterbridge/_latestVersion)
 | 
			
		||||
[](https://codeclimate.com/github/42wim/matterbridge/maintainability)
 | 
			
		||||
[](https://codeclimate.com/github/42wim/matterbridge/test_coverage)<br />
 | 
			
		||||
 | 
			
		||||
@@ -94,6 +93,8 @@ And more...
 | 
			
		||||
- [Matrix](https://matrix.org)
 | 
			
		||||
- [Mattermost](https://github.com/mattermost/mattermost-server/) 4.x, 5.x
 | 
			
		||||
- [Microsoft Teams](https://teams.microsoft.com)
 | 
			
		||||
- [Mumble](https://www.mumble.info/)
 | 
			
		||||
- [Nextcloud Talk](https://nextcloud.com/talk/)
 | 
			
		||||
- [Rocket.chat](https://rocket.chat)
 | 
			
		||||
- [Slack](https://slack.com)
 | 
			
		||||
- [Ssh-chat](https://github.com/shazow/ssh-chat)
 | 
			
		||||
@@ -111,6 +112,7 @@ And more...
 | 
			
		||||
- [Minecraft](https://github.com/elytra/MatterLink)
 | 
			
		||||
- [Reddit](https://github.com/bonehurtingjuice/mattereddit)
 | 
			
		||||
- [Counter-Strike, half-life and more](https://forums.alliedmods.net/showthread.php?t=319430)
 | 
			
		||||
- [MatterAMXX](https://github.com/GabeIggy/MatterAMXX)
 | 
			
		||||
 | 
			
		||||
### API
 | 
			
		||||
 | 
			
		||||
@@ -145,20 +147,21 @@ Questions or want to test on your favorite platform? Join below:
 | 
			
		||||
 | 
			
		||||
## Screenshots
 | 
			
		||||
 | 
			
		||||
See https://github.com/42wim/matterbridge/wiki
 | 
			
		||||
See <https://github.com/42wim/matterbridge/wiki>
 | 
			
		||||
 | 
			
		||||
## Installing / upgrading
 | 
			
		||||
 | 
			
		||||
### Binaries
 | 
			
		||||
 | 
			
		||||
- Latest stable release [v1.17.3](https://github.com/42wim/matterbridge/releases/latest)
 | 
			
		||||
- Development releases (follows master) can be downloaded [here](https://dl.bintray.com/42wim/nightly/)
 | 
			
		||||
- Latest stable release [v1.19.0](https://github.com/42wim/matterbridge/releases/latest)
 | 
			
		||||
- Development releases (follows master) can be downloaded [here](https://github.com/42wim/matterbridge/actions) selecting the latest green build and then artifacts.
 | 
			
		||||
 | 
			
		||||
To install or upgrade just download the latest [binary](https://github.com/42wim/matterbridge/releases/latest) and follow the instructions on the [howto](https://github.com/42wim/matterbridge/wiki/How-to-create-your-config) for a step by step walkthrough for creating your configuration.
 | 
			
		||||
 | 
			
		||||
### Packages
 | 
			
		||||
 | 
			
		||||
- [Overview](https://repology.org/metapackage/matterbridge/versions)
 | 
			
		||||
- [snap](https://snapcraft.io/matterbridge)
 | 
			
		||||
 | 
			
		||||
## Building
 | 
			
		||||
 | 
			
		||||
@@ -167,14 +170,13 @@ Most people just want to use binaries, you can find those [here](https://github.
 | 
			
		||||
If you really want to build from source, follow these instructions:
 | 
			
		||||
Go 1.12+ is required. Make sure you have [Go](https://golang.org/doc/install) properly installed.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
```bash
 | 
			
		||||
go get github.com/42wim/matterbridge
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
You should now have matterbridge binary in the ~/go/bin directory:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
```bash
 | 
			
		||||
$ ls ~/go/bin/
 | 
			
		||||
matterbridge
 | 
			
		||||
```
 | 
			
		||||
@@ -257,7 +259,7 @@ RemoteNickFormat="[{PROTOCOL}/{BRIDGE}] <{NICK}> "
 | 
			
		||||
 | 
			
		||||
See [howto](https://github.com/42wim/matterbridge/wiki/How-to-create-your-config) for a step by step walkthrough for creating your configuration.
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
```bash
 | 
			
		||||
Usage of ./matterbridge:
 | 
			
		||||
  -conf string
 | 
			
		||||
        config file (default "matterbridge.toml")
 | 
			
		||||
@@ -298,14 +300,14 @@ See [FAQ](https://github.com/42wim/matterbridge/wiki/FAQ)
 | 
			
		||||
## Articles
 | 
			
		||||
 | 
			
		||||
- [matterbridge on kubernetes](https://medium.freecodecamp.org/using-kubernetes-to-deploy-a-chat-gateway-or-when-technology-works-like-its-supposed-to-a169a8cd69a3)
 | 
			
		||||
- https://mattermost.com/blog/connect-irc-to-mattermost/
 | 
			
		||||
- https://blog.valvin.fr/2016/09/17/mattermost-et-un-channel-irc-cest-possible/
 | 
			
		||||
- https://blog.brightscout.com/top-10-mattermost-integrations/
 | 
			
		||||
- http://bencey.co.nz/2018/09/17/bridge/
 | 
			
		||||
- https://www.algoo.fr/blog/2018/01/19/recouvrez-votre-liberte-en-quittant-slack-pour-un-mattermost-auto-heberge/
 | 
			
		||||
- https://kopano.com/blog/matterbridge-bridging-mattermost-chat/
 | 
			
		||||
- https://www.stitcher.com/s/?eid=52382713
 | 
			
		||||
- https://daniele.tech/2019/02/how-to-use-matterbridge-to-connect-2-different-slack-workspaces/
 | 
			
		||||
- <https://mattermost.com/blog/connect-irc-to-mattermost/>
 | 
			
		||||
- <https://blog.valvin.fr/2016/09/17/mattermost-et-un-channel-irc-cest-possible/>
 | 
			
		||||
- <https://blog.brightscout.com/top-10-mattermost-integrations/>
 | 
			
		||||
- <https://www.algoo.fr/blog/2018/01/19/recouvrez-votre-liberte-en-quittant-slack-pour-un-mattermost-auto-heberge/>
 | 
			
		||||
- <https://kopano.com/blog/matterbridge-bridging-mattermost-chat/>
 | 
			
		||||
- <https://www.stitcher.com/s/?eid=52382713>
 | 
			
		||||
- <https://daniele.tech/2019/02/how-to-use-matterbridge-to-connect-2-different-slack-workspaces/>
 | 
			
		||||
- <https://userlinux.net/mattermost-and-matterbridge.html>
 | 
			
		||||
 | 
			
		||||
## Thanks
 | 
			
		||||
 | 
			
		||||
@@ -318,24 +320,27 @@ See [FAQ](https://github.com/42wim/matterbridge/wiki/FAQ)
 | 
			
		||||
 | 
			
		||||
Matterbridge wouldn't exist without these libraries:
 | 
			
		||||
 | 
			
		||||
- discord - https://github.com/bwmarrin/discordgo
 | 
			
		||||
- echo - https://github.com/labstack/echo
 | 
			
		||||
- gitter - https://github.com/sromku/go-gitter
 | 
			
		||||
- gops - https://github.com/google/gops
 | 
			
		||||
- gozulipbot - https://github.com/ifo/gozulipbot
 | 
			
		||||
- irc - https://github.com/lrstanley/girc
 | 
			
		||||
- keybase - https://github.com/keybase/go-keybase-chat-bot
 | 
			
		||||
- matrix - https://github.com/matrix-org/gomatrix
 | 
			
		||||
- mattermost - https://github.com/mattermost/mattermost-server
 | 
			
		||||
- msgraph.go - https://github.com/yaegashi/msgraph.go
 | 
			
		||||
- slack - https://github.com/nlopes/slack
 | 
			
		||||
- sshchat - https://github.com/shazow/ssh-chat
 | 
			
		||||
- steam - https://github.com/Philipp15b/go-steam
 | 
			
		||||
- telegram - https://github.com/go-telegram-bot-api/telegram-bot-api
 | 
			
		||||
- tengo - https://github.com/d5/tengo
 | 
			
		||||
- whatsapp - https://github.com/Rhymen/go-whatsapp/
 | 
			
		||||
- xmpp - https://github.com/mattn/go-xmpp
 | 
			
		||||
- zulip - https://github.com/ifo/gozulipbot
 | 
			
		||||
- discord - <https://github.com/bwmarrin/discordgo>
 | 
			
		||||
- echo - <https://github.com/labstack/echo>
 | 
			
		||||
- gitter - <https://github.com/sromku/go-gitter>
 | 
			
		||||
- gops - <https://github.com/google/gops>
 | 
			
		||||
- gozulipbot - <https://github.com/ifo/gozulipbot>
 | 
			
		||||
- gumble - <https://github.com/layeh/gumble>
 | 
			
		||||
- irc - <https://github.com/lrstanley/girc>
 | 
			
		||||
- keybase - <https://github.com/keybase/go-keybase-chat-bot>
 | 
			
		||||
- matrix - <https://github.com/matrix-org/gomatrix>
 | 
			
		||||
- mattermost - <https://github.com/mattermost/mattermost-server>
 | 
			
		||||
- msgraph.go - <https://github.com/yaegashi/msgraph.go>
 | 
			
		||||
- mumble - <https://github.com/layeh/gumble>
 | 
			
		||||
- nctalk - <https://github.com/gary-kim/go-nc-talk>
 | 
			
		||||
- slack - <https://github.com/nlopes/slack>
 | 
			
		||||
- sshchat - <https://github.com/shazow/ssh-chat>
 | 
			
		||||
- steam - <https://github.com/Philipp15b/go-steam>
 | 
			
		||||
- telegram - <https://github.com/go-telegram-bot-api/telegram-bot-api>
 | 
			
		||||
- tengo - <https://github.com/d5/tengo>
 | 
			
		||||
- whatsapp - <https://github.com/Rhymen/go-whatsapp>
 | 
			
		||||
- xmpp - <https://github.com/mattn/go-xmpp>
 | 
			
		||||
- zulip - <https://github.com/ifo/gozulipbot>
 | 
			
		||||
 | 
			
		||||
<!-- Links -->
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -6,17 +6,20 @@ import (
 | 
			
		||||
	"sync"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"gopkg.in/olahol/melody.v1"
 | 
			
		||||
 | 
			
		||||
	"github.com/42wim/matterbridge/bridge"
 | 
			
		||||
	"github.com/42wim/matterbridge/bridge/config"
 | 
			
		||||
	"github.com/labstack/echo/v4"
 | 
			
		||||
	"github.com/labstack/echo/v4/middleware"
 | 
			
		||||
	"github.com/zfjagann/golang-ring"
 | 
			
		||||
	ring "github.com/zfjagann/golang-ring"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type API struct {
 | 
			
		||||
	Messages ring.Ring
 | 
			
		||||
	sync.RWMutex
 | 
			
		||||
	*bridge.Config
 | 
			
		||||
	mrouter *melody.Melody
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type Message struct {
 | 
			
		||||
@@ -32,6 +35,32 @@ func New(cfg *bridge.Config) bridge.Bridger {
 | 
			
		||||
	e := echo.New()
 | 
			
		||||
	e.HideBanner = true
 | 
			
		||||
	e.HidePort = true
 | 
			
		||||
 | 
			
		||||
	b.mrouter = melody.New()
 | 
			
		||||
	b.mrouter.HandleMessage(func(s *melody.Session, msg []byte) {
 | 
			
		||||
		message := config.Message{}
 | 
			
		||||
		err := json.Unmarshal(msg, &message)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			b.Log.Errorf("failed to decode message from byte[] '%s'", string(msg))
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
		b.handleWebsocketMessage(message, s)
 | 
			
		||||
	})
 | 
			
		||||
	b.mrouter.HandleConnect(func(session *melody.Session) {
 | 
			
		||||
		greet := b.getGreeting()
 | 
			
		||||
		data, err := json.Marshal(greet)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			b.Log.Errorf("failed to encode message '%v'", greet)
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
		err = session.Write(data)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			b.Log.Errorf("failed to write message '%s'", string(data))
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
		// TODO: send message history buffer from `b.Messages` here
 | 
			
		||||
	})
 | 
			
		||||
 | 
			
		||||
	b.Messages = ring.Ring{}
 | 
			
		||||
	if b.GetInt("Buffer") != 0 {
 | 
			
		||||
		b.Messages.SetCapacity(b.GetInt("Buffer"))
 | 
			
		||||
@@ -41,9 +70,17 @@ func New(cfg *bridge.Config) bridge.Bridger {
 | 
			
		||||
			return key == b.GetString("Token"), nil
 | 
			
		||||
		}))
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Set RemoteNickFormat to a sane default
 | 
			
		||||
	if !b.IsKeySet("RemoteNickFormat") {
 | 
			
		||||
		b.Log.Debugln("RemoteNickFormat is unset, defaulting to \"{NICK}\"")
 | 
			
		||||
		b.Config.Config.Viper().Set(b.GetConfigKey("RemoteNickFormat"), "{NICK}")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	e.GET("/api/health", b.handleHealthcheck)
 | 
			
		||||
	e.GET("/api/messages", b.handleMessages)
 | 
			
		||||
	e.GET("/api/stream", b.handleStream)
 | 
			
		||||
	e.GET("/api/websocket", b.handleWebsocket)
 | 
			
		||||
	e.POST("/api/message", b.handlePostMessage)
 | 
			
		||||
	go func() {
 | 
			
		||||
		if b.GetString("BindAddress") == "" {
 | 
			
		||||
@@ -58,13 +95,13 @@ func New(cfg *bridge.Config) bridge.Bridger {
 | 
			
		||||
func (b *API) Connect() error {
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (b *API) Disconnect() error {
 | 
			
		||||
	return nil
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (b *API) JoinChannel(channel config.ChannelInfo) error {
 | 
			
		||||
	return nil
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (b *API) Send(msg config.Message) (string, error) {
 | 
			
		||||
@@ -74,7 +111,14 @@ func (b *API) Send(msg config.Message) (string, error) {
 | 
			
		||||
	if msg.Event == config.EventMsgDelete {
 | 
			
		||||
		return "", nil
 | 
			
		||||
	}
 | 
			
		||||
	b.Messages.Enqueue(&msg)
 | 
			
		||||
	b.Log.Debugf("enqueueing message from %s on ring buffer", msg.Username)
 | 
			
		||||
	b.Messages.Enqueue(msg)
 | 
			
		||||
 | 
			
		||||
	data, err := json.Marshal(msg)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		b.Log.Errorf("failed to encode message  '%s'", msg)
 | 
			
		||||
	}
 | 
			
		||||
	_ = b.mrouter.Broadcast(data)
 | 
			
		||||
	return "", nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -106,18 +150,23 @@ func (b *API) handleMessages(c echo.Context) error {
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (b *API) handleStream(c echo.Context) error {
 | 
			
		||||
	c.Response().Header().Set(echo.HeaderContentType, echo.MIMEApplicationJSON)
 | 
			
		||||
	c.Response().WriteHeader(http.StatusOK)
 | 
			
		||||
	greet := config.Message{
 | 
			
		||||
func (b *API) getGreeting() config.Message {
 | 
			
		||||
	return config.Message{
 | 
			
		||||
		Event:     config.EventAPIConnected,
 | 
			
		||||
		Timestamp: time.Now(),
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (b *API) handleStream(c echo.Context) error {
 | 
			
		||||
	c.Response().Header().Set(echo.HeaderContentType, echo.MIMEApplicationJSON)
 | 
			
		||||
	c.Response().WriteHeader(http.StatusOK)
 | 
			
		||||
	greet := b.getGreeting()
 | 
			
		||||
	if err := json.NewEncoder(c.Response()).Encode(greet); err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	c.Response().Flush()
 | 
			
		||||
	for {
 | 
			
		||||
		// TODO: this causes issues, messages should be broadcasted to all connected clients
 | 
			
		||||
		msg := b.Messages.Dequeue()
 | 
			
		||||
		if msg != nil {
 | 
			
		||||
			if err := json.NewEncoder(c.Response()).Encode(msg); err != nil {
 | 
			
		||||
@@ -128,3 +177,31 @@ func (b *API) handleStream(c echo.Context) error {
 | 
			
		||||
		time.Sleep(200 * time.Millisecond)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (b *API) handleWebsocketMessage(message config.Message, s *melody.Session) {
 | 
			
		||||
	message.Channel = "api"
 | 
			
		||||
	message.Protocol = "api"
 | 
			
		||||
	message.Account = b.Account
 | 
			
		||||
	message.ID = ""
 | 
			
		||||
	message.Timestamp = time.Now()
 | 
			
		||||
 | 
			
		||||
	data, err := json.Marshal(message)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		b.Log.Errorf("failed to encode message for loopback '%v'", message)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	_ = b.mrouter.BroadcastOthers(data, s)
 | 
			
		||||
 | 
			
		||||
	b.Log.Debugf("Sending websocket message from %s on %s to gateway", message.Username, "api")
 | 
			
		||||
	b.Remote <- message
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (b *API) handleWebsocket(c echo.Context) error {
 | 
			
		||||
	err := b.mrouter.HandleRequest(c.Response(), c.Request())
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		b.Log.Errorf("error in websocket handling  '%v'", err)
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -86,8 +86,16 @@ func (b *Bridge) joinChannels(channels map[string]config.ChannelInfo, exists map
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (b *Bridge) GetConfigKey(key string) string {
 | 
			
		||||
	return b.Account + "." + key
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (b *Bridge) IsKeySet(key string) bool {
 | 
			
		||||
	return b.Config.IsKeySet(b.GetConfigKey(key)) || b.Config.IsKeySet("general."+key)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (b *Bridge) GetBool(key string) bool {
 | 
			
		||||
	val, ok := b.Config.GetBool(b.Account + "." + key)
 | 
			
		||||
	val, ok := b.Config.GetBool(b.GetConfigKey(key))
 | 
			
		||||
	if !ok {
 | 
			
		||||
		val, _ = b.Config.GetBool("general." + key)
 | 
			
		||||
	}
 | 
			
		||||
@@ -95,7 +103,7 @@ func (b *Bridge) GetBool(key string) bool {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (b *Bridge) GetInt(key string) int {
 | 
			
		||||
	val, ok := b.Config.GetInt(b.Account + "." + key)
 | 
			
		||||
	val, ok := b.Config.GetInt(b.GetConfigKey(key))
 | 
			
		||||
	if !ok {
 | 
			
		||||
		val, _ = b.Config.GetInt("general." + key)
 | 
			
		||||
	}
 | 
			
		||||
@@ -103,7 +111,7 @@ func (b *Bridge) GetInt(key string) int {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (b *Bridge) GetString(key string) string {
 | 
			
		||||
	val, ok := b.Config.GetString(b.Account + "." + key)
 | 
			
		||||
	val, ok := b.Config.GetString(b.GetConfigKey(key))
 | 
			
		||||
	if !ok {
 | 
			
		||||
		val, _ = b.Config.GetString("general." + key)
 | 
			
		||||
	}
 | 
			
		||||
@@ -111,7 +119,7 @@ func (b *Bridge) GetString(key string) string {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (b *Bridge) GetStringSlice(key string) []string {
 | 
			
		||||
	val, ok := b.Config.GetStringSlice(b.Account + "." + key)
 | 
			
		||||
	val, ok := b.Config.GetStringSlice(b.GetConfigKey(key))
 | 
			
		||||
	if !ok {
 | 
			
		||||
		val, _ = b.Config.GetStringSlice("general." + key)
 | 
			
		||||
	}
 | 
			
		||||
@@ -119,7 +127,7 @@ func (b *Bridge) GetStringSlice(key string) []string {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (b *Bridge) GetStringSlice2D(key string) [][]string {
 | 
			
		||||
	val, ok := b.Config.GetStringSlice2D(b.Account + "." + key)
 | 
			
		||||
	val, ok := b.Config.GetStringSlice2D(b.GetConfigKey(key))
 | 
			
		||||
	if !ok {
 | 
			
		||||
		val, _ = b.Config.GetStringSlice2D("general." + key)
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
@@ -3,6 +3,7 @@ package config
 | 
			
		||||
import (
 | 
			
		||||
	"bytes"
 | 
			
		||||
	"io/ioutil"
 | 
			
		||||
	"os"
 | 
			
		||||
	"path/filepath"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"sync"
 | 
			
		||||
@@ -84,6 +85,7 @@ type Protocol struct {
 | 
			
		||||
	DisableWebPagePreview  bool   // telegram
 | 
			
		||||
	EditSuffix             string // mattermost, slack, discord, telegram, gitter
 | 
			
		||||
	EditDisable            bool   // mattermost, slack, discord, telegram, gitter
 | 
			
		||||
	HTMLDisable            bool   // matrix
 | 
			
		||||
	IconURL                string // mattermost, slack
 | 
			
		||||
	IgnoreFailureOnStart   bool   // general
 | 
			
		||||
	IgnoreNicks            string // all protocols
 | 
			
		||||
@@ -92,11 +94,13 @@ type Protocol struct {
 | 
			
		||||
	JoinDelay              string // all protocols
 | 
			
		||||
	Label                  string // all protocols
 | 
			
		||||
	Login                  string // mattermost, matrix
 | 
			
		||||
	LogFile                string // general
 | 
			
		||||
	MediaDownloadBlackList []string
 | 
			
		||||
	MediaDownloadPath      string // Basically MediaServerUpload, but instead of uploading it, just write it to a file on the same server.
 | 
			
		||||
	MediaDownloadSize      int    // all protocols
 | 
			
		||||
	MediaServerDownload    string
 | 
			
		||||
	MediaServerUpload      string
 | 
			
		||||
	MediaConvertTgs        string     // telegram
 | 
			
		||||
	MediaConvertWebPToPNG  bool       // telegram
 | 
			
		||||
	MessageDelay           int        // IRC, time in millisecond to wait between messages
 | 
			
		||||
	MessageFormat          string     // telegram
 | 
			
		||||
@@ -135,6 +139,7 @@ type Protocol struct {
 | 
			
		||||
	SkipTLSVerify          bool       // IRC, mattermost
 | 
			
		||||
	SkipVersionCheck       bool       // mattermost
 | 
			
		||||
	StripNick              bool       // all protocols
 | 
			
		||||
	StripMarkdown          bool       // irc
 | 
			
		||||
	SyncTopic              bool       // slack
 | 
			
		||||
	TengoModifyMessage     string     // general
 | 
			
		||||
	Team                   string     // mattermost, keybase
 | 
			
		||||
@@ -208,6 +213,7 @@ type BridgeValues struct {
 | 
			
		||||
	WhatsApp           map[string]Protocol // TODO is this struct used? Search for "SlackLegacy" for example didn't return any results
 | 
			
		||||
	Zulip              map[string]Protocol
 | 
			
		||||
	Keybase            map[string]Protocol
 | 
			
		||||
	Mumble             map[string]Protocol
 | 
			
		||||
	General            Protocol
 | 
			
		||||
	Tengo              Tengo
 | 
			
		||||
	Gateway            []Gateway
 | 
			
		||||
@@ -217,6 +223,7 @@ type BridgeValues struct {
 | 
			
		||||
type Config interface {
 | 
			
		||||
	Viper() *viper.Viper
 | 
			
		||||
	BridgeValues() *BridgeValues
 | 
			
		||||
	IsKeySet(key string) bool
 | 
			
		||||
	GetBool(key string) (bool, bool)
 | 
			
		||||
	GetInt(key string) (int, bool)
 | 
			
		||||
	GetString(key string) (string, bool)
 | 
			
		||||
@@ -244,6 +251,15 @@ func NewConfig(rootLogger *logrus.Logger, cfgfile string) Config {
 | 
			
		||||
 | 
			
		||||
	cfgtype := detectConfigType(cfgfile)
 | 
			
		||||
	mycfg := newConfigFromString(logger, input, cfgtype)
 | 
			
		||||
	if mycfg.cv.General.LogFile != "" {
 | 
			
		||||
		logfile, err := os.OpenFile(mycfg.cv.General.LogFile, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0600)
 | 
			
		||||
		if err == nil {
 | 
			
		||||
			logger.Info("Opening log file ", mycfg.cv.General.LogFile)
 | 
			
		||||
			rootLogger.Out = logfile
 | 
			
		||||
		} else {
 | 
			
		||||
			logger.Warn("Failed to open ", mycfg.cv.General.LogFile)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if mycfg.cv.General.MediaDownloadSize == 0 {
 | 
			
		||||
		mycfg.cv.General.MediaDownloadSize = 1000000
 | 
			
		||||
	}
 | 
			
		||||
@@ -301,6 +317,12 @@ func (c *config) Viper() *viper.Viper {
 | 
			
		||||
	return c.v
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *config) IsKeySet(key string) bool {
 | 
			
		||||
	c.RLock()
 | 
			
		||||
	defer c.RUnlock()
 | 
			
		||||
	return c.v.IsSet(key)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *config) GetBool(key string) (bool, bool) {
 | 
			
		||||
	c.RLock()
 | 
			
		||||
	defer c.RUnlock()
 | 
			
		||||
@@ -360,6 +382,11 @@ type TestConfig struct {
 | 
			
		||||
	Overrides map[string]interface{}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *TestConfig) IsKeySet(key string) bool {
 | 
			
		||||
	_, ok := c.Overrides[key]
 | 
			
		||||
	return ok || c.Config.IsKeySet(key)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *TestConfig) GetBool(key string) (bool, bool) {
 | 
			
		||||
	val, ok := c.Overrides[key]
 | 
			
		||||
	if ok {
 | 
			
		||||
 
 | 
			
		||||
@@ -34,6 +34,8 @@ type Bdiscord struct {
 | 
			
		||||
	membersMutex  sync.RWMutex
 | 
			
		||||
	userMemberMap map[string]*discordgo.Member
 | 
			
		||||
	nickMemberMap map[string]*discordgo.Member
 | 
			
		||||
	webhookCache  map[string]string
 | 
			
		||||
	webhookMutex  sync.RWMutex
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func New(cfg *bridge.Config) bridge.Bridger {
 | 
			
		||||
@@ -41,6 +43,7 @@ func New(cfg *bridge.Config) bridge.Bridger {
 | 
			
		||||
	b.userMemberMap = make(map[string]*discordgo.Member)
 | 
			
		||||
	b.nickMemberMap = make(map[string]*discordgo.Member)
 | 
			
		||||
	b.channelInfoMap = make(map[string]*config.ChannelInfo)
 | 
			
		||||
	b.webhookCache = make(map[string]string)
 | 
			
		||||
	if b.GetString("WebhookURL") != "" {
 | 
			
		||||
		b.Log.Debug("Configuring Discord Incoming Webhook")
 | 
			
		||||
		b.webhookID, b.webhookToken = b.splitURL(b.GetString("WebhookURL"))
 | 
			
		||||
@@ -188,6 +191,8 @@ func (b *Bdiscord) JoinChannel(channel config.ChannelInfo) error {
 | 
			
		||||
func (b *Bdiscord) Send(msg config.Message) (string, error) {
 | 
			
		||||
	b.Log.Debugf("=> Receiving %#v", msg)
 | 
			
		||||
 | 
			
		||||
	origMsgID := msg.ID
 | 
			
		||||
 | 
			
		||||
	channelID := b.getChannelID(msg.Channel)
 | 
			
		||||
	if channelID == "" {
 | 
			
		||||
		return "", fmt.Errorf("Could not find channelID for %v", msg.Channel)
 | 
			
		||||
@@ -224,12 +229,13 @@ func (b *Bdiscord) Send(msg config.Message) (string, error) {
 | 
			
		||||
	// Use webhook to send the message
 | 
			
		||||
	if wID != "" && msg.Event != config.EventMsgDelete {
 | 
			
		||||
		// skip events
 | 
			
		||||
		if msg.Event != "" && msg.Event != config.EventJoinLeave && msg.Event != config.EventTopicChange {
 | 
			
		||||
		if msg.Event != "" && msg.Event != config.EventUserAction && msg.Event != config.EventJoinLeave && msg.Event != config.EventTopicChange {
 | 
			
		||||
			return "", nil
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// If we are editing a message, delete the old message
 | 
			
		||||
		if msg.ID != "" {
 | 
			
		||||
			msg.ID = b.getCacheID(msg.ID)
 | 
			
		||||
			b.Log.Debugf("Deleting edited webhook message")
 | 
			
		||||
			err := b.c.ChannelMessageDelete(channelID, msg.ID)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
@@ -273,6 +279,8 @@ func (b *Bdiscord) Send(msg config.Message) (string, error) {
 | 
			
		||||
		if msg == nil {
 | 
			
		||||
			return "", nil
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		b.updateCacheID(origMsgID, msg.ID)
 | 
			
		||||
		return msg.ID, nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -283,6 +291,7 @@ func (b *Bdiscord) Send(msg config.Message) (string, error) {
 | 
			
		||||
		if msg.ID == "" {
 | 
			
		||||
			return "", nil
 | 
			
		||||
		}
 | 
			
		||||
		msg.ID = b.getCacheID(msg.ID)
 | 
			
		||||
		err := b.c.ChannelMessageDelete(channelID, msg.ID)
 | 
			
		||||
		return "", err
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
@@ -217,7 +217,7 @@ func handleEmbed(embed *discordgo.MessageEmbed) string {
 | 
			
		||||
 | 
			
		||||
		i++
 | 
			
		||||
		if i == 1 {
 | 
			
		||||
			result += "embed: " + e
 | 
			
		||||
			result += " embed: " + e
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -20,14 +20,14 @@ func TestHandleEmbed(t *testing.T) {
 | 
			
		||||
			embed: &discordgo.MessageEmbed{
 | 
			
		||||
				Title: "blah",
 | 
			
		||||
			},
 | 
			
		||||
			result: "embed: blah\n",
 | 
			
		||||
			result: " embed: blah\n",
 | 
			
		||||
		},
 | 
			
		||||
		"two": {
 | 
			
		||||
			embed: &discordgo.MessageEmbed{
 | 
			
		||||
				Title:       "blah",
 | 
			
		||||
				Description: "blah2",
 | 
			
		||||
			},
 | 
			
		||||
			result: "embed: blah - blah2\n",
 | 
			
		||||
			result: " embed: blah - blah2\n",
 | 
			
		||||
		},
 | 
			
		||||
		"three": {
 | 
			
		||||
			embed: &discordgo.MessageEmbed{
 | 
			
		||||
@@ -35,20 +35,20 @@ func TestHandleEmbed(t *testing.T) {
 | 
			
		||||
				Description: "blah2",
 | 
			
		||||
				URL:         "blah3",
 | 
			
		||||
			},
 | 
			
		||||
			result: "embed: blah - blah2 - blah3\n",
 | 
			
		||||
			result: " embed: blah - blah2 - blah3\n",
 | 
			
		||||
		},
 | 
			
		||||
		"twob": {
 | 
			
		||||
			embed: &discordgo.MessageEmbed{
 | 
			
		||||
				Description: "blah2",
 | 
			
		||||
				URL:         "blah3",
 | 
			
		||||
			},
 | 
			
		||||
			result: "embed: blah2 - blah3\n",
 | 
			
		||||
			result: " embed: blah2 - blah3\n",
 | 
			
		||||
		},
 | 
			
		||||
		"oneb": {
 | 
			
		||||
			embed: &discordgo.MessageEmbed{
 | 
			
		||||
				URL: "blah3",
 | 
			
		||||
			},
 | 
			
		||||
			result: "embed: blah3\n",
 | 
			
		||||
			result: " embed: blah3\n",
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -188,8 +188,9 @@ func replaceEmotes(text string) string {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (b *Bdiscord) replaceAction(text string) (string, bool) {
 | 
			
		||||
	if strings.HasPrefix(text, "_") && strings.HasSuffix(text, "_") {
 | 
			
		||||
		return text[1 : len(text)-1], true
 | 
			
		||||
	length := len(text)
 | 
			
		||||
	if length > 1 && text[0] == '_' && text[length-1] == '_' {
 | 
			
		||||
		return text[1 : length-1], true
 | 
			
		||||
	}
 | 
			
		||||
	return text, false
 | 
			
		||||
}
 | 
			
		||||
@@ -208,6 +209,40 @@ func (b *Bdiscord) splitURL(url string) (string, string) {
 | 
			
		||||
	return webhookURLSplit[webhookIdxID], webhookURLSplit[webhookIdxToken]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// getcacheID tries to find a corresponding msgID in the webhook cache.
 | 
			
		||||
// if not found returns the original request.
 | 
			
		||||
func (b *Bdiscord) getCacheID(msgID string) string {
 | 
			
		||||
	b.webhookMutex.RLock()
 | 
			
		||||
	defer b.webhookMutex.RUnlock()
 | 
			
		||||
	for k, v := range b.webhookCache {
 | 
			
		||||
		if msgID == k {
 | 
			
		||||
			return v
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return msgID
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// updateCacheID updates the cache so that the newID takes the place of
 | 
			
		||||
// the original ID. This is used for edit/deletes in combination with webhooks
 | 
			
		||||
// as editing a message via webhook means deleting the message and creating a
 | 
			
		||||
// new message (with a new ID). This ID needs to be set instead of the original ID
 | 
			
		||||
func (b *Bdiscord) updateCacheID(origID, newID string) {
 | 
			
		||||
	b.webhookMutex.Lock()
 | 
			
		||||
	match := false
 | 
			
		||||
	for k, v := range b.webhookCache {
 | 
			
		||||
		if v == origID {
 | 
			
		||||
			delete(b.webhookCache, k)
 | 
			
		||||
			b.webhookCache[origID] = newID
 | 
			
		||||
			match = true
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if !match && origID != "" {
 | 
			
		||||
		b.webhookCache[origID] = newID
 | 
			
		||||
	}
 | 
			
		||||
	b.webhookMutex.Unlock()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func enumerateUsernames(s string) []string {
 | 
			
		||||
	onlySpace := true
 | 
			
		||||
	for _, r := range s {
 | 
			
		||||
 
 | 
			
		||||
@@ -5,7 +5,10 @@ import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"image/png"
 | 
			
		||||
	"io"
 | 
			
		||||
	"io/ioutil"
 | 
			
		||||
	"net/http"
 | 
			
		||||
	"os"
 | 
			
		||||
	"os/exec"
 | 
			
		||||
	"regexp"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"time"
 | 
			
		||||
@@ -192,7 +195,7 @@ func ParseMarkdown(input string) string {
 | 
			
		||||
	return res
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ConvertWebPToPNG convert input data (which should be WebP format to PNG format)
 | 
			
		||||
// ConvertWebPToPNG converts input data (which should be WebP format) to PNG format
 | 
			
		||||
func ConvertWebPToPNG(data *[]byte) error {
 | 
			
		||||
	r := bytes.NewReader(*data)
 | 
			
		||||
	m, err := webp.Decode(r)
 | 
			
		||||
@@ -207,3 +210,49 @@ func ConvertWebPToPNG(data *[]byte) error {
 | 
			
		||||
	*data = w.Bytes()
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// CanConvertTgsToX Checks whether the external command necessary for ConvertTgsToX works.
 | 
			
		||||
func CanConvertTgsToX() error {
 | 
			
		||||
	// We depend on the fact that `lottie_convert.py --help` has exit status 0.
 | 
			
		||||
	// Hyrum's Law predicted this, and Murphy's Law predicts that this will break eventually.
 | 
			
		||||
	// However, there is no alternative like `lottie_convert.py --is-properly-installed`
 | 
			
		||||
	cmd := exec.Command("lottie_convert.py", "--help")
 | 
			
		||||
	return cmd.Run()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ConvertTgsToWebP convert input data (which should be tgs format) to WebP format
 | 
			
		||||
// This relies on an external command, which is ugly, but works.
 | 
			
		||||
func ConvertTgsToX(data *[]byte, outputFormat string, logger *logrus.Entry) error {
 | 
			
		||||
	// lottie can't handle input from a pipe, so write to a temporary file:
 | 
			
		||||
	tmpFile, err := ioutil.TempFile(os.TempDir(), "matterbridge-lottie-*.tgs")
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	tmpFileName := tmpFile.Name()
 | 
			
		||||
	defer func() {
 | 
			
		||||
		if removeErr := os.Remove(tmpFileName); removeErr != nil {
 | 
			
		||||
			logger.Errorf("Could not delete temporary file %s: %v", tmpFileName, removeErr)
 | 
			
		||||
		}
 | 
			
		||||
	}()
 | 
			
		||||
 | 
			
		||||
	if _, writeErr := tmpFile.Write(*data); writeErr != nil {
 | 
			
		||||
		return writeErr
 | 
			
		||||
	}
 | 
			
		||||
	// Must close before calling lottie to avoid data races:
 | 
			
		||||
	if closeErr := tmpFile.Close(); closeErr != nil {
 | 
			
		||||
		return closeErr
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Call lottie to transform:
 | 
			
		||||
	cmd := exec.Command("lottie_convert.py", "--input-format", "lottie", "--output-format", outputFormat, tmpFileName, "/dev/stdout")
 | 
			
		||||
	cmd.Stderr = nil
 | 
			
		||||
	// NB: lottie writes progress into to stderr in all cases.
 | 
			
		||||
	stdout, stderr := cmd.Output()
 | 
			
		||||
	if stderr != nil {
 | 
			
		||||
		// 'stderr' already contains some parts of Stderr, because it was set to 'nil'.
 | 
			
		||||
		return stderr
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	*data = stdout
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -10,8 +10,8 @@ import (
 | 
			
		||||
 | 
			
		||||
	"github.com/42wim/matterbridge/bridge/config"
 | 
			
		||||
	"github.com/42wim/matterbridge/bridge/helper"
 | 
			
		||||
	"github.com/dfordsoft/golib/ic"
 | 
			
		||||
	"github.com/lrstanley/girc"
 | 
			
		||||
	"github.com/missdeer/golib/ic"
 | 
			
		||||
	"github.com/paulrosania/go-charset/charset"
 | 
			
		||||
	"github.com/saintfish/chardet"
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -4,6 +4,7 @@ import (
 | 
			
		||||
	"crypto/tls"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"hash/crc32"
 | 
			
		||||
	"io/ioutil"
 | 
			
		||||
	"net"
 | 
			
		||||
	"sort"
 | 
			
		||||
	"strconv"
 | 
			
		||||
@@ -14,6 +15,7 @@ import (
 | 
			
		||||
	"github.com/42wim/matterbridge/bridge/config"
 | 
			
		||||
	"github.com/42wim/matterbridge/bridge/helper"
 | 
			
		||||
	"github.com/lrstanley/girc"
 | 
			
		||||
	stripmd "github.com/writeas/go-strip-markdown"
 | 
			
		||||
 | 
			
		||||
	// We need to import the 'data' package as an implicit dependency.
 | 
			
		||||
	// See: https://godoc.org/github.com/paulrosania/go-charset/charset
 | 
			
		||||
@@ -156,6 +158,10 @@ func (b *Birc) Send(msg config.Message) (string, error) {
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var msgLines []string
 | 
			
		||||
	if b.GetBool("StripMarkdown") {
 | 
			
		||||
		msg.Text = stripmd.Strip(msg.Text)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if b.GetBool("MessageSplit") {
 | 
			
		||||
		msgLines = helper.GetSubLines(msg.Text, b.MessageLength)
 | 
			
		||||
	} else {
 | 
			
		||||
@@ -201,7 +207,7 @@ func (b *Birc) doSend() {
 | 
			
		||||
	for msg := range b.Local {
 | 
			
		||||
		<-throttle.C
 | 
			
		||||
		username := msg.Username
 | 
			
		||||
		if b.GetBool("Colornicks") {
 | 
			
		||||
		if b.GetBool("Colornicks") && len(username) > 1 {
 | 
			
		||||
			checksum := crc32.ChecksumIEEE([]byte(msg.Username))
 | 
			
		||||
			colorCode := checksum%14 + 2 // quick fix - prevent white or black color codes
 | 
			
		||||
			username = fmt.Sprintf("\x03%02d%s\x0F", colorCode, msg.Username)
 | 
			
		||||
@@ -235,6 +241,11 @@ func (b *Birc) getClient() (*girc.Client, error) {
 | 
			
		||||
		user = user[1:]
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	debug := ioutil.Discard
 | 
			
		||||
	if b.GetInt("DebugLevel") == 2 {
 | 
			
		||||
		debug = b.Log.Writer()
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	i := girc.New(girc.Config{
 | 
			
		||||
		Server:     server,
 | 
			
		||||
		ServerPass: b.GetString("Password"),
 | 
			
		||||
@@ -245,6 +256,9 @@ func (b *Birc) getClient() (*girc.Client, error) {
 | 
			
		||||
		SSL:        b.GetBool("UseTLS"),
 | 
			
		||||
		TLSConfig:  &tls.Config{InsecureSkipVerify: b.GetBool("SkipTLSVerify"), ServerName: server}, //nolint:gosec
 | 
			
		||||
		PingDelay:  time.Minute,
 | 
			
		||||
		// skip gIRC internal rate limiting, since we have our own throttling
 | 
			
		||||
		AllowFlood: true,
 | 
			
		||||
		Debug:      debug,
 | 
			
		||||
	})
 | 
			
		||||
	return i, nil
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -2,17 +2,24 @@ package bmatrix
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"bytes"
 | 
			
		||||
	"encoding/json"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"html"
 | 
			
		||||
	"mime"
 | 
			
		||||
	"regexp"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"sync"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"github.com/42wim/matterbridge/bridge"
 | 
			
		||||
	"github.com/42wim/matterbridge/bridge/config"
 | 
			
		||||
	"github.com/42wim/matterbridge/bridge/helper"
 | 
			
		||||
	matrix "github.com/matterbridge/gomatrix"
 | 
			
		||||
	matrix "github.com/matrix-org/gomatrix"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	htmlTag            = regexp.MustCompile("</.*?>")
 | 
			
		||||
	htmlReplacementTag = regexp.MustCompile("<[^>]*>")
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type Bmatrix struct {
 | 
			
		||||
@@ -20,13 +27,38 @@ type Bmatrix struct {
 | 
			
		||||
	UserID  string
 | 
			
		||||
	RoomMap map[string]string
 | 
			
		||||
	sync.RWMutex
 | 
			
		||||
	htmlTag *regexp.Regexp
 | 
			
		||||
	*bridge.Config
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type httpError struct {
 | 
			
		||||
	Errcode      string `json:"errcode"`
 | 
			
		||||
	Err          string `json:"error"`
 | 
			
		||||
	RetryAfterMs int    `json:"retry_after_ms"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type matrixUsername struct {
 | 
			
		||||
	plain     string
 | 
			
		||||
	formatted string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func newMatrixUsername(username string) *matrixUsername {
 | 
			
		||||
	mUsername := new(matrixUsername)
 | 
			
		||||
 | 
			
		||||
	// check if we have a </tag>. if we have, we don't escape HTML. #696
 | 
			
		||||
	if htmlTag.MatchString(username) {
 | 
			
		||||
		mUsername.formatted = username
 | 
			
		||||
		// remove the HTML formatting for beautiful push messages #1188
 | 
			
		||||
		mUsername.plain = htmlReplacementTag.ReplaceAllString(username, "")
 | 
			
		||||
	} else {
 | 
			
		||||
		mUsername.formatted = html.EscapeString(username)
 | 
			
		||||
		mUsername.plain = username
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return mUsername
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func New(cfg *bridge.Config) bridge.Bridger {
 | 
			
		||||
	b := &Bmatrix{Config: cfg}
 | 
			
		||||
	b.htmlTag = regexp.MustCompile("</.*?>")
 | 
			
		||||
	b.RoomMap = make(map[string]string)
 | 
			
		||||
	return b
 | 
			
		||||
}
 | 
			
		||||
@@ -39,9 +71,10 @@ func (b *Bmatrix) Connect() error {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	resp, err := b.mc.Login(&matrix.ReqLogin{
 | 
			
		||||
		Type:     "m.login.password",
 | 
			
		||||
		User:     b.GetString("Login"),
 | 
			
		||||
		Password: b.GetString("Password"),
 | 
			
		||||
		Type:       "m.login.password",
 | 
			
		||||
		User:       b.GetString("Login"),
 | 
			
		||||
		Password:   b.GetString("Password"),
 | 
			
		||||
		Identifier: matrix.NewUserIdentifier(b.GetString("Login")),
 | 
			
		||||
	})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
@@ -58,14 +91,25 @@ func (b *Bmatrix) Disconnect() error {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (b *Bmatrix) JoinChannel(channel config.ChannelInfo) error {
 | 
			
		||||
retry:
 | 
			
		||||
	resp, err := b.mc.JoinRoom(channel.Name, "", nil)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		httpErr := handleError(err)
 | 
			
		||||
		if httpErr.Errcode == "M_LIMIT_EXCEEDED" {
 | 
			
		||||
			b.Log.Infof("getting ratelimited by matrix, sleeping approx %d seconds before joining %s", httpErr.RetryAfterMs/1000, channel.Name)
 | 
			
		||||
			time.Sleep((time.Duration(httpErr.RetryAfterMs) * time.Millisecond))
 | 
			
		||||
 | 
			
		||||
			goto retry
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	b.Lock()
 | 
			
		||||
	b.RoomMap[resp.RoomID] = channel.Name
 | 
			
		||||
	b.Unlock()
 | 
			
		||||
	return err
 | 
			
		||||
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (b *Bmatrix) Send(msg config.Message) (string, error) {
 | 
			
		||||
@@ -74,11 +118,14 @@ func (b *Bmatrix) Send(msg config.Message) (string, error) {
 | 
			
		||||
	channel := b.getRoomID(msg.Channel)
 | 
			
		||||
	b.Log.Debugf("Channel %s maps to channel id %s", msg.Channel, channel)
 | 
			
		||||
 | 
			
		||||
	username := newMatrixUsername(msg.Username)
 | 
			
		||||
 | 
			
		||||
	// Make a action /me of the message
 | 
			
		||||
	if msg.Event == config.EventUserAction {
 | 
			
		||||
		m := matrix.TextMessage{
 | 
			
		||||
			MsgType: "m.emote",
 | 
			
		||||
			Body:    msg.Username + msg.Text,
 | 
			
		||||
			MsgType:       "m.emote",
 | 
			
		||||
			Body:          username.plain + msg.Text,
 | 
			
		||||
			FormattedBody: username.formatted + msg.Text,
 | 
			
		||||
		}
 | 
			
		||||
		resp, err := b.mc.SendMessageEvent(channel, "m.room.message", m)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
@@ -117,20 +164,28 @@ func (b *Bmatrix) Send(msg config.Message) (string, error) {
 | 
			
		||||
 | 
			
		||||
	// Use notices to send join/leave events
 | 
			
		||||
	if msg.Event == config.EventJoinLeave {
 | 
			
		||||
		resp, err := b.mc.SendNotice(channel, msg.Username+msg.Text)
 | 
			
		||||
		m := matrix.TextMessage{
 | 
			
		||||
			MsgType:       "m.notice",
 | 
			
		||||
			Body:          username.plain + msg.Text,
 | 
			
		||||
			FormattedBody: username.formatted + msg.Text,
 | 
			
		||||
		}
 | 
			
		||||
		resp, err := b.mc.SendMessageEvent(channel, "m.room.message", m)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return "", err
 | 
			
		||||
		}
 | 
			
		||||
		return resp.EventID, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	username := html.EscapeString(msg.Username)
 | 
			
		||||
	// check if we have a </tag>. if we have, we don't escape HTML. #696
 | 
			
		||||
	if b.htmlTag.MatchString(msg.Username) {
 | 
			
		||||
		username = msg.Username
 | 
			
		||||
	if b.GetBool("HTMLDisable") {
 | 
			
		||||
		resp, err := b.mc.SendText(channel, username.plain+msg.Text)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return "", err
 | 
			
		||||
		}
 | 
			
		||||
		return resp.EventID, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Post normal message with HTML support (eg riot.im)
 | 
			
		||||
	resp, err := b.mc.SendHTML(channel, msg.Username+msg.Text, username+helper.ParseMarkdown(msg.Text))
 | 
			
		||||
	resp, err := b.mc.SendFormattedText(channel, username.plain+msg.Text, username.formatted+helper.ParseMarkdown(msg.Text))
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return "", err
 | 
			
		||||
	}
 | 
			
		||||
@@ -293,25 +348,16 @@ func (b *Bmatrix) handleUploadFiles(msg *config.Message, channel string) (string
 | 
			
		||||
 | 
			
		||||
// handleUploadFile handles native upload of a file.
 | 
			
		||||
func (b *Bmatrix) handleUploadFile(msg *config.Message, channel string, fi *config.FileInfo) {
 | 
			
		||||
	username := newMatrixUsername(msg.Username)
 | 
			
		||||
	content := bytes.NewReader(*fi.Data)
 | 
			
		||||
	sp := strings.Split(fi.Name, ".")
 | 
			
		||||
	mtype := mime.TypeByExtension("." + sp[len(sp)-1])
 | 
			
		||||
	if !(strings.Contains(mtype, "image") || strings.Contains(mtype, "video") ||
 | 
			
		||||
		strings.Contains(mtype, "application") || strings.Contains(mtype, "audio")) {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	if fi.Comment != "" {
 | 
			
		||||
		_, err := b.mc.SendText(channel, msg.Username+fi.Comment)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			b.Log.Errorf("file comment failed: %#v", err)
 | 
			
		||||
		}
 | 
			
		||||
	} else {
 | 
			
		||||
		// image and video uploads send no username, we have to do this ourself here #715
 | 
			
		||||
		_, err := b.mc.SendText(channel, msg.Username)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			b.Log.Errorf("file comment failed: %#v", err)
 | 
			
		||||
		}
 | 
			
		||||
	// image and video uploads send no username, we have to do this ourself here #715
 | 
			
		||||
	_, err := b.mc.SendFormattedText(channel, username.plain+fi.Comment, username.formatted+fi.Comment)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		b.Log.Errorf("file comment failed: %#v", err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	b.Log.Debugf("uploading file: %s %s", fi.Name, mtype)
 | 
			
		||||
	res, err := b.mc.UploadToContentRepo(content, mtype, int64(len(*fi.Data)))
 | 
			
		||||
	if err != nil {
 | 
			
		||||
@@ -332,18 +378,34 @@ func (b *Bmatrix) handleUploadFile(msg *config.Message, channel string, fi *conf
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			b.Log.Errorf("sendImage failed: %#v", err)
 | 
			
		||||
		}
 | 
			
		||||
	case strings.Contains(mtype, "application"):
 | 
			
		||||
		b.Log.Debugf("sendFile %s", res.ContentURI)
 | 
			
		||||
		_, err = b.mc.SendFile(channel, fi.Name, res.ContentURI, mtype, uint(len(*fi.Data)))
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			b.Log.Errorf("sendFile failed: %#v", err)
 | 
			
		||||
		}
 | 
			
		||||
	case strings.Contains(mtype, "audio"):
 | 
			
		||||
		b.Log.Debugf("sendAudio %s", res.ContentURI)
 | 
			
		||||
		_, err = b.mc.SendAudio(channel, fi.Name, res.ContentURI, mtype, uint(len(*fi.Data)))
 | 
			
		||||
		_, err = b.mc.SendMessageEvent(channel, "m.room.message", matrix.AudioMessage{
 | 
			
		||||
			MsgType: "m.audio",
 | 
			
		||||
			Body:    fi.Name,
 | 
			
		||||
			URL:     res.ContentURI,
 | 
			
		||||
			Info: matrix.AudioInfo{
 | 
			
		||||
				Mimetype: mtype,
 | 
			
		||||
				Size:     uint(len(*fi.Data)),
 | 
			
		||||
			},
 | 
			
		||||
		})
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			b.Log.Errorf("sendAudio failed: %#v", err)
 | 
			
		||||
		}
 | 
			
		||||
	default:
 | 
			
		||||
		b.Log.Debugf("sendFile %s", res.ContentURI)
 | 
			
		||||
		_, err = b.mc.SendMessageEvent(channel, "m.room.message", matrix.FileMessage{
 | 
			
		||||
			MsgType: "m.file",
 | 
			
		||||
			Body:    fi.Name,
 | 
			
		||||
			URL:     res.ContentURI,
 | 
			
		||||
			Info: matrix.FileInfo{
 | 
			
		||||
				Mimetype: mtype,
 | 
			
		||||
				Size:     uint(len(*fi.Data)),
 | 
			
		||||
			},
 | 
			
		||||
		})
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			b.Log.Errorf("sendFile failed: %#v", err)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	b.Log.Debugf("result: %#v", res)
 | 
			
		||||
}
 | 
			
		||||
@@ -366,12 +428,39 @@ func (b *Bmatrix) containsAttachment(content map[string]interface{}) bool {
 | 
			
		||||
 | 
			
		||||
// getAvatarURL returns the avatar URL of the specified sender
 | 
			
		||||
func (b *Bmatrix) getAvatarURL(sender string) string {
 | 
			
		||||
	mxcURL, err := b.mc.GetSenderAvatarURL(sender)
 | 
			
		||||
	urlPath := b.mc.BuildURL("profile", sender, "avatar_url")
 | 
			
		||||
 | 
			
		||||
	s := struct {
 | 
			
		||||
		AvatarURL string `json:"avatar_url"`
 | 
			
		||||
	}{}
 | 
			
		||||
 | 
			
		||||
	err := b.mc.MakeRequest("GET", urlPath, nil, &s)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		b.Log.Errorf("getAvatarURL failed: %s", err)
 | 
			
		||||
		return ""
 | 
			
		||||
	}
 | 
			
		||||
	url := strings.ReplaceAll(mxcURL, "mxc://", b.GetString("Server")+"/_matrix/media/r0/thumbnail/")
 | 
			
		||||
	url += "?width=37&height=37&method=crop"
 | 
			
		||||
	url := strings.ReplaceAll(s.AvatarURL, "mxc://", b.GetString("Server")+"/_matrix/media/r0/thumbnail/")
 | 
			
		||||
	if url != "" {
 | 
			
		||||
		url += "?width=37&height=37&method=crop"
 | 
			
		||||
	}
 | 
			
		||||
	return url
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func handleError(err error) *httpError {
 | 
			
		||||
	mErr, ok := err.(matrix.HTTPError)
 | 
			
		||||
	if !ok {
 | 
			
		||||
		return &httpError{
 | 
			
		||||
			Err: "not a HTTPError",
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var httpErr httpError
 | 
			
		||||
 | 
			
		||||
	if err := json.Unmarshal(mErr.Contents, &httpErr); err != nil {
 | 
			
		||||
		return &httpError{
 | 
			
		||||
			Err: "unmarshal failed",
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return &httpErr
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										28
									
								
								bridge/matrix/matrix_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								bridge/matrix/matrix_test.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,28 @@
 | 
			
		||||
package bmatrix
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"testing"
 | 
			
		||||
 | 
			
		||||
	"github.com/stretchr/testify/assert"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func TestPlainUsername(t *testing.T) {
 | 
			
		||||
	uut := newMatrixUsername("MyUser")
 | 
			
		||||
 | 
			
		||||
	assert.Equal(t, "MyUser", uut.formatted)
 | 
			
		||||
	assert.Equal(t, "MyUser", uut.plain)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestHTMLUsername(t *testing.T) {
 | 
			
		||||
	uut := newMatrixUsername("<b>MyUser</b>")
 | 
			
		||||
 | 
			
		||||
	assert.Equal(t, "<b>MyUser</b>", uut.formatted)
 | 
			
		||||
	assert.Equal(t, "MyUser", uut.plain)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestFancyUsername(t *testing.T) {
 | 
			
		||||
	uut := newMatrixUsername("<MyUser>")
 | 
			
		||||
 | 
			
		||||
	assert.Equal(t, "<MyUser>", uut.formatted)
 | 
			
		||||
	assert.Equal(t, "<MyUser>", uut.plain)
 | 
			
		||||
}
 | 
			
		||||
@@ -4,7 +4,7 @@ import (
 | 
			
		||||
	"github.com/42wim/matterbridge/bridge/config"
 | 
			
		||||
	"github.com/42wim/matterbridge/bridge/helper"
 | 
			
		||||
	"github.com/42wim/matterbridge/matterclient"
 | 
			
		||||
	"github.com/mattermost/mattermost-server/model"
 | 
			
		||||
	"github.com/mattermost/mattermost-server/v5/model"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// handleDownloadAvatar downloads the avatar of userid from channel
 | 
			
		||||
 
 | 
			
		||||
@@ -7,7 +7,7 @@ import (
 | 
			
		||||
	"github.com/42wim/matterbridge/bridge/helper"
 | 
			
		||||
	"github.com/42wim/matterbridge/matterclient"
 | 
			
		||||
	"github.com/42wim/matterbridge/matterhook"
 | 
			
		||||
	"github.com/mattermost/mattermost-server/model"
 | 
			
		||||
	"github.com/mattermost/mattermost-server/v5/model"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func (b *Bmattermost) doConnectWebhookBind() error {
 | 
			
		||||
 
 | 
			
		||||
@@ -10,6 +10,7 @@ import (
 | 
			
		||||
 | 
			
		||||
	"github.com/42wim/matterbridge/bridge"
 | 
			
		||||
	"github.com/42wim/matterbridge/bridge/config"
 | 
			
		||||
	"github.com/davecgh/go-spew/spew"
 | 
			
		||||
 | 
			
		||||
	"github.com/mattn/godown"
 | 
			
		||||
	msgraph "github.com/yaegashi/msgraph.go/beta"
 | 
			
		||||
@@ -71,7 +72,15 @@ func (b *Bmsteams) Disconnect() error {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (b *Bmsteams) JoinChannel(channel config.ChannelInfo) error {
 | 
			
		||||
	go b.poll(channel.Name)
 | 
			
		||||
	go func(name string) {
 | 
			
		||||
		for {
 | 
			
		||||
			err := b.poll(name)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				b.Log.Errorf("polling failed for %s: %s. retrying in 5 seconds", name, err)
 | 
			
		||||
			}
 | 
			
		||||
			time.Sleep(time.Second * 5)
 | 
			
		||||
		}
 | 
			
		||||
	}(channel.Name)
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -120,12 +129,12 @@ func (b *Bmsteams) getMessages(channel string) ([]msgraph.ChatMessage, error) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//nolint:gocognit
 | 
			
		||||
func (b *Bmsteams) poll(channelName string) {
 | 
			
		||||
func (b *Bmsteams) poll(channelName string) error {
 | 
			
		||||
	msgmap := make(map[string]time.Time)
 | 
			
		||||
	b.Log.Debug("getting initial messages")
 | 
			
		||||
	res, err := b.getMessages(channelName)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		panic(err)
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	for _, msg := range res {
 | 
			
		||||
		msgmap[*msg.ID] = *msg.CreatedDateTime
 | 
			
		||||
@@ -138,7 +147,7 @@ func (b *Bmsteams) poll(channelName string) {
 | 
			
		||||
	for {
 | 
			
		||||
		res, err := b.getMessages(channelName)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			panic(err)
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
		for i := len(res) - 1; i >= 0; i-- {
 | 
			
		||||
			msg := res[i]
 | 
			
		||||
@@ -150,11 +159,22 @@ func (b *Bmsteams) poll(channelName string) {
 | 
			
		||||
					continue
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if b.GetBool("debug") {
 | 
			
		||||
				b.Log.Debug("Msg dump: ", spew.Sdump(msg))
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			// skip non-user message for now.
 | 
			
		||||
			if msg.From.User == nil {
 | 
			
		||||
				continue
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if *msg.From.User.ID == b.botID {
 | 
			
		||||
				b.Log.Debug("skipping own message")
 | 
			
		||||
				msgmap[*msg.ID] = *msg.CreatedDateTime
 | 
			
		||||
				continue
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			msgmap[*msg.ID] = *msg.CreatedDateTime
 | 
			
		||||
			if msg.LastModifiedDateTime != nil {
 | 
			
		||||
				msgmap[*msg.ID] = *msg.LastModifiedDateTime
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										90
									
								
								bridge/mumble/handlers.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										90
									
								
								bridge/mumble/handlers.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,90 @@
 | 
			
		||||
package bmumble
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"strconv"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"layeh.com/gumble/gumble"
 | 
			
		||||
 | 
			
		||||
	"github.com/42wim/matterbridge/bridge/config"
 | 
			
		||||
	"github.com/42wim/matterbridge/bridge/helper"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func (b *Bmumble) handleServerConfig(event *gumble.ServerConfigEvent) {
 | 
			
		||||
	b.serverConfigUpdate <- *event
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (b *Bmumble) handleTextMessage(event *gumble.TextMessageEvent) {
 | 
			
		||||
	sender := "unknown"
 | 
			
		||||
	if event.TextMessage.Sender != nil {
 | 
			
		||||
		sender = event.TextMessage.Sender.Name
 | 
			
		||||
	}
 | 
			
		||||
	// Convert Mumble HTML messages to markdown
 | 
			
		||||
	parts, err := b.convertHTMLtoMarkdown(event.TextMessage.Message)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		b.Log.Error(err)
 | 
			
		||||
	}
 | 
			
		||||
	now := time.Now().UTC()
 | 
			
		||||
	for i, part := range parts {
 | 
			
		||||
		// Construct matterbridge message and pass on to the gateway
 | 
			
		||||
		rmsg := config.Message{
 | 
			
		||||
			Channel:  strconv.FormatUint(uint64(event.Client.Self.Channel.ID), 10),
 | 
			
		||||
			Username: sender,
 | 
			
		||||
			UserID:   sender + "@" + b.Host,
 | 
			
		||||
			Account:  b.Account,
 | 
			
		||||
		}
 | 
			
		||||
		if part.Image == nil {
 | 
			
		||||
			rmsg.Text = part.Text
 | 
			
		||||
		} else {
 | 
			
		||||
			fname := b.Account + "_" + strconv.FormatInt(now.UnixNano(), 10) + "_" + strconv.Itoa(i) + part.FileExtension
 | 
			
		||||
			rmsg.Extra = make(map[string][]interface{})
 | 
			
		||||
			if err = helper.HandleDownloadSize(b.Log, &rmsg, fname, int64(len(part.Image)), b.General); err != nil {
 | 
			
		||||
				b.Log.WithError(err).Warn("not including image in message")
 | 
			
		||||
				continue
 | 
			
		||||
			}
 | 
			
		||||
			helper.HandleDownloadData(b.Log, &rmsg, fname, "", "", &part.Image, b.General)
 | 
			
		||||
		}
 | 
			
		||||
		b.Log.Debugf("Sending message to gateway: %+v", rmsg)
 | 
			
		||||
		b.Remote <- rmsg
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (b *Bmumble) handleConnect(event *gumble.ConnectEvent) {
 | 
			
		||||
	// Set the user's "bio"/comment
 | 
			
		||||
	if comment := b.GetString("UserComment"); comment != "" && event.Client.Self != nil {
 | 
			
		||||
		event.Client.Self.SetComment(comment)
 | 
			
		||||
	}
 | 
			
		||||
	// No need to talk or listen
 | 
			
		||||
	event.Client.Self.SetSelfDeafened(true)
 | 
			
		||||
	event.Client.Self.SetSelfMuted(true)
 | 
			
		||||
	// if the Channel variable is set, this is a reconnect -> rejoin channel
 | 
			
		||||
	if b.Channel != nil {
 | 
			
		||||
		if err := b.doJoin(event.Client, *b.Channel); err != nil {
 | 
			
		||||
			b.Log.Error(err)
 | 
			
		||||
		}
 | 
			
		||||
		b.Remote <- config.Message{
 | 
			
		||||
			Username: "system",
 | 
			
		||||
			Text:     "rejoin",
 | 
			
		||||
			Channel:  "",
 | 
			
		||||
			Account:  b.Account,
 | 
			
		||||
			Event:    config.EventRejoinChannels,
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (b *Bmumble) handleUserChange(event *gumble.UserChangeEvent) {
 | 
			
		||||
	// Only care about changes to self
 | 
			
		||||
	if event.User != event.Client.Self {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	// Someone attempted to move the user out of the configured channel; attempt to join back
 | 
			
		||||
	if b.Channel != nil {
 | 
			
		||||
		if err := b.doJoin(event.Client, *b.Channel); err != nil {
 | 
			
		||||
			b.Log.Error(err)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (b *Bmumble) handleDisconnect(event *gumble.DisconnectEvent) {
 | 
			
		||||
	b.connected <- *event
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										143
									
								
								bridge/mumble/helpers.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										143
									
								
								bridge/mumble/helpers.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,143 @@
 | 
			
		||||
package bmumble
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"mime"
 | 
			
		||||
	"net/http"
 | 
			
		||||
	"regexp"
 | 
			
		||||
	"strings"
 | 
			
		||||
 | 
			
		||||
	"github.com/42wim/matterbridge/bridge/config"
 | 
			
		||||
	"github.com/mattn/godown"
 | 
			
		||||
	"github.com/vincent-petithory/dataurl"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type MessagePart struct {
 | 
			
		||||
	Text          string
 | 
			
		||||
	FileExtension string
 | 
			
		||||
	Image         []byte
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (b *Bmumble) decodeImage(uri string, parts *[]MessagePart) error {
 | 
			
		||||
	// Decode the data:image/... URI
 | 
			
		||||
	image, err := dataurl.DecodeString(uri)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		b.Log.WithError(err).Info("No image extracted")
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	// Determine the file extensions for that image
 | 
			
		||||
	ext, err := mime.ExtensionsByType(image.MediaType.ContentType())
 | 
			
		||||
	if err != nil || len(ext) == 0 {
 | 
			
		||||
		b.Log.WithError(err).Infof("No file extension registered for MIME type '%s'", image.MediaType.ContentType())
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	// Add the image to the MessagePart slice
 | 
			
		||||
	*parts = append(*parts, MessagePart{"", ext[0], image.Data})
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (b *Bmumble) tokenize(t *string) ([]MessagePart, error) {
 | 
			
		||||
	// `^(.*?)` matches everything before the image
 | 
			
		||||
	// `!\[[^\]]*\]\(` matches the `]+)` matches the data: URI used by Mumble
 | 
			
		||||
	// `\)` matches the closing parenthesis after the URI
 | 
			
		||||
	// `(.*)$` matches the remaining text to be examined in the next iteration
 | 
			
		||||
	p := regexp.MustCompile(`^(?ms)(.*?)!\[[^\]]*\]\((data:image\/[^)]+)\)(.*)$`)
 | 
			
		||||
	remaining := *t
 | 
			
		||||
	var parts []MessagePart
 | 
			
		||||
	for {
 | 
			
		||||
		tokens := p.FindStringSubmatch(remaining)
 | 
			
		||||
		if tokens == nil {
 | 
			
		||||
			// no match -> remaining string is non-image text
 | 
			
		||||
			pre := strings.TrimSpace(remaining)
 | 
			
		||||
			if len(pre) > 0 {
 | 
			
		||||
				parts = append(parts, MessagePart{pre, "", nil})
 | 
			
		||||
			}
 | 
			
		||||
			return parts, nil
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// tokens[1] is the text before the image
 | 
			
		||||
		if len(tokens[1]) > 0 {
 | 
			
		||||
			pre := strings.TrimSpace(tokens[1])
 | 
			
		||||
			parts = append(parts, MessagePart{pre, "", nil})
 | 
			
		||||
		}
 | 
			
		||||
		// tokens[2] is the image URL
 | 
			
		||||
		uri, err := dataurl.UnescapeToString(strings.TrimSpace(strings.ReplaceAll(tokens[2], " ", "")))
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			b.Log.WithError(err).Info("URL unescaping failed")
 | 
			
		||||
			remaining = strings.TrimSpace(tokens[3])
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		err = b.decodeImage(uri, &parts)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			b.Log.WithError(err).Info("Decoding the image failed")
 | 
			
		||||
		}
 | 
			
		||||
		// tokens[3] is the text after the image, processed in the next iteration
 | 
			
		||||
		remaining = strings.TrimSpace(tokens[3])
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (b *Bmumble) convertHTMLtoMarkdown(html string) ([]MessagePart, error) {
 | 
			
		||||
	var sb strings.Builder
 | 
			
		||||
	err := godown.Convert(&sb, strings.NewReader(html), nil)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	markdown := sb.String()
 | 
			
		||||
	b.Log.Debugf("### to markdown: %s", markdown)
 | 
			
		||||
	return b.tokenize(&markdown)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (b *Bmumble) extractFiles(msg *config.Message) []config.Message {
 | 
			
		||||
	var messages []config.Message
 | 
			
		||||
	if msg.Extra == nil || len(msg.Extra["file"]) == 0 {
 | 
			
		||||
		return messages
 | 
			
		||||
	}
 | 
			
		||||
	// Create a separate message for each file
 | 
			
		||||
	for _, f := range msg.Extra["file"] {
 | 
			
		||||
		fi := f.(config.FileInfo)
 | 
			
		||||
		imsg := config.Message{
 | 
			
		||||
			Channel:   msg.Channel,
 | 
			
		||||
			Username:  msg.Username,
 | 
			
		||||
			UserID:    msg.UserID,
 | 
			
		||||
			Account:   msg.Account,
 | 
			
		||||
			Protocol:  msg.Protocol,
 | 
			
		||||
			Timestamp: msg.Timestamp,
 | 
			
		||||
			Event:     "mumble_image",
 | 
			
		||||
		}
 | 
			
		||||
		// If no data is present for the file, send a link instead
 | 
			
		||||
		if fi.Data == nil || len(*fi.Data) == 0 {
 | 
			
		||||
			if len(fi.URL) > 0 {
 | 
			
		||||
				imsg.Text = fmt.Sprintf(`<a href="%s">%s</a>`, fi.URL, fi.URL)
 | 
			
		||||
				messages = append(messages, imsg)
 | 
			
		||||
			} else {
 | 
			
		||||
				b.Log.Infof("Not forwarding file without local data")
 | 
			
		||||
			}
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		mimeType := http.DetectContentType(*fi.Data)
 | 
			
		||||
		// Mumble only supports images natively, send a link instead
 | 
			
		||||
		if !strings.HasPrefix(mimeType, "image/") {
 | 
			
		||||
			if len(fi.URL) > 0 {
 | 
			
		||||
				imsg.Text = fmt.Sprintf(`<a href="%s">%s</a>`, fi.URL, fi.URL)
 | 
			
		||||
				messages = append(messages, imsg)
 | 
			
		||||
			} else {
 | 
			
		||||
				b.Log.Infof("Not forwarding file of type %s", mimeType)
 | 
			
		||||
			}
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		mimeType = strings.TrimSpace(strings.Split(mimeType, ";")[0])
 | 
			
		||||
		// Build data:image/...;base64,... style image URL and embed image directly into the message
 | 
			
		||||
		du := dataurl.New(*fi.Data, mimeType)
 | 
			
		||||
		dataURL, err := du.MarshalText()
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			b.Log.WithError(err).Infof("Image Serialization into data URL failed (type: %s, length: %d)", mimeType, len(*fi.Data))
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		imsg.Text = fmt.Sprintf(`<img src="%s"/>`, dataURL)
 | 
			
		||||
		messages = append(messages, imsg)
 | 
			
		||||
	}
 | 
			
		||||
	// Remove files from original message
 | 
			
		||||
	msg.Extra["file"] = nil
 | 
			
		||||
	return messages
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										259
									
								
								bridge/mumble/mumble.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										259
									
								
								bridge/mumble/mumble.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,259 @@
 | 
			
		||||
package bmumble
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"crypto/tls"
 | 
			
		||||
	"crypto/x509"
 | 
			
		||||
	"errors"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"io/ioutil"
 | 
			
		||||
	"net"
 | 
			
		||||
	"strconv"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"layeh.com/gumble/gumble"
 | 
			
		||||
	"layeh.com/gumble/gumbleutil"
 | 
			
		||||
 | 
			
		||||
	"github.com/42wim/matterbridge/bridge"
 | 
			
		||||
	"github.com/42wim/matterbridge/bridge/config"
 | 
			
		||||
	"github.com/42wim/matterbridge/bridge/helper"
 | 
			
		||||
	stripmd "github.com/writeas/go-strip-markdown"
 | 
			
		||||
 | 
			
		||||
	// We need to import the 'data' package as an implicit dependency.
 | 
			
		||||
	// See: https://godoc.org/github.com/paulrosania/go-charset/charset
 | 
			
		||||
	_ "github.com/paulrosania/go-charset/data"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type Bmumble struct {
 | 
			
		||||
	client             *gumble.Client
 | 
			
		||||
	Nick               string
 | 
			
		||||
	Host               string
 | 
			
		||||
	Channel            *uint32
 | 
			
		||||
	local              chan config.Message
 | 
			
		||||
	running            chan error
 | 
			
		||||
	connected          chan gumble.DisconnectEvent
 | 
			
		||||
	serverConfigUpdate chan gumble.ServerConfigEvent
 | 
			
		||||
	serverConfig       gumble.ServerConfigEvent
 | 
			
		||||
	tlsConfig          tls.Config
 | 
			
		||||
 | 
			
		||||
	*bridge.Config
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func New(cfg *bridge.Config) bridge.Bridger {
 | 
			
		||||
	b := &Bmumble{}
 | 
			
		||||
	b.Config = cfg
 | 
			
		||||
	b.Nick = b.GetString("Nick")
 | 
			
		||||
	b.local = make(chan config.Message)
 | 
			
		||||
	b.running = make(chan error)
 | 
			
		||||
	b.connected = make(chan gumble.DisconnectEvent)
 | 
			
		||||
	b.serverConfigUpdate = make(chan gumble.ServerConfigEvent)
 | 
			
		||||
	return b
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (b *Bmumble) Connect() error {
 | 
			
		||||
	b.Log.Infof("Connecting %s", b.GetString("Server"))
 | 
			
		||||
	host, portstr, err := net.SplitHostPort(b.GetString("Server"))
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	b.Host = host
 | 
			
		||||
	_, err = strconv.Atoi(portstr)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if err = b.buildTLSConfig(); err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	go b.doSend()
 | 
			
		||||
	go b.connectLoop()
 | 
			
		||||
	err = <-b.running
 | 
			
		||||
	return err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (b *Bmumble) Disconnect() error {
 | 
			
		||||
	return b.client.Disconnect()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (b *Bmumble) JoinChannel(channel config.ChannelInfo) error {
 | 
			
		||||
	cid, err := strconv.ParseUint(channel.Name, 10, 32)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	channelID := uint32(cid)
 | 
			
		||||
	if b.Channel != nil && *b.Channel != channelID {
 | 
			
		||||
		b.Log.Fatalf("Cannot join channel ID '%d', already joined to channel ID %d", channelID, *b.Channel)
 | 
			
		||||
		return errors.New("the Mumble bridge can only join a single channel")
 | 
			
		||||
	}
 | 
			
		||||
	b.Channel = &channelID
 | 
			
		||||
	return b.doJoin(b.client, channelID)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (b *Bmumble) Send(msg config.Message) (string, error) {
 | 
			
		||||
	// Only process text messages
 | 
			
		||||
	b.Log.Debugf("=> Received local message %#v", msg)
 | 
			
		||||
	if msg.Event != "" && msg.Event != config.EventUserAction {
 | 
			
		||||
		return "", nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	attachments := b.extractFiles(&msg)
 | 
			
		||||
	b.local <- msg
 | 
			
		||||
	for _, a := range attachments {
 | 
			
		||||
		b.local <- a
 | 
			
		||||
	}
 | 
			
		||||
	return "", nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (b *Bmumble) buildTLSConfig() error {
 | 
			
		||||
	b.tlsConfig = tls.Config{}
 | 
			
		||||
	// Load TLS client certificate keypair required for registered user authentication
 | 
			
		||||
	if cpath := b.GetString("TLSClientCertificate"); cpath != "" {
 | 
			
		||||
		if ckey := b.GetString("TLSClientKey"); ckey != "" {
 | 
			
		||||
			cert, err := tls.LoadX509KeyPair(cpath, ckey)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				return err
 | 
			
		||||
			}
 | 
			
		||||
			b.tlsConfig.Certificates = []tls.Certificate{cert}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	// Load TLS CA used for server verification.  If not provided, the Go system trust anchor is used
 | 
			
		||||
	if capath := b.GetString("TLSCACertificate"); capath != "" {
 | 
			
		||||
		ca, err := ioutil.ReadFile(capath)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
		b.tlsConfig.RootCAs = x509.NewCertPool()
 | 
			
		||||
		b.tlsConfig.RootCAs.AppendCertsFromPEM(ca)
 | 
			
		||||
	}
 | 
			
		||||
	b.tlsConfig.InsecureSkipVerify = b.GetBool("SkipTLSVerify")
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (b *Bmumble) connectLoop() {
 | 
			
		||||
	firstConnect := true
 | 
			
		||||
	for {
 | 
			
		||||
		err := b.doConnect()
 | 
			
		||||
		if firstConnect {
 | 
			
		||||
			b.running <- err
 | 
			
		||||
		}
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			b.Log.Errorf("Connection to server failed: %#v", err)
 | 
			
		||||
			if firstConnect {
 | 
			
		||||
				break
 | 
			
		||||
			} else {
 | 
			
		||||
				b.Log.Info("Retrying in 10s")
 | 
			
		||||
				time.Sleep(10 * time.Second)
 | 
			
		||||
				continue
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		firstConnect = false
 | 
			
		||||
		d := <-b.connected
 | 
			
		||||
		switch d.Type {
 | 
			
		||||
		case gumble.DisconnectError:
 | 
			
		||||
			b.Log.Errorf("Lost connection to the server (%s), attempting reconnect", d.String)
 | 
			
		||||
			continue
 | 
			
		||||
		case gumble.DisconnectKicked:
 | 
			
		||||
			b.Log.Errorf("Kicked from the server (%s), attempting reconnect", d.String)
 | 
			
		||||
			continue
 | 
			
		||||
		case gumble.DisconnectBanned:
 | 
			
		||||
			b.Log.Errorf("Banned from the server (%s), not attempting reconnect", d.String)
 | 
			
		||||
			close(b.connected)
 | 
			
		||||
			close(b.running)
 | 
			
		||||
			return
 | 
			
		||||
		case gumble.DisconnectUser:
 | 
			
		||||
			b.Log.Infof("Disconnect successful")
 | 
			
		||||
			close(b.connected)
 | 
			
		||||
			close(b.running)
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (b *Bmumble) doConnect() error {
 | 
			
		||||
	// Create new gumble config and attach event handlers
 | 
			
		||||
	gumbleConfig := gumble.NewConfig()
 | 
			
		||||
	gumbleConfig.Attach(gumbleutil.Listener{
 | 
			
		||||
		ServerConfig: b.handleServerConfig,
 | 
			
		||||
		TextMessage:  b.handleTextMessage,
 | 
			
		||||
		Connect:      b.handleConnect,
 | 
			
		||||
		Disconnect:   b.handleDisconnect,
 | 
			
		||||
		UserChange:   b.handleUserChange,
 | 
			
		||||
	})
 | 
			
		||||
	gumbleConfig.Username = b.GetString("Nick")
 | 
			
		||||
	if password := b.GetString("Password"); password != "" {
 | 
			
		||||
		gumbleConfig.Password = password
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	client, err := gumble.DialWithDialer(new(net.Dialer), b.GetString("Server"), gumbleConfig, &b.tlsConfig)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	b.client = client
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (b *Bmumble) doJoin(client *gumble.Client, channelID uint32) error {
 | 
			
		||||
	channel, ok := client.Channels[channelID]
 | 
			
		||||
	if !ok {
 | 
			
		||||
		return fmt.Errorf("no channel with ID %d", channelID)
 | 
			
		||||
	}
 | 
			
		||||
	client.Self.Move(channel)
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (b *Bmumble) doSend() {
 | 
			
		||||
	// Message sending loop that makes sure server-side
 | 
			
		||||
	// restrictions and client-side message traits don't conflict
 | 
			
		||||
	// with each other.
 | 
			
		||||
	for {
 | 
			
		||||
		select {
 | 
			
		||||
		case serverConfig := <-b.serverConfigUpdate:
 | 
			
		||||
			b.Log.Debugf("Received server config update: AllowHTML=%#v, MaximumMessageLength=%#v", serverConfig.AllowHTML, serverConfig.MaximumMessageLength)
 | 
			
		||||
			b.serverConfig = serverConfig
 | 
			
		||||
		case msg := <-b.local:
 | 
			
		||||
			b.processMessage(&msg)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (b *Bmumble) processMessage(msg *config.Message) {
 | 
			
		||||
	b.Log.Debugf("Processing message %s", msg.Text)
 | 
			
		||||
 | 
			
		||||
	allowHTML := true
 | 
			
		||||
	if b.serverConfig.AllowHTML != nil {
 | 
			
		||||
		allowHTML = *b.serverConfig.AllowHTML
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// If this is a specially generated image message, send it unmodified
 | 
			
		||||
	if msg.Event == "mumble_image" {
 | 
			
		||||
		if allowHTML {
 | 
			
		||||
			b.client.Self.Channel.Send(msg.Username+msg.Text, false)
 | 
			
		||||
		} else {
 | 
			
		||||
			b.Log.Info("Can't send image, server does not allow HTML messages")
 | 
			
		||||
		}
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Don't process empty messages
 | 
			
		||||
	if len(msg.Text) == 0 {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	// If HTML is allowed, convert markdown into HTML, otherwise strip markdown
 | 
			
		||||
	if allowHTML {
 | 
			
		||||
		msg.Text = helper.ParseMarkdown(msg.Text)
 | 
			
		||||
	} else {
 | 
			
		||||
		msg.Text = stripmd.Strip(msg.Text)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// If there is a maximum message length, split and truncate the lines
 | 
			
		||||
	var msgLines []string
 | 
			
		||||
	if maxLength := b.serverConfig.MaximumMessageLength; maxLength != nil {
 | 
			
		||||
		msgLines = helper.GetSubLines(msg.Text, *maxLength-len(msg.Username))
 | 
			
		||||
	} else {
 | 
			
		||||
		msgLines = helper.GetSubLines(msg.Text, 0)
 | 
			
		||||
	}
 | 
			
		||||
	// Send the individual lindes
 | 
			
		||||
	for i := range msgLines {
 | 
			
		||||
		b.client.Self.Channel.Send(msg.Username+msgLines[i], false)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										203
									
								
								bridge/nctalk/nctalk.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										203
									
								
								bridge/nctalk/nctalk.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,203 @@
 | 
			
		||||
package nctalk
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"context"
 | 
			
		||||
	"crypto/tls"
 | 
			
		||||
	"strconv"
 | 
			
		||||
	"strings"
 | 
			
		||||
 | 
			
		||||
	"github.com/42wim/matterbridge/bridge"
 | 
			
		||||
	"github.com/42wim/matterbridge/bridge/config"
 | 
			
		||||
 | 
			
		||||
	"gomod.garykim.dev/nc-talk/ocs"
 | 
			
		||||
	"gomod.garykim.dev/nc-talk/room"
 | 
			
		||||
	"gomod.garykim.dev/nc-talk/user"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type Btalk struct {
 | 
			
		||||
	user  *user.TalkUser
 | 
			
		||||
	rooms []Broom
 | 
			
		||||
	*bridge.Config
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func New(cfg *bridge.Config) bridge.Bridger {
 | 
			
		||||
	return &Btalk{Config: cfg}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type Broom struct {
 | 
			
		||||
	room      *room.TalkRoom
 | 
			
		||||
	ctx       context.Context
 | 
			
		||||
	ctxCancel context.CancelFunc
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (b *Btalk) Connect() error {
 | 
			
		||||
	b.Log.Info("Connecting")
 | 
			
		||||
	tconfig := &user.TalkUserConfig{
 | 
			
		||||
		TLSConfig: &tls.Config{
 | 
			
		||||
			InsecureSkipVerify: b.GetBool("SkipTLSVerify"), //nolint:gosec
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
	var err error
 | 
			
		||||
	b.user, err = user.NewUser(b.GetString("Server"), b.GetString("Login"), b.GetString("Password"), tconfig)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		b.Log.Error("Config could not be used")
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	_, err = b.user.Capabilities()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		b.Log.Error("Cannot Connect")
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	b.Log.Info("Connected")
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (b *Btalk) Disconnect() error {
 | 
			
		||||
	for _, r := range b.rooms {
 | 
			
		||||
		r.ctxCancel()
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (b *Btalk) JoinChannel(channel config.ChannelInfo) error {
 | 
			
		||||
	tr, err := room.NewTalkRoom(b.user, channel.Name)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	newRoom := Broom{
 | 
			
		||||
		room: tr,
 | 
			
		||||
	}
 | 
			
		||||
	newRoom.ctx, newRoom.ctxCancel = context.WithCancel(context.Background())
 | 
			
		||||
	c, err := newRoom.room.ReceiveMessages(newRoom.ctx)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	b.rooms = append(b.rooms, newRoom)
 | 
			
		||||
 | 
			
		||||
	// Config
 | 
			
		||||
	guestSuffix := " (Guest)"
 | 
			
		||||
	if b.IsKeySet("GuestSuffix") {
 | 
			
		||||
		guestSuffix = b.GetString("GuestSuffix")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	go func() {
 | 
			
		||||
		for msg := range c {
 | 
			
		||||
			msg := msg
 | 
			
		||||
			// ignore messages that are one of the following
 | 
			
		||||
			// * not a message from a user
 | 
			
		||||
			// * from ourselves
 | 
			
		||||
			if msg.MessageType != ocs.MessageComment || msg.ActorID == b.user.User {
 | 
			
		||||
				continue
 | 
			
		||||
			}
 | 
			
		||||
			remoteMessage := config.Message{
 | 
			
		||||
				Text:     formatRichObjectString(msg.Message, msg.MessageParameters),
 | 
			
		||||
				Channel:  newRoom.room.Token,
 | 
			
		||||
				Username: DisplayName(msg, guestSuffix),
 | 
			
		||||
				UserID:   msg.ActorID,
 | 
			
		||||
				Account:  b.Account,
 | 
			
		||||
			}
 | 
			
		||||
			// It is possible for the ID to not be set on older versions of Talk so we only set it if
 | 
			
		||||
			// the ID is not blank
 | 
			
		||||
			if msg.ID != 0 {
 | 
			
		||||
				remoteMessage.ID = strconv.Itoa(msg.ID)
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			// Handle Files
 | 
			
		||||
			err = b.handleFiles(&remoteMessage, &msg)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				b.Log.Errorf("Error handling file: %#v", msg)
 | 
			
		||||
 | 
			
		||||
				continue
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			b.Log.Debugf("<= Message is %#v", remoteMessage)
 | 
			
		||||
			b.Remote <- remoteMessage
 | 
			
		||||
		}
 | 
			
		||||
	}()
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (b *Btalk) Send(msg config.Message) (string, error) {
 | 
			
		||||
	r := b.getRoom(msg.Channel)
 | 
			
		||||
	if r == nil {
 | 
			
		||||
		b.Log.Errorf("Could not find room for %v", msg.Channel)
 | 
			
		||||
		return "", nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Talk currently only supports sending normal messages
 | 
			
		||||
	if msg.Event != "" {
 | 
			
		||||
		return "", nil
 | 
			
		||||
	}
 | 
			
		||||
	sentMessage, err := r.room.SendMessage(msg.Username + msg.Text)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		b.Log.Errorf("Could not send message to room %v from %v: %v", msg.Channel, msg.Username, err)
 | 
			
		||||
		return "", nil
 | 
			
		||||
	}
 | 
			
		||||
	return strconv.Itoa(sentMessage.ID), nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (b *Btalk) getRoom(token string) *Broom {
 | 
			
		||||
	for _, r := range b.rooms {
 | 
			
		||||
		if r.room.Token == token {
 | 
			
		||||
			return &r
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (b *Btalk) handleFiles(mmsg *config.Message, message *ocs.TalkRoomMessageData) error {
 | 
			
		||||
	for _, parameter := range message.MessageParameters {
 | 
			
		||||
		if parameter.Type == ocs.ROSTypeFile {
 | 
			
		||||
			// Get the file
 | 
			
		||||
			file, err := b.user.DownloadFile(parameter.Path)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				return err
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if mmsg.Extra == nil {
 | 
			
		||||
				mmsg.Extra = make(map[string][]interface{})
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			mmsg.Extra["file"] = append(mmsg.Extra["file"], config.FileInfo{
 | 
			
		||||
				Name:   parameter.Name,
 | 
			
		||||
				Data:   file,
 | 
			
		||||
				Size:   int64(len(*file)),
 | 
			
		||||
				Avatar: false,
 | 
			
		||||
			})
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Spec: https://github.com/nextcloud/server/issues/1706#issue-182308785
 | 
			
		||||
func formatRichObjectString(message string, parameters map[string]ocs.RichObjectString) string {
 | 
			
		||||
	for id, parameter := range parameters {
 | 
			
		||||
		text := parameter.Name
 | 
			
		||||
 | 
			
		||||
		switch parameter.Type {
 | 
			
		||||
		case ocs.ROSTypeUser, ocs.ROSTypeGroup:
 | 
			
		||||
			text = "@" + text
 | 
			
		||||
		case ocs.ROSTypeFile:
 | 
			
		||||
			if parameter.Link != "" {
 | 
			
		||||
				text = parameter.Name
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		message = strings.ReplaceAll(message, "{"+id+"}", text)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return message
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func DisplayName(msg ocs.TalkRoomMessageData, suffix string) string {
 | 
			
		||||
	if msg.ActorType == ocs.ActorGuest {
 | 
			
		||||
		if msg.ActorDisplayName == "" {
 | 
			
		||||
			return "Guest"
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return msg.ActorDisplayName + suffix
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return msg.ActorDisplayName
 | 
			
		||||
}
 | 
			
		||||
@@ -16,7 +16,7 @@ var ErrEventIgnored = errors.New("this event message should ignored")
 | 
			
		||||
 | 
			
		||||
func (b *Bslack) handleSlack() {
 | 
			
		||||
	messages := make(chan *config.Message)
 | 
			
		||||
	if b.GetString(incomingWebhookConfig) != "" {
 | 
			
		||||
	if b.GetString(incomingWebhookConfig) != "" && b.GetString(tokenConfig) == "" {
 | 
			
		||||
		b.Log.Debugf("Choosing webhooks based receiving")
 | 
			
		||||
		go b.handleMatterHook(messages)
 | 
			
		||||
	} else {
 | 
			
		||||
 
 | 
			
		||||
@@ -204,7 +204,7 @@ func (b *Bslack) Send(msg config.Message) (string, error) {
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Use webhook to send the message
 | 
			
		||||
	if b.GetString(outgoingWebhookConfig) != "" {
 | 
			
		||||
	if b.GetString(outgoingWebhookConfig) != "" && b.GetString(tokenConfig) == "" {
 | 
			
		||||
		return "", b.sendWebhook(msg)
 | 
			
		||||
	}
 | 
			
		||||
	return b.sendRTM(msg)
 | 
			
		||||
 
 | 
			
		||||
@@ -39,22 +39,32 @@ func (b *Btelegram) handleGroups(rmsg *config.Message, message *tgbotapi.Message
 | 
			
		||||
 | 
			
		||||
// handleForwarded handles forwarded messages
 | 
			
		||||
func (b *Btelegram) handleForwarded(rmsg *config.Message, message *tgbotapi.Message) {
 | 
			
		||||
	if message.ForwardFrom != nil {
 | 
			
		||||
		usernameForward := ""
 | 
			
		||||
		if b.GetBool("UseFirstName") {
 | 
			
		||||
	if message.ForwardDate == 0 {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if message.ForwardFrom == nil {
 | 
			
		||||
		rmsg.Text = "Forwarded from " + unknownUser + ": " + rmsg.Text
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	usernameForward := ""
 | 
			
		||||
	if b.GetBool("UseFirstName") {
 | 
			
		||||
		usernameForward = message.ForwardFrom.FirstName
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if usernameForward == "" {
 | 
			
		||||
		usernameForward = message.ForwardFrom.UserName
 | 
			
		||||
		if usernameForward == "" {
 | 
			
		||||
			usernameForward = message.ForwardFrom.FirstName
 | 
			
		||||
		}
 | 
			
		||||
		if usernameForward == "" {
 | 
			
		||||
			usernameForward = message.ForwardFrom.UserName
 | 
			
		||||
			if usernameForward == "" {
 | 
			
		||||
				usernameForward = message.ForwardFrom.FirstName
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		if usernameForward == "" {
 | 
			
		||||
			usernameForward = unknownUser
 | 
			
		||||
		}
 | 
			
		||||
		rmsg.Text = "Forwarded from " + usernameForward + ": " + rmsg.Text
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if usernameForward == "" {
 | 
			
		||||
		usernameForward = unknownUser
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	rmsg.Text = "Forwarded from " + usernameForward + ": " + rmsg.Text
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// handleQuoting handles quoting of previous messages
 | 
			
		||||
@@ -207,6 +217,46 @@ func (b *Btelegram) handleDownloadAvatar(userid int, channel string) {
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (b *Btelegram) maybeConvertTgs(name *string, data *[]byte) {
 | 
			
		||||
	var format string
 | 
			
		||||
	switch b.GetString("MediaConvertTgs") {
 | 
			
		||||
	case FormatWebp:
 | 
			
		||||
		b.Log.Debugf("Tgs to WebP conversion enabled, converting %v", name)
 | 
			
		||||
		format = FormatWebp
 | 
			
		||||
	case FormatPng:
 | 
			
		||||
		// The WebP to PNG converter can't handle animated webp files yet,
 | 
			
		||||
		// and I'm not going to write a path for x/image/webp.
 | 
			
		||||
		// The error message would be:
 | 
			
		||||
		//     conversion failed: webp: non-Alpha VP8X is not implemented
 | 
			
		||||
		// So instead, we tell lottie to directly go to PNG.
 | 
			
		||||
		b.Log.Debugf("Tgs to PNG conversion enabled, converting %v", name)
 | 
			
		||||
		format = FormatPng
 | 
			
		||||
	default:
 | 
			
		||||
		// Otherwise, no conversion was requested. Trying to run the usual webp
 | 
			
		||||
		// converter would fail, because '.tgs.webp' is actually a gzipped JSON
 | 
			
		||||
		// file, and has nothing to do with WebP.
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	err := helper.ConvertTgsToX(data, format, b.Log)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		b.Log.Errorf("conversion failed: %v", err)
 | 
			
		||||
	} else {
 | 
			
		||||
		*name = strings.Replace(*name, "tgs.webp", format, 1)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (b *Btelegram) maybeConvertWebp(name *string, data *[]byte) {
 | 
			
		||||
	if b.GetBool("MediaConvertWebPToPNG") {
 | 
			
		||||
		b.Log.Debugf("WebP to PNG conversion enabled, converting %v", name)
 | 
			
		||||
		err := helper.ConvertWebPToPNG(data)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			b.Log.Errorf("conversion failed: %v", err)
 | 
			
		||||
		} else {
 | 
			
		||||
			*name = strings.Replace(*name, ".webp", ".png", 1)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// handleDownloadFile handles file download
 | 
			
		||||
func (b *Btelegram) handleDownload(rmsg *config.Message, message *tgbotapi.Message) error {
 | 
			
		||||
	size := 0
 | 
			
		||||
@@ -254,15 +304,13 @@ func (b *Btelegram) handleDownload(rmsg *config.Message, message *tgbotapi.Messa
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	if strings.HasSuffix(name, ".webp") && b.GetBool("MediaConvertWebPToPNG") {
 | 
			
		||||
		b.Log.Debugf("WebP to PNG conversion enabled, converting %s", name)
 | 
			
		||||
		err := helper.ConvertWebPToPNG(data)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			b.Log.Errorf("conversion failed: %s", err)
 | 
			
		||||
		} else {
 | 
			
		||||
			name = strings.Replace(name, ".webp", ".png", 1)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	if strings.HasSuffix(name, ".tgs.webp") {
 | 
			
		||||
		b.maybeConvertTgs(&name, data)
 | 
			
		||||
	} else if strings.HasSuffix(name, ".webp") {
 | 
			
		||||
		b.maybeConvertWebp(&name, data)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	helper.HandleDownloadData(b.Log, rmsg, name, message.Caption, "", data, b.General)
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
@@ -312,6 +360,9 @@ func (b *Btelegram) handleEdit(msg *config.Message, chatid int64) (string, error
 | 
			
		||||
	case "Markdown":
 | 
			
		||||
		b.Log.Debug("Using mode markdown")
 | 
			
		||||
		m.ParseMode = tgbotapi.ModeMarkdown
 | 
			
		||||
	case MarkdownV2:
 | 
			
		||||
		b.Log.Debug("Using mode MarkdownV2")
 | 
			
		||||
		m.ParseMode = MarkdownV2
 | 
			
		||||
	}
 | 
			
		||||
	if strings.ToLower(b.GetString("MessageFormat")) == HTMLNick {
 | 
			
		||||
		b.Log.Debug("Using mode HTML - nick only")
 | 
			
		||||
 
 | 
			
		||||
@@ -2,6 +2,7 @@ package btelegram
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"html"
 | 
			
		||||
	"log"
 | 
			
		||||
	"strconv"
 | 
			
		||||
	"strings"
 | 
			
		||||
 | 
			
		||||
@@ -15,6 +16,9 @@ const (
 | 
			
		||||
	unknownUser = "unknown"
 | 
			
		||||
	HTMLFormat  = "HTML"
 | 
			
		||||
	HTMLNick    = "htmlnick"
 | 
			
		||||
	MarkdownV2  = "MarkdownV2"
 | 
			
		||||
	FormatPng   = "png"
 | 
			
		||||
	FormatWebp  = "webp"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type Btelegram struct {
 | 
			
		||||
@@ -24,6 +28,16 @@ type Btelegram struct {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func New(cfg *bridge.Config) bridge.Bridger {
 | 
			
		||||
	tgsConvertFormat := cfg.GetString("MediaConvertTgs")
 | 
			
		||||
	if tgsConvertFormat != "" {
 | 
			
		||||
		err := helper.CanConvertTgsToX()
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			log.Fatalf("Telegram bridge configured to convert .tgs files to '%s', but lottie does not appear to work:\n%#v", tgsConvertFormat, err)
 | 
			
		||||
		}
 | 
			
		||||
		if tgsConvertFormat != FormatPng && tgsConvertFormat != FormatWebp {
 | 
			
		||||
			log.Fatalf("Telegram bridge configured to convert .tgs files to '%s', but only '%s' and '%s' are supported.", FormatPng, FormatWebp, tgsConvertFormat)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return &Btelegram{Config: cfg, avatarMap: make(map[string]string)}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -126,6 +140,10 @@ func (b *Btelegram) sendMessage(chatid int64, username, text string) (string, er
 | 
			
		||||
		b.Log.Debug("Using mode markdown")
 | 
			
		||||
		m.ParseMode = tgbotapi.ModeMarkdown
 | 
			
		||||
	}
 | 
			
		||||
	if b.GetString("MessageFormat") == MarkdownV2 {
 | 
			
		||||
		b.Log.Debug("Using mode MarkdownV2")
 | 
			
		||||
		m.ParseMode = MarkdownV2
 | 
			
		||||
	}
 | 
			
		||||
	if strings.ToLower(b.GetString("MessageFormat")) == HTMLNick {
 | 
			
		||||
		b.Log.Debug("Using mode HTML - nick only")
 | 
			
		||||
		m.Text = username + html.EscapeString(text)
 | 
			
		||||
 
 | 
			
		||||
@@ -78,7 +78,9 @@ func (b *Bwhatsapp) HandleTextMessage(message whatsapp.TextMessage) {
 | 
			
		||||
	senderJID := message.Info.SenderJid
 | 
			
		||||
	if len(senderJID) == 0 {
 | 
			
		||||
		// TODO workaround till https://github.com/Rhymen/go-whatsapp/issues/86 resolved
 | 
			
		||||
		senderJID = *message.Info.Source.Participant
 | 
			
		||||
		if message.Info.Source != nil && message.Info.Source.Participant != nil {
 | 
			
		||||
			senderJID = *message.Info.Source.Participant
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// translate sender's JID to the nicest username we can get
 | 
			
		||||
@@ -141,10 +143,12 @@ func (b *Bwhatsapp) HandleImageMessage(message whatsapp.ImageMessage) {
 | 
			
		||||
	groupJID := message.Info.RemoteJid
 | 
			
		||||
 | 
			
		||||
	senderJID := message.Info.SenderJid
 | 
			
		||||
	// if len(senderJid) == 0 {
 | 
			
		||||
	//   // TODO workaround till https://github.com/Rhymen/go-whatsapp/issues/86 resolved
 | 
			
		||||
	//   senderJid = *message.Info.Source.Participant
 | 
			
		||||
	// }
 | 
			
		||||
	if len(senderJID) == 0 {
 | 
			
		||||
		// TODO workaround till https://github.com/Rhymen/go-whatsapp/issues/86 resolved
 | 
			
		||||
		if message.Info.Source != nil && message.Info.Source.Participant != nil {
 | 
			
		||||
			senderJID = *message.Info.Source.Participant
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// translate sender's Jid to the nicest username we can get
 | 
			
		||||
	senderName := b.getSenderName(senderJID)
 | 
			
		||||
 
 | 
			
		||||
@@ -80,8 +80,33 @@ func (b *Bwhatsapp) getSenderName(senderJid string) string {
 | 
			
		||||
		// if user is not in phone contacts
 | 
			
		||||
		// it is the most obvious scenario unless you sync your phone contacts with some remote updated source
 | 
			
		||||
		// users can change it in their WhatsApp settings -> profile -> click on Avatar
 | 
			
		||||
		return sender.Notify
 | 
			
		||||
		if sender.Notify != "" {
 | 
			
		||||
			return sender.Notify
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if sender.Short != "" {
 | 
			
		||||
			return sender.Short
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// try to reload this contact
 | 
			
		||||
	_, err := b.conn.Contacts()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		b.Log.Errorf("error on update of contacts: %v", err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if contact, exists := b.conn.Store.Contacts[senderJid]; exists {
 | 
			
		||||
		// Add it to the user map
 | 
			
		||||
		b.users[senderJid] = contact
 | 
			
		||||
 | 
			
		||||
		if contact.Name != "" {
 | 
			
		||||
			return contact.Name
 | 
			
		||||
		}
 | 
			
		||||
		// if user is not in phone contacts
 | 
			
		||||
		// same as above
 | 
			
		||||
		return contact.Notify
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return ""
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -67,7 +67,6 @@ func (b *Bwhatsapp) Connect() error {
 | 
			
		||||
	// https://github.com/Rhymen/go-whatsapp#creating-a-connection
 | 
			
		||||
	b.Log.Debugln("Connecting to WhatsApp..")
 | 
			
		||||
	conn, err := whatsapp.NewConn(20 * time.Second)
 | 
			
		||||
	conn.SetClientVersion(0, 4, 2080)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return errors.New("failed to connect to WhatsApp: " + err.Error())
 | 
			
		||||
	}
 | 
			
		||||
@@ -184,7 +183,7 @@ func (b *Bwhatsapp) Disconnect() error {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func isGroupJid(identifier string) bool {
 | 
			
		||||
	return strings.HasSuffix(identifier, "@g.us") || strings.HasSuffix(identifier, "@temp")
 | 
			
		||||
	return strings.HasSuffix(identifier, "@g.us") || strings.HasSuffix(identifier, "@temp") || strings.HasSuffix(identifier, "@broadcast")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// JoinChannel Join a WhatsApp group specified in gateway config as channel='number-id@g.us' or channel='Channel name'
 | 
			
		||||
 
 | 
			
		||||
@@ -24,14 +24,16 @@ type Bxmpp struct {
 | 
			
		||||
	connected bool
 | 
			
		||||
	sync.RWMutex
 | 
			
		||||
 | 
			
		||||
	avatarMap map[string]string
 | 
			
		||||
	avatarAvailability map[string]bool
 | 
			
		||||
	avatarMap          map[string]string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func New(cfg *bridge.Config) bridge.Bridger {
 | 
			
		||||
	return &Bxmpp{
 | 
			
		||||
		Config:    cfg,
 | 
			
		||||
		xmppMap:   make(map[string]string),
 | 
			
		||||
		avatarMap: make(map[string]string),
 | 
			
		||||
		Config:             cfg,
 | 
			
		||||
		xmppMap:            make(map[string]string),
 | 
			
		||||
		avatarAvailability: make(map[string]bool),
 | 
			
		||||
		avatarMap:          make(map[string]string),
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -70,12 +72,19 @@ func (b *Bxmpp) Send(msg config.Message) (string, error) {
 | 
			
		||||
	if msg.Event == config.EventMsgDelete {
 | 
			
		||||
		return "", nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	b.Log.Debugf("=> Receiving %#v", msg)
 | 
			
		||||
 | 
			
		||||
	if msg.Event == config.EventAvatarDownload {
 | 
			
		||||
		return b.cacheAvatar(&msg), nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Make a action /me of the message, prepend the username with it.
 | 
			
		||||
	// https://xmpp.org/extensions/xep-0245.html
 | 
			
		||||
	if msg.Event == config.EventUserAction {
 | 
			
		||||
		msg.Username = "/me " + msg.Username
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Upload a file (in XMPP case send the upload URL because XMPP has no native upload support).
 | 
			
		||||
	if msg.Extra != nil {
 | 
			
		||||
		for _, rmsg := range helper.HandleExtra(&msg, b.General) {
 | 
			
		||||
@@ -237,10 +246,14 @@ func (b *Bxmpp) handleXMPP() error {
 | 
			
		||||
					event = config.EventTopicChange
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				avatar := getAvatar(b.avatarMap, v.Remote, b.General)
 | 
			
		||||
				if avatar == "" {
 | 
			
		||||
				available, sok := b.avatarAvailability[v.Remote]
 | 
			
		||||
				avatar := ""
 | 
			
		||||
				if !sok {
 | 
			
		||||
					b.Log.Debugf("Requesting avatar data")
 | 
			
		||||
					b.avatarAvailability[v.Remote] = false
 | 
			
		||||
					b.xc.AvatarRequestData(v.Remote)
 | 
			
		||||
				} else if available {
 | 
			
		||||
					avatar = getAvatar(b.avatarMap, v.Remote, b.General)
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				msgID := v.ID
 | 
			
		||||
@@ -271,6 +284,8 @@ func (b *Bxmpp) handleXMPP() error {
 | 
			
		||||
			}
 | 
			
		||||
		case xmpp.AvatarData:
 | 
			
		||||
			b.handleDownloadAvatar(v)
 | 
			
		||||
			b.avatarAvailability[v.From] = true
 | 
			
		||||
			b.Log.Debugf("Avatar for %s is now available", v.From)
 | 
			
		||||
		case xmpp.Presence:
 | 
			
		||||
			// Do nothing.
 | 
			
		||||
		}
 | 
			
		||||
 
 | 
			
		||||
@@ -135,19 +135,25 @@ func (b *Bzulip) handleQueue() error {
 | 
			
		||||
			if m.SenderEmail == b.GetString("login") {
 | 
			
		||||
				continue
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			avatarURL := m.AvatarURL
 | 
			
		||||
			if !strings.HasPrefix(avatarURL, "http") {
 | 
			
		||||
				avatarURL = b.GetString("server") + avatarURL
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			rmsg := config.Message{
 | 
			
		||||
				Username: m.SenderFullName,
 | 
			
		||||
				Text:     m.Content,
 | 
			
		||||
				Channel:  b.getChannel(m.StreamID) + "/topic:" + m.Subject,
 | 
			
		||||
				Account:  b.Account,
 | 
			
		||||
				UserID:   strconv.Itoa(m.SenderID),
 | 
			
		||||
				Avatar:   m.AvatarURL,
 | 
			
		||||
				Avatar:   avatarURL,
 | 
			
		||||
			}
 | 
			
		||||
			b.Log.Debugf("<= Sending message from %s on %s to gateway", rmsg.Username, b.Account)
 | 
			
		||||
			b.Log.Debugf("<= Message is %#v", rmsg)
 | 
			
		||||
			b.Remote <- rmsg
 | 
			
		||||
			b.q.LastEventID = m.ID
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		time.Sleep(time.Second * 3)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										128
									
								
								changelog.md
									
									
									
									
									
								
							
							
						
						
									
										128
									
								
								changelog.md
									
									
									
									
									
								
							@@ -1,3 +1,131 @@
 | 
			
		||||
# v1.19.0
 | 
			
		||||
 | 
			
		||||
## New features
 | 
			
		||||
 | 
			
		||||
- mumble: new protocol added: Add Mumble support (#1245)
 | 
			
		||||
- nctalk: Add support for downloading files (nctalk) (#1249)
 | 
			
		||||
- nctalk: Append a suffix if user is a guest user (nctalk) (#1250)
 | 
			
		||||
 | 
			
		||||
## Enhancements
 | 
			
		||||
 | 
			
		||||
- irc: Add even more debug for irc (#1266)
 | 
			
		||||
- matrix: Add username formatting for all events (matrix) (#1233)
 | 
			
		||||
- matrix: Permit uploading files of other mimetypes (#1237)
 | 
			
		||||
- whatsapp: Use vendored whatsapp version (#1258)
 | 
			
		||||
- whatsapp: Add username for images from WhatsApp (#1232)
 | 
			
		||||
 | 
			
		||||
This release couldn't exist without the following contributors:
 | 
			
		||||
@Dellle, @42wim, @gary-kim, @s3lph, @BenWiederhake
 | 
			
		||||
 | 
			
		||||
# v1.18.3
 | 
			
		||||
 | 
			
		||||
## Enhancements
 | 
			
		||||
 | 
			
		||||
- nctalk: Add TLSConfig to nctalk (#1195)
 | 
			
		||||
- whatsapp: Handle broadcasts as groups in Whatsapp #1213
 | 
			
		||||
- matrix: switch to upstream gomatrix #1219
 | 
			
		||||
- api: support multiple websocket clients #1205
 | 
			
		||||
 | 
			
		||||
## Bugfix
 | 
			
		||||
 | 
			
		||||
- general: update vendor
 | 
			
		||||
- zulip: Check location of avatarURL (zulip). Fixes #1214 (#1227)
 | 
			
		||||
- nctalk: Fix issue with too many open files #1223
 | 
			
		||||
- nctalk: Fix mentions #1222
 | 
			
		||||
- nctalk: Fix message replays #1220
 | 
			
		||||
 | 
			
		||||
This release couldn't exist without the following contributors:
 | 
			
		||||
@gary-kim, @tilosp, @NikkyAI, @escoand, @42wim
 | 
			
		||||
 | 
			
		||||
# v1.18.2
 | 
			
		||||
 | 
			
		||||
## Bugfix
 | 
			
		||||
 | 
			
		||||
- zulip: Fix error loop (zulip) (#1210)
 | 
			
		||||
- whatsapp: Update whatsapp vendor and fix a panic (#1209)
 | 
			
		||||
 | 
			
		||||
This release couldn't exist without the following contributors:
 | 
			
		||||
@SuperSandro2000, @42wim
 | 
			
		||||
 | 
			
		||||
# v1.18.1
 | 
			
		||||
 | 
			
		||||
## New features
 | 
			
		||||
 | 
			
		||||
- telegram: Support Telegram animated stickers (tgs) format (#1173). See https://github.com/42wim/matterbridge/wiki/Settings#mediaConverttgs for more info
 | 
			
		||||
 | 
			
		||||
## Enhancements
 | 
			
		||||
 | 
			
		||||
- matrix: Remove HTML formatting for push messages (#1188) (#1189)
 | 
			
		||||
- mattermost: Use mattermost v5 module (#1192)
 | 
			
		||||
 | 
			
		||||
## Bugfix
 | 
			
		||||
 | 
			
		||||
- whatsapp: Handle panic in whatsapp. Fixes #1180 (#1184)
 | 
			
		||||
- nctalk: Fix Nextcloud Talk connection failure (#1179)
 | 
			
		||||
- matrix: Sleep when ratelimited on joins (matrix). Fixes #1201 (#1206)
 | 
			
		||||
 | 
			
		||||
This release couldn't exist without the following contributors:
 | 
			
		||||
@42wim, @BenWiederhake, @Dellle, @gary-kim
 | 
			
		||||
 | 
			
		||||
# v1.18.0
 | 
			
		||||
 | 
			
		||||
## New features
 | 
			
		||||
 | 
			
		||||
- nctalk: new protocol added. Add Nextcloud Talk support #1167
 | 
			
		||||
- general: Add an option to log into a file rather than stdout (#1168)
 | 
			
		||||
- api: Add websocket to API (#970)
 | 
			
		||||
 | 
			
		||||
## Enhancements
 | 
			
		||||
 | 
			
		||||
- telegram: Fix MarkdownV2 support in Telegram (#1169)
 | 
			
		||||
- whatsapp: Reload user information when a new contact is detected (whatsapp) (#1160)
 | 
			
		||||
- api: Add sane RemoteNickFormat default for API (#1157)
 | 
			
		||||
- irc: Skip gIRC built-in rate limiting (irc) (#1164)
 | 
			
		||||
- irc: Only colour IRC nicks if there is one. (#1161)
 | 
			
		||||
- docker: Combine runs to one layer (#1151)
 | 
			
		||||
 | 
			
		||||
## Bugfix
 | 
			
		||||
 | 
			
		||||
- general: Update dependencies for 1.18.0 release (#1175)
 | 
			
		||||
 | 
			
		||||
Discord users are encouraged to upgrade, this release works with the move to the discord.com domain.
 | 
			
		||||
 | 
			
		||||
This release couldn't exist without the following contributors:
 | 
			
		||||
@42wim, @jlu5, @qaisjp, @TheHolyRoger, @SuperSandro2000, @gary-kim, @z3bra, @greenx, @haykam821, @nathanaelhoun
 | 
			
		||||
 | 
			
		||||
# v1.17.5
 | 
			
		||||
 | 
			
		||||
## Enhancements
 | 
			
		||||
 | 
			
		||||
- irc: Add StripMarkdown option (irc). (#1145)
 | 
			
		||||
- general: Increase debug logging with function,file and linenumber (#1147)
 | 
			
		||||
- general: Update Dockerfile so inotify works (#1148)
 | 
			
		||||
- matrix: Add an option to disable sending HTML to matrix. Fixes #1022 (#1135)
 | 
			
		||||
- xmpp: Implement xep-0245 (xmpp). Closes #1137 (#1144)
 | 
			
		||||
 | 
			
		||||
## Bugfix
 | 
			
		||||
 | 
			
		||||
- discord: Fix #1120: replaceAction "_" crash (discord) (#1121)
 | 
			
		||||
- discord: Fix #1049: missing space before embeds (discord) (#1124)
 | 
			
		||||
- discord: Fix webhook EventUserAction messages being skipped (discord) (#1133)
 | 
			
		||||
- matrix: Avoid creating invalid url when the user doesn't have an avatar (matrix) (#1130)
 | 
			
		||||
- msteams: Ignore non-user messages (msteams). Fixes #1141 (#1149)
 | 
			
		||||
- slack: Do not use webhooks when token is configured (slack) (fixes #1123) (#1134)
 | 
			
		||||
- telegram: Fix forward from hidden users (telegram). Closes #1131 (#1143)
 | 
			
		||||
- xmpp: Prevent re-requesting avatar data (xmpp) (#1117)
 | 
			
		||||
 | 
			
		||||
This release couldn't exist without the following contributors:
 | 
			
		||||
@qaisjp, @xnaas, @42wim, @Polynomdivision, @tfve
 | 
			
		||||
 | 
			
		||||
# v1.17.4
 | 
			
		||||
 | 
			
		||||
## Bugfix
 | 
			
		||||
 | 
			
		||||
- general: Lowercase account names. Fixes #1108 (#1110)
 | 
			
		||||
- msteams: Remove panics and retry polling on failure (msteams). Fixes #1104 (#1105
 | 
			
		||||
- whatsapp: Update Rhymen/go-whatsapp. Fixes #1107 (#1109) (make whatsapp working again)
 | 
			
		||||
- discord: Add an ID cache (discord). Fixes #1106 (#1111) (fix delete/edits with webhooks)
 | 
			
		||||
 | 
			
		||||
# v1.17.3
 | 
			
		||||
 | 
			
		||||
## Enhancements
 | 
			
		||||
 
 | 
			
		||||
@@ -1,30 +0,0 @@
 | 
			
		||||
#!/usr/bin/env bash
 | 
			
		||||
set -u -e -x -o pipefail
 | 
			
		||||
 | 
			
		||||
go version | grep go1.14 || exit
 | 
			
		||||
 | 
			
		||||
VERSION=$(git describe --tags)
 | 
			
		||||
mkdir ci/binaries
 | 
			
		||||
GOOS=windows GOARCH=amd64 go build -ldflags "-s -w -X main.githash=$(git log --pretty=format:'%h' -n 1)" -o ci/binaries/matterbridge-$VERSION-windows-amd64.exe
 | 
			
		||||
GOOS=linux GOARCH=amd64 go build -ldflags "-s -w -X main.githash=$(git log --pretty=format:'%h' -n 1)" -o ci/binaries/matterbridge-$VERSION-linux-amd64
 | 
			
		||||
GOOS=linux GOARCH=arm go build -ldflags "-s -w -X main.githash=$(git log --pretty=format:'%h' -n 1)" -o ci/binaries/matterbridge-$VERSION-linux-arm
 | 
			
		||||
GOOS=darwin GOARCH=amd64 go build -ldflags "-s -w -X main.githash=$(git log --pretty=format:'%h' -n 1)" -o ci/binaries/matterbridge-$VERSION-darwin-amd64
 | 
			
		||||
cd ci
 | 
			
		||||
cat > deploy.json <<EOF
 | 
			
		||||
{
 | 
			
		||||
    "package": {
 | 
			
		||||
        "name": "Matterbridge",
 | 
			
		||||
        "repo": "nightly",
 | 
			
		||||
        "subject": "42wim"
 | 
			
		||||
    },
 | 
			
		||||
    "version": {
 | 
			
		||||
        "name": "$VERSION"
 | 
			
		||||
    },
 | 
			
		||||
    "files":
 | 
			
		||||
        [
 | 
			
		||||
        {"includePattern": "ci/binaries/(.*)", "uploadPattern":"\$1"}
 | 
			
		||||
        ],
 | 
			
		||||
    "publish": true
 | 
			
		||||
}
 | 
			
		||||
EOF
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										17
									
								
								ci/lint.sh
									
									
									
									
									
								
							
							
						
						
									
										17
									
								
								ci/lint.sh
									
									
									
									
									
								
							@@ -1,17 +0,0 @@
 | 
			
		||||
#!/usr/bin/env bash
 | 
			
		||||
set -u -e -x -o pipefail
 | 
			
		||||
 | 
			
		||||
if [[ -n "${GOLANGCI_VERSION-}" ]]; then
 | 
			
		||||
  # Retrieve the golangci-lint linter binary.
 | 
			
		||||
  curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | bash -s -- -b ${GOPATH}/bin ${GOLANGCI_VERSION}
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
# Run the linter.
 | 
			
		||||
golangci-lint run
 | 
			
		||||
 | 
			
		||||
# if [[ "${GO111MODULE-off}" == "on" ]]; then
 | 
			
		||||
#   # If Go modules are active then check that dependencies are correctly maintained.
 | 
			
		||||
#   go mod tidy
 | 
			
		||||
#   go mod vendor
 | 
			
		||||
#   git diff --exit-code --quiet || (echo "Please run 'go mod tidy' to clean up the 'go.mod' and 'go.sum' files."; false)
 | 
			
		||||
# fi
 | 
			
		||||
							
								
								
									
										17
									
								
								ci/test.sh
									
									
									
									
									
								
							
							
						
						
									
										17
									
								
								ci/test.sh
									
									
									
									
									
								
							@@ -1,17 +0,0 @@
 | 
			
		||||
#!/usr/bin/env bash
 | 
			
		||||
set -u -e -x -o pipefail
 | 
			
		||||
 | 
			
		||||
if [[ -n "${REPORT_COVERAGE+cover}" ]]; then
 | 
			
		||||
  # Retrieve and prepare CodeClimate's test coverage reporter.
 | 
			
		||||
  curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
 | 
			
		||||
  chmod +x ./cc-test-reporter
 | 
			
		||||
  ./cc-test-reporter before-build
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
# Run all the tests with the race detector and generate coverage.
 | 
			
		||||
go test -v -race -coverprofile c.out ./...
 | 
			
		||||
 | 
			
		||||
if [[ -n "${REPORT_COVERAGE+cover}" && "${TRAVIS_SECURE_ENV_VARS}" == "true" ]]; then
 | 
			
		||||
  # Upload test coverage to CodeClimate.
 | 
			
		||||
  ./cc-test-reporter after-build
 | 
			
		||||
fi
 | 
			
		||||
							
								
								
									
										11
									
								
								gateway/bridgemap/bmumble.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								gateway/bridgemap/bmumble.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,11 @@
 | 
			
		||||
// +build !nomumble
 | 
			
		||||
 | 
			
		||||
package bridgemap
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	bmumble "github.com/42wim/matterbridge/bridge/mumble"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func init() {
 | 
			
		||||
	FullMap["mumble"] = bmumble.New
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										11
									
								
								gateway/bridgemap/bnctalk.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								gateway/bridgemap/bnctalk.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,11 @@
 | 
			
		||||
// +build !nonctalk
 | 
			
		||||
 | 
			
		||||
package bridgemap
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	btalk "github.com/42wim/matterbridge/bridge/nctalk"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func init() {
 | 
			
		||||
	FullMap["nctalk"] = btalk.New
 | 
			
		||||
}
 | 
			
		||||
@@ -108,7 +108,7 @@ func (gw *Gateway) AddBridge(cfg *config.Bridge) error {
 | 
			
		||||
func (gw *Gateway) checkConfig(cfg *config.Bridge) {
 | 
			
		||||
	match := false
 | 
			
		||||
	for _, key := range gw.Router.Config.Viper().AllKeys() {
 | 
			
		||||
		if strings.HasPrefix(key, cfg.Account) {
 | 
			
		||||
		if strings.HasPrefix(key, strings.ToLower(cfg.Account)) {
 | 
			
		||||
			match = true
 | 
			
		||||
			break
 | 
			
		||||
		}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										72
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										72
									
								
								go.mod
									
									
									
									
									
								
							@@ -4,61 +4,55 @@ require (
 | 
			
		||||
	github.com/42wim/go-gitter v0.0.0-20170828205020-017310c2d557
 | 
			
		||||
	github.com/Baozisoftware/qrcode-terminal-go v0.0.0-20170407111555-c0650d8dff0f
 | 
			
		||||
	github.com/Jeffail/gabs v1.1.1 // indirect
 | 
			
		||||
	github.com/Philipp15b/go-steam v1.0.1-0.20190816133340-b04c5a83c1c0
 | 
			
		||||
	github.com/Rhymen/go-whatsapp v0.1.1-0.20200408093540-2f227c53b44f
 | 
			
		||||
	github.com/d5/tengo/v2 v2.1.2
 | 
			
		||||
	github.com/dfordsoft/golib v0.0.0-20180902042739-76ee6ab99bec
 | 
			
		||||
	github.com/fsnotify/fsnotify v1.4.7
 | 
			
		||||
	github.com/go-telegram-bot-api/telegram-bot-api v4.6.5-0.20181225215658-ec221ba9ea45+incompatible
 | 
			
		||||
	github.com/gomarkdown/markdown v0.0.0-20200127000047-1813ea067497
 | 
			
		||||
	github.com/google/gops v0.3.6
 | 
			
		||||
	github.com/Philipp15b/go-steam v1.0.1-0.20200727090957-6ae9b3c0a560
 | 
			
		||||
	github.com/Rhymen/go-whatsapp v0.1.1-0.20201007125822-005103751b7a
 | 
			
		||||
	github.com/d5/tengo/v2 v2.6.2
 | 
			
		||||
	github.com/davecgh/go-spew v1.1.1
 | 
			
		||||
	github.com/fsnotify/fsnotify v1.4.9
 | 
			
		||||
	github.com/go-telegram-bot-api/telegram-bot-api v1.0.1-0.20200524105306-7434b0456e81
 | 
			
		||||
	github.com/gomarkdown/markdown v0.0.0-20200824053859-8c8b3816f167
 | 
			
		||||
	github.com/google/gops v0.3.11
 | 
			
		||||
	github.com/gopackage/ddp v0.0.0-20170117053602-652027933df4 // indirect
 | 
			
		||||
	github.com/gorilla/schema v1.1.0
 | 
			
		||||
	github.com/gorilla/websocket v1.4.1
 | 
			
		||||
	github.com/hashicorp/golang-lru v0.5.3
 | 
			
		||||
	github.com/hpcloud/tail v1.0.0 // indirect
 | 
			
		||||
	github.com/gorilla/schema v1.2.0
 | 
			
		||||
	github.com/gorilla/websocket v1.4.2
 | 
			
		||||
	github.com/hashicorp/golang-lru v0.5.4
 | 
			
		||||
	github.com/jpillora/backoff v1.0.0
 | 
			
		||||
	github.com/keybase/go-keybase-chat-bot v0.0.0-20200226211841-4e48f3eaef3e
 | 
			
		||||
	github.com/labstack/echo/v4 v4.1.13
 | 
			
		||||
	github.com/keybase/go-keybase-chat-bot v0.0.0-20200505163032-5cacf52379da
 | 
			
		||||
	github.com/labstack/echo/v4 v4.1.17
 | 
			
		||||
	github.com/lrstanley/girc v0.0.0-20190801035559-4fc93959e1a7
 | 
			
		||||
	github.com/matrix-org/gomatrix v0.0.0-20200827122206-7dd5e2a05bcd
 | 
			
		||||
	github.com/matterbridge/Rocket.Chat.Go.SDK v0.0.0-20200411204219-d5c18ce75048
 | 
			
		||||
	github.com/matterbridge/discordgo v0.18.1-0.20200308151012-aa40f01cbcc3
 | 
			
		||||
	github.com/matterbridge/discordgo v0.22.0
 | 
			
		||||
	github.com/matterbridge/emoji v2.1.1-0.20191117213217-af507f6b02db+incompatible
 | 
			
		||||
	github.com/matterbridge/go-xmpp v0.0.0-20200418225040-c8a3a57b4050
 | 
			
		||||
	github.com/matterbridge/gomatrix v0.0.0-20200209224845-c2104d7936a6
 | 
			
		||||
	github.com/matterbridge/gozulipbot v0.0.0-20190212232658-7aa251978a18
 | 
			
		||||
	github.com/matterbridge/logrus-prefixed-formatter v0.0.0-20180806162718-01618749af61
 | 
			
		||||
	github.com/mattermost/mattermost-server v5.5.0+incompatible
 | 
			
		||||
	github.com/mattn/go-runewidth v0.0.7 // indirect
 | 
			
		||||
	github.com/mattn/godown v0.0.0-20180312012330-2e9e17e0ea51
 | 
			
		||||
	github.com/matterbridge/gozulipbot v0.0.0-20200820220548-be5824faa913
 | 
			
		||||
	github.com/matterbridge/logrus-prefixed-formatter v0.5.3-0.20200523233437-d971309a77ba
 | 
			
		||||
	github.com/mattermost/mattermost-server/v5 v5.28.1
 | 
			
		||||
	github.com/mattn/godown v0.0.0-20200217152941-afc959f6a561
 | 
			
		||||
	github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b // indirect
 | 
			
		||||
	github.com/missdeer/golib v1.0.3
 | 
			
		||||
	github.com/mreiferson/go-httpclient v0.0.0-20160630210159-31f0106b4474 // indirect
 | 
			
		||||
	github.com/mrexodia/wray v0.0.0-20160318003008-78a2c1f284ff // indirect
 | 
			
		||||
	github.com/nelsonken/gomf v0.0.0-20180504123937-a9dd2f9deae9
 | 
			
		||||
	github.com/nicksnyder/go-i18n v1.4.0 // indirect
 | 
			
		||||
	github.com/onsi/ginkgo v1.6.0 // indirect
 | 
			
		||||
	github.com/onsi/gomega v1.4.1 // indirect
 | 
			
		||||
	github.com/paulrosania/go-charset v0.0.0-20190326053356-55c9d7a5834c
 | 
			
		||||
	github.com/pborman/uuid v0.0.0-20160216163710-c55201b03606 // indirect
 | 
			
		||||
	github.com/rs/xid v1.2.1
 | 
			
		||||
	github.com/russross/blackfriday v1.5.2
 | 
			
		||||
	github.com/saintfish/chardet v0.0.0-20120816061221-3af4cd4741ca
 | 
			
		||||
	github.com/shazow/ssh-chat v1.8.3-0.20200308224626-80ddf1f43a98
 | 
			
		||||
	github.com/sirupsen/logrus v1.4.2
 | 
			
		||||
	github.com/slack-go/slack v0.6.3
 | 
			
		||||
	github.com/spf13/viper v1.6.1
 | 
			
		||||
	github.com/stretchr/testify v1.4.0
 | 
			
		||||
	github.com/technoweenie/multipartstreamer v1.0.1 // indirect
 | 
			
		||||
	github.com/sirupsen/logrus v1.7.0
 | 
			
		||||
	github.com/slack-go/slack v0.7.2
 | 
			
		||||
	github.com/spf13/viper v1.7.1
 | 
			
		||||
	github.com/stretchr/testify v1.6.1
 | 
			
		||||
	github.com/vincent-petithory/dataurl v0.0.0-20191104211930-d1553a71de50
 | 
			
		||||
	github.com/writeas/go-strip-markdown v2.0.1+incompatible
 | 
			
		||||
	github.com/x-cray/logrus-prefixed-formatter v0.5.2 // indirect
 | 
			
		||||
	github.com/yaegashi/msgraph.go v0.1.2
 | 
			
		||||
	github.com/zfjagann/golang-ring v0.0.0-20190106091943-a88bb6aef447
 | 
			
		||||
	golang.org/x/image v0.0.0-20191214001246-9130b4cfad52
 | 
			
		||||
	golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d
 | 
			
		||||
	gopkg.in/fsnotify.v1 v1.4.7 // indirect
 | 
			
		||||
	gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect
 | 
			
		||||
	gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect
 | 
			
		||||
	github.com/yaegashi/msgraph.go v0.1.4
 | 
			
		||||
	github.com/zfjagann/golang-ring v0.0.0-20190304061218-d34796e0a6c2
 | 
			
		||||
	golang.org/x/image v0.0.0-20200927104501-e162460cd6b5
 | 
			
		||||
	golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43
 | 
			
		||||
	gomod.garykim.dev/nc-talk v0.1.5
 | 
			
		||||
	gopkg.in/olahol/melody.v1 v1.0.0-20170518105555-d52139073376
 | 
			
		||||
	layeh.com/gumble v0.0.0-20200818122324-146f9205029b
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
//replace github.com/bwmarrin/discordgo v0.20.2 => github.com/matterbridge/discordgo v0.18.1-0.20200109173909-ed873362fa43
 | 
			
		||||
 | 
			
		||||
go 1.13
 | 
			
		||||
 
 | 
			
		||||
@@ -4,6 +4,7 @@ import (
 | 
			
		||||
	"flag"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"os"
 | 
			
		||||
	"runtime"
 | 
			
		||||
	"strings"
 | 
			
		||||
 | 
			
		||||
	"github.com/42wim/matterbridge/bridge/config"
 | 
			
		||||
@@ -15,7 +16,7 @@ import (
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	version = "1.17.3"
 | 
			
		||||
	version = "1.19.0"
 | 
			
		||||
	githash string
 | 
			
		||||
 | 
			
		||||
	flagConfig  = flag.String("conf", "matterbridge.toml", "config file")
 | 
			
		||||
@@ -50,6 +51,15 @@ func main() {
 | 
			
		||||
	cfg := config.NewConfig(rootLogger, *flagConfig)
 | 
			
		||||
	cfg.BridgeValues().General.Debug = *flagDebug
 | 
			
		||||
 | 
			
		||||
	// if logging to a file, ensure it is closed when the program terminates
 | 
			
		||||
	// nolint:errcheck
 | 
			
		||||
	defer func() {
 | 
			
		||||
		if f, ok := rootLogger.Out.(*os.File); ok {
 | 
			
		||||
			f.Sync()
 | 
			
		||||
			f.Close()
 | 
			
		||||
		}
 | 
			
		||||
	}()
 | 
			
		||||
 | 
			
		||||
	r, err := gateway.NewRouter(rootLogger, cfg, bridgemap.FullMap)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		logger.Fatalf("Starting gateway failed: %s", err)
 | 
			
		||||
@@ -67,17 +77,31 @@ func setupLogger() *logrus.Logger {
 | 
			
		||||
		Formatter: &prefixed.TextFormatter{
 | 
			
		||||
			PrefixPadding: 13,
 | 
			
		||||
			DisableColors: true,
 | 
			
		||||
			FullTimestamp: true,
 | 
			
		||||
		},
 | 
			
		||||
		Level: logrus.InfoLevel,
 | 
			
		||||
	}
 | 
			
		||||
	if *flagDebug || os.Getenv("DEBUG") == "1" {
 | 
			
		||||
		logger.SetReportCaller(true)
 | 
			
		||||
		logger.Formatter = &prefixed.TextFormatter{
 | 
			
		||||
			PrefixPadding:   13,
 | 
			
		||||
			DisableColors:   true,
 | 
			
		||||
			FullTimestamp:   false,
 | 
			
		||||
			ForceFormatting: true,
 | 
			
		||||
			PrefixPadding: 13,
 | 
			
		||||
			DisableColors: true,
 | 
			
		||||
			FullTimestamp: false,
 | 
			
		||||
 | 
			
		||||
			CallerFormatter: func(function, file string) string {
 | 
			
		||||
				return fmt.Sprintf(" [%s:%s]", function, file)
 | 
			
		||||
			},
 | 
			
		||||
			CallerPrettyfier: func(f *runtime.Frame) (string, string) {
 | 
			
		||||
				sp := strings.SplitAfter(f.File, "/matterbridge/")
 | 
			
		||||
				filename := f.File
 | 
			
		||||
				if len(sp) > 1 {
 | 
			
		||||
					filename = sp[1]
 | 
			
		||||
				}
 | 
			
		||||
				s := strings.Split(f.Function, ".")
 | 
			
		||||
				funcName := s[len(s)-1]
 | 
			
		||||
				return funcName, fmt.Sprintf("%s:%d", filename, f.Line)
 | 
			
		||||
			},
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		logger.Level = logrus.DebugLevel
 | 
			
		||||
		logger.WithFields(logrus.Fields{"prefix": "main"}).Info("Enabling debug logging.")
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
@@ -103,6 +103,10 @@ ColorNicks=false
 | 
			
		||||
#OPTIONAL (default empty)
 | 
			
		||||
RunCommands=["PRIVMSG user hello","PRIVMSG chanserv something"]
 | 
			
		||||
 | 
			
		||||
#StripMarkdown strips markdown from messages
 | 
			
		||||
#OPTIONAL (default false)
 | 
			
		||||
StripMarkdown=false
 | 
			
		||||
 | 
			
		||||
#Nicks you want to ignore.
 | 
			
		||||
#Regular expressions supported
 | 
			
		||||
#Messages from those users will not be sent to other bridges.
 | 
			
		||||
@@ -1209,6 +1213,11 @@ Password="yourpass"
 | 
			
		||||
#OPTIONAL (default false)
 | 
			
		||||
NoHomeServerSuffix=false
 | 
			
		||||
 | 
			
		||||
#Whether to disable sending of HTML content to matrix
 | 
			
		||||
#See https://github.com/42wim/matterbridge/issues/1022
 | 
			
		||||
#OPTIONAL (default false)
 | 
			
		||||
HTMLDisable=false
 | 
			
		||||
 | 
			
		||||
## RELOADABLE SETTINGS
 | 
			
		||||
## Settings below can be reloaded by editing the file
 | 
			
		||||
 | 
			
		||||
@@ -1374,7 +1383,76 @@ StripNick=false
 | 
			
		||||
#OPTIONAL (default false)
 | 
			
		||||
ShowTopicChange=false
 | 
			
		||||
 | 
			
		||||
###################################################################
 | 
			
		||||
#
 | 
			
		||||
# NCTalk (Nextcloud Talk)
 | 
			
		||||
#
 | 
			
		||||
###################################################################
 | 
			
		||||
 | 
			
		||||
[nctalk.bridge]
 | 
			
		||||
 | 
			
		||||
# Url of your Nextcloud server
 | 
			
		||||
Server = "https://cloud.youdomain.me"
 | 
			
		||||
 | 
			
		||||
# Enable to not verify the certificate on your Nextcloud server.
 | 
			
		||||
# e.g. when using selfsigned certificates
 | 
			
		||||
# OPTIONAL (default false)
 | 
			
		||||
SkipTLSVerify=true
 | 
			
		||||
 | 
			
		||||
# Username of the bot
 | 
			
		||||
Login = "talkuser"
 | 
			
		||||
 | 
			
		||||
# Password of the bot
 | 
			
		||||
Password = "talkuserpass"
 | 
			
		||||
 | 
			
		||||
# Suffix for Guest Users
 | 
			
		||||
GuestSuffix = " (Guest)"
 | 
			
		||||
 | 
			
		||||
###################################################################
 | 
			
		||||
#
 | 
			
		||||
# Mumble
 | 
			
		||||
#
 | 
			
		||||
###################################################################
 | 
			
		||||
 | 
			
		||||
[mumble.bridge]
 | 
			
		||||
 | 
			
		||||
# Host and port of your Mumble server
 | 
			
		||||
Server = "mumble.yourdomain.me:64738"
 | 
			
		||||
 | 
			
		||||
# Nickname to log in as
 | 
			
		||||
Nick = "matterbridge"
 | 
			
		||||
 | 
			
		||||
# Some servers require a password 
 | 
			
		||||
# OPTIONAL (default empty)
 | 
			
		||||
Password = "serverpasswordhere"
 | 
			
		||||
 | 
			
		||||
# User comment to set on the Mumble user, visible to other users.
 | 
			
		||||
# OPTIONAL (default empty)
 | 
			
		||||
UserComment="I am bridging text messages between this channel and #general on irc.yourdomain.me"
 | 
			
		||||
 | 
			
		||||
# Self-signed TLS client certificate + private key used to connect to
 | 
			
		||||
# Mumble.  This is required if you want to register the matterbridge
 | 
			
		||||
# user on your Mumble server, so its nick becomes reserved.
 | 
			
		||||
# You can generate a keypair using e.g.
 | 
			
		||||
#
 | 
			
		||||
#     openssl req -x509 -newkey rsa:2048 -nodes -days 10000 \
 | 
			
		||||
#             -keyout mumble.key -out mumble.crt
 | 
			
		||||
#
 | 
			
		||||
# To actually register the matterbridege user, connect to Mumble as an
 | 
			
		||||
# admin, right click on the user and click "Register".
 | 
			
		||||
#
 | 
			
		||||
# OPTIONAL (default empty)
 | 
			
		||||
TLSClientCertificate="mumble.crt"
 | 
			
		||||
TLSClientKey="mumble.key"
 | 
			
		||||
 | 
			
		||||
# TLS CA certificate used to validate the Mumble server.
 | 
			
		||||
# OPTIONAL (defaults to Go system CA)
 | 
			
		||||
TLSCACertificate=mumble-ca.crt
 | 
			
		||||
 | 
			
		||||
# Enable to not verify the certificate on your Mumble server.
 | 
			
		||||
# e.g. when using selfsigned certificates
 | 
			
		||||
# OPTIONAL (default false)
 | 
			
		||||
SkipTLSVerify=false
 | 
			
		||||
 | 
			
		||||
###################################################################
 | 
			
		||||
#
 | 
			
		||||
@@ -1516,6 +1594,8 @@ Buffer=1000
 | 
			
		||||
 | 
			
		||||
#Bearer token used for authentication
 | 
			
		||||
#curl -H "Authorization: Bearer token" http://localhost:4242/api/messages
 | 
			
		||||
# https://github.com/vi/websocat
 | 
			
		||||
# websocat -H="Authorization: Bearer token" ws://127.0.0.1:4242/api/websocket
 | 
			
		||||
#OPTIONAL (no authorization if token is empty)
 | 
			
		||||
Token="mytoken"
 | 
			
		||||
 | 
			
		||||
@@ -1595,6 +1675,14 @@ MediaDownloadBlacklist=[".html$",".htm$"]
 | 
			
		||||
#OPTIONAL (default false)
 | 
			
		||||
IgnoreFailureOnStart=false
 | 
			
		||||
 | 
			
		||||
#LogFile defines the location of a file to write logs into, rather
 | 
			
		||||
#than stdout.
 | 
			
		||||
#Logging will still happen on stdout if the file cannot be open for
 | 
			
		||||
#writing, or if the value is empty. Note that the log won't roll, so
 | 
			
		||||
#you might want to use logrotate(8) with this feature.
 | 
			
		||||
#OPTIONAL (default empty)
 | 
			
		||||
LogFile="/var/log/matterbridge.log"
 | 
			
		||||
 | 
			
		||||
###################################################################
 | 
			
		||||
#Tengo configuration
 | 
			
		||||
###################################################################
 | 
			
		||||
@@ -1685,7 +1773,7 @@ enable=true
 | 
			
		||||
    # REQUIRED
 | 
			
		||||
    account="irc.freenode"
 | 
			
		||||
 | 
			
		||||
    # The channel key in each gateway is mapped to a similar group chat ID on the chat platform 
 | 
			
		||||
    # The channel key in each gateway is mapped to a similar group chat ID on the chat platform
 | 
			
		||||
    # To find the group chat ID for different platforms, refer to the table below
 | 
			
		||||
    #
 | 
			
		||||
    # Platform   |   Identifier name  |            Example            | Description
 | 
			
		||||
@@ -1706,6 +1794,8 @@ enable=true
 | 
			
		||||
    # -------------------------------------------------------------------------------------------------------------------------------------
 | 
			
		||||
    #   msteams  |      threadId      |    19:82abcxx@thread.skype    | You'll find the threadId in the URL
 | 
			
		||||
    # -------------------------------------------------------------------------------------------------------------------------------------
 | 
			
		||||
    #   mumble   |    channel id      |              42               | The channel ID, as shown in the channel's "Edit" window
 | 
			
		||||
    # -------------------------------------------------------------------------------------------------------------------------------------
 | 
			
		||||
    # rocketchat |      channel       |            #channel           | # is required for private channels too
 | 
			
		||||
    # -------------------------------------------------------------------------------------------------------------------------------------
 | 
			
		||||
    #   slack    |   channel name     |            general            | Do not include the # symbol
 | 
			
		||||
@@ -1713,6 +1803,8 @@ enable=true
 | 
			
		||||
    # -------------------------------------------------------------------------------------------------------------------------------------
 | 
			
		||||
    #   steam    |      chatid        |         example needed        | The number in the URL when you click "enter chat room" in the browser
 | 
			
		||||
    # -------------------------------------------------------------------------------------------------------------------------------------
 | 
			
		||||
    #   nctalk   |      token         |           xs25tz5y            | The token in the URL when you are in a chat. It will be the last part of the URL.
 | 
			
		||||
    # -------------------------------------------------------------------------------------------------------------------------------------
 | 
			
		||||
    #  telegram  |      chatid        |          -123456789           | A large negative number. see https://www.linkedin.com/pulse/telegram-bots-beginners-marco-frau
 | 
			
		||||
    # -------------------------------------------------------------------------------------------------------------------------------------
 | 
			
		||||
    #  whatsapp  |     group JID      | 48111222333-123455678999@g.us | A unique group JID. If you specify an empty string, bridge will list all the possibilities
 | 
			
		||||
 
 | 
			
		||||
@@ -4,7 +4,7 @@ import (
 | 
			
		||||
	"errors"
 | 
			
		||||
	"strings"
 | 
			
		||||
 | 
			
		||||
	"github.com/mattermost/mattermost-server/model"
 | 
			
		||||
	"github.com/mattermost/mattermost-server/v5/model"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// GetChannels returns all channels we're members off
 | 
			
		||||
@@ -167,7 +167,7 @@ func (m *MMClient) JoinChannel(channelId string) error { //nolint:golint
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *MMClient) UpdateChannelsTeam(teamID string) error {
 | 
			
		||||
	mmchannels, resp := m.Client.GetChannelsForTeamForUser(teamID, m.User.Id, "")
 | 
			
		||||
	mmchannels, resp := m.Client.GetChannelsForTeamForUser(teamID, m.User.Id, false, "")
 | 
			
		||||
	if resp.Error != nil {
 | 
			
		||||
		return errors.New(resp.Error.DetailedError)
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
@@ -13,7 +13,7 @@ import (
 | 
			
		||||
 | 
			
		||||
	"github.com/gorilla/websocket"
 | 
			
		||||
	"github.com/jpillora/backoff"
 | 
			
		||||
	"github.com/mattermost/mattermost-server/model"
 | 
			
		||||
	"github.com/mattermost/mattermost-server/v5/model"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func (m *MMClient) doLogin(firstConnection bool, b *backoff.Backoff) error {
 | 
			
		||||
@@ -154,7 +154,7 @@ func (m *MMClient) initUser() error {
 | 
			
		||||
 | 
			
		||||
		t := &Team{Team: team, Users: usermap, Id: team.Id}
 | 
			
		||||
 | 
			
		||||
		mmchannels, resp := m.Client.GetChannelsForTeamForUser(team.Id, m.User.Id, "")
 | 
			
		||||
		mmchannels, resp := m.Client.GetChannelsForTeamForUser(team.Id, m.User.Id, false, "")
 | 
			
		||||
		if resp.Error != nil {
 | 
			
		||||
			return resp.Error
 | 
			
		||||
		}
 | 
			
		||||
 
 | 
			
		||||
@@ -11,7 +11,7 @@ import (
 | 
			
		||||
	lru "github.com/hashicorp/golang-lru"
 | 
			
		||||
	"github.com/jpillora/backoff"
 | 
			
		||||
	prefixed "github.com/matterbridge/logrus-prefixed-formatter"
 | 
			
		||||
	"github.com/mattermost/mattermost-server/model"
 | 
			
		||||
	"github.com/mattermost/mattermost-server/v5/model"
 | 
			
		||||
	"github.com/sirupsen/logrus"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
@@ -69,6 +69,7 @@ type MMClient struct {
 | 
			
		||||
	logger     *logrus.Entry
 | 
			
		||||
	rootLogger *logrus.Logger
 | 
			
		||||
	lruCache   *lru.Cache
 | 
			
		||||
	allevents  bool
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// New will instantiate a new Matterclient with the specified login details without connecting.
 | 
			
		||||
@@ -119,6 +120,10 @@ func (m *MMClient) SetLogLevel(level string) {
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *MMClient) EnableAllEvents() {
 | 
			
		||||
	m.allevents = true
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Login tries to connect the client with the loging details with which it was initialized.
 | 
			
		||||
func (m *MMClient) Login() error {
 | 
			
		||||
	// check if this is a first connect or a reconnection
 | 
			
		||||
@@ -220,6 +225,10 @@ func (m *MMClient) WsReceiver() {
 | 
			
		||||
					continue
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			if m.allevents {
 | 
			
		||||
				m.MessageChan <- msg
 | 
			
		||||
				continue
 | 
			
		||||
			}
 | 
			
		||||
			switch msg.Raw.Event {
 | 
			
		||||
			case model.WEBSOCKET_EVENT_USER_ADDED,
 | 
			
		||||
				model.WEBSOCKET_EVENT_USER_REMOVED,
 | 
			
		||||
 
 | 
			
		||||
@@ -3,7 +3,7 @@ package matterclient
 | 
			
		||||
import (
 | 
			
		||||
	"strings"
 | 
			
		||||
 | 
			
		||||
	"github.com/mattermost/mattermost-server/model"
 | 
			
		||||
	"github.com/mattermost/mattermost-server/v5/model"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func (m *MMClient) parseActionPost(rmsg *Message) {
 | 
			
		||||
 
 | 
			
		||||
@@ -4,7 +4,7 @@ import (
 | 
			
		||||
	"errors"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"github.com/mattermost/mattermost-server/model"
 | 
			
		||||
	"github.com/mattermost/mattermost-server/v5/model"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func (m *MMClient) GetNickName(userId string) string { //nolint:golint
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										38
									
								
								tgs.Dockerfile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								tgs.Dockerfile
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,38 @@
 | 
			
		||||
FROM alpine AS builder
 | 
			
		||||
 | 
			
		||||
COPY . /go/src/github.com/42wim/matterbridge
 | 
			
		||||
RUN apk add \
 | 
			
		||||
    go \
 | 
			
		||||
    git \
 | 
			
		||||
    gcc \
 | 
			
		||||
    musl-dev \
 | 
			
		||||
  && cd /go/src/github.com/42wim/matterbridge \
 | 
			
		||||
  && export GOPATH=/go \
 | 
			
		||||
  && go get \
 | 
			
		||||
  && go build -x -ldflags "-X main.githash=$(git log --pretty=format:'%h' -n 1)" -o /bin/matterbridge
 | 
			
		||||
 | 
			
		||||
FROM alpine
 | 
			
		||||
RUN apk --no-cache add \
 | 
			
		||||
    ca-certificates \
 | 
			
		||||
    cairo \
 | 
			
		||||
    libjpeg-turbo \
 | 
			
		||||
    mailcap \
 | 
			
		||||
    py3-webencodings \
 | 
			
		||||
    python3 \
 | 
			
		||||
  && apk --no-cache add --virtual .compile \
 | 
			
		||||
    gcc \
 | 
			
		||||
    libffi-dev \
 | 
			
		||||
    libjpeg-turbo-dev \
 | 
			
		||||
    musl-dev \
 | 
			
		||||
    py3-pip \
 | 
			
		||||
    py3-wheel \
 | 
			
		||||
    python3-dev \
 | 
			
		||||
    zlib-dev \
 | 
			
		||||
  && pip3 install --no-cache-dir lottie[PNG] \
 | 
			
		||||
  && apk --no-cache del .compile
 | 
			
		||||
 | 
			
		||||
COPY --from=builder /bin/matterbridge /bin/matterbridge
 | 
			
		||||
RUN mkdir /etc/matterbridge \
 | 
			
		||||
  && touch /etc/matterbridge/matterbridge.toml \
 | 
			
		||||
  && ln -sf /matterbridge.toml /etc/matterbridge/matterbridge.toml
 | 
			
		||||
ENTRYPOINT ["/bin/matterbridge", "-conf", "/etc/matterbridge/matterbridge.toml"]
 | 
			
		||||
							
								
								
									
										5
									
								
								vendor/github.com/Philipp15b/go-steam/.gitmodules
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										5
									
								
								vendor/github.com/Philipp15b/go-steam/.gitmodules
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,3 +1,6 @@
 | 
			
		||||
[submodule "generator/SteamKit"]
 | 
			
		||||
	path = generator/SteamKit
 | 
			
		||||
	url = https://github.com/Philipp15b/SteamKit.git
 | 
			
		||||
	url = https://github.com/SteamRE/SteamKit.git
 | 
			
		||||
[submodule "generator/Protobufs"]
 | 
			
		||||
	path = generator/Protobufs
 | 
			
		||||
	url = https://github.com/SteamDatabase/Protobufs.git
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										4
									
								
								vendor/github.com/Philipp15b/go-steam/auth.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								vendor/github.com/Philipp15b/go-steam/auth.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -119,7 +119,7 @@ func (a *Auth) handleLogOnResponse(packet *Packet) {
 | 
			
		||||
			ExtendedResult:            EResult(body.GetEresultExtended()),
 | 
			
		||||
			OutOfGameSecsPerHeartbeat: body.GetOutOfGameHeartbeatSeconds(),
 | 
			
		||||
			InGameSecsPerHeartbeat:    body.GetInGameHeartbeatSeconds(),
 | 
			
		||||
			PublicIp:                  body.GetPublicIp(),
 | 
			
		||||
			PublicIp:                  body.GetDeprecatedPublicIp(),
 | 
			
		||||
			ServerTime:                body.GetRtime32ServerTime(),
 | 
			
		||||
			AccountFlags:              EAccountFlags(body.GetAccountFlags()),
 | 
			
		||||
			ClientSteamId:             SteamId(body.GetClientSuppliedSteamid()),
 | 
			
		||||
@@ -127,7 +127,7 @@ func (a *Auth) handleLogOnResponse(packet *Packet) {
 | 
			
		||||
			CellId:                    body.GetCellId(),
 | 
			
		||||
			CellIdPingThreshold:       body.GetCellIdPingThreshold(),
 | 
			
		||||
			Steam2Ticket:              body.GetSteam2Ticket(),
 | 
			
		||||
			UsePics:                   body.GetUsePics(),
 | 
			
		||||
			UsePics:                   body.GetDeprecatedUsePics(),
 | 
			
		||||
			WebApiUserNonce:           body.GetWebapiAuthenticateUserNonce(),
 | 
			
		||||
			IpCountryCode:             body.GetIpCountryCode(),
 | 
			
		||||
			VanityUrl:                 body.GetVanityUrl(),
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										8
									
								
								vendor/github.com/Philipp15b/go-steam/go.mod
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								vendor/github.com/Philipp15b/go-steam/go.mod
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,8 @@
 | 
			
		||||
module github.com/Philipp15b/go-steam
 | 
			
		||||
 | 
			
		||||
go 1.14
 | 
			
		||||
 | 
			
		||||
require (
 | 
			
		||||
	github.com/davecgh/go-spew v1.1.1
 | 
			
		||||
	github.com/golang/protobuf v1.4.2
 | 
			
		||||
)
 | 
			
		||||
							
								
								
									
										22
									
								
								vendor/github.com/Philipp15b/go-steam/go.sum
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								vendor/github.com/Philipp15b/go-steam/go.sum
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,22 @@
 | 
			
		||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
 | 
			
		||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 | 
			
		||||
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
 | 
			
		||||
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
 | 
			
		||||
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
 | 
			
		||||
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
 | 
			
		||||
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
 | 
			
		||||
github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0=
 | 
			
		||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
 | 
			
		||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
 | 
			
		||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
 | 
			
		||||
github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4=
 | 
			
		||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 | 
			
		||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
 | 
			
		||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 | 
			
		||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
 | 
			
		||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
 | 
			
		||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
 | 
			
		||||
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
 | 
			
		||||
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
 | 
			
		||||
google.golang.org/protobuf v1.23.0 h1:4MY060fB1DLGMB/7MBTLnwQUY6+F09GEiz6SsrNqyzM=
 | 
			
		||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
 | 
			
		||||
							
								
								
									
										32
									
								
								vendor/github.com/Philipp15b/go-steam/protocol/protobuf/app_ticket.pb.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										32
									
								
								vendor/github.com/Philipp15b/go-steam/protocol/protobuf/app_ticket.pb.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -21,11 +21,11 @@ var _ = math.Inf
 | 
			
		||||
const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
 | 
			
		||||
 | 
			
		||||
type EncryptedAppTicket struct {
 | 
			
		||||
	TicketVersionNo               *uint32  `protobuf:"varint,1,opt,name=ticket_version_no" json:"ticket_version_no,omitempty"`
 | 
			
		||||
	CrcEncryptedticket            *uint32  `protobuf:"varint,2,opt,name=crc_encryptedticket" json:"crc_encryptedticket,omitempty"`
 | 
			
		||||
	CbEncrypteduserdata           *uint32  `protobuf:"varint,3,opt,name=cb_encrypteduserdata" json:"cb_encrypteduserdata,omitempty"`
 | 
			
		||||
	CbEncryptedAppownershipticket *uint32  `protobuf:"varint,4,opt,name=cb_encrypted_appownershipticket" json:"cb_encrypted_appownershipticket,omitempty"`
 | 
			
		||||
	EncryptedTicket               []byte   `protobuf:"bytes,5,opt,name=encrypted_ticket" json:"encrypted_ticket,omitempty"`
 | 
			
		||||
	TicketVersionNo               *uint32  `protobuf:"varint,1,opt,name=ticket_version_no,json=ticketVersionNo" json:"ticket_version_no,omitempty"`
 | 
			
		||||
	CrcEncryptedticket            *uint32  `protobuf:"varint,2,opt,name=crc_encryptedticket,json=crcEncryptedticket" json:"crc_encryptedticket,omitempty"`
 | 
			
		||||
	CbEncrypteduserdata           *uint32  `protobuf:"varint,3,opt,name=cb_encrypteduserdata,json=cbEncrypteduserdata" json:"cb_encrypteduserdata,omitempty"`
 | 
			
		||||
	CbEncryptedAppownershipticket *uint32  `protobuf:"varint,4,opt,name=cb_encrypted_appownershipticket,json=cbEncryptedAppownershipticket" json:"cb_encrypted_appownershipticket,omitempty"`
 | 
			
		||||
	EncryptedTicket               []byte   `protobuf:"bytes,5,opt,name=encrypted_ticket,json=encryptedTicket" json:"encrypted_ticket,omitempty"`
 | 
			
		||||
	XXX_NoUnkeyedLiteral          struct{} `json:"-"`
 | 
			
		||||
	XXX_unrecognized              []byte   `json:"-"`
 | 
			
		||||
	XXX_sizecache                 int32    `json:"-"`
 | 
			
		||||
@@ -98,16 +98,18 @@ func init() {
 | 
			
		||||
func init() { proto.RegisterFile("encrypted_app_ticket.proto", fileDescriptor_c6d69fd1cac4e8d5) }
 | 
			
		||||
 | 
			
		||||
var fileDescriptor_c6d69fd1cac4e8d5 = []byte{
 | 
			
		||||
	// 164 bytes of a gzipped FileDescriptorProto
 | 
			
		||||
	// 202 bytes of a gzipped FileDescriptorProto
 | 
			
		||||
	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0x4a, 0xcd, 0x4b, 0x2e,
 | 
			
		||||
	0xaa, 0x2c, 0x28, 0x49, 0x4d, 0x89, 0x4f, 0x2c, 0x28, 0x88, 0x2f, 0xc9, 0x4c, 0xce, 0x4e, 0x2d,
 | 
			
		||||
	0xd1, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x57, 0x5a, 0xcb, 0xc8, 0x25, 0xe4, 0x0a, 0x93, 0x76, 0x2c,
 | 
			
		||||
	0x28, 0x08, 0x01, 0x4b, 0x0a, 0x49, 0x72, 0x09, 0x42, 0x94, 0xc5, 0x97, 0xa5, 0x16, 0x15, 0x67,
 | 
			
		||||
	0xe6, 0xe7, 0xc5, 0xe7, 0xe5, 0x4b, 0x30, 0x2a, 0x30, 0x6a, 0xf0, 0x0a, 0x49, 0x73, 0x09, 0x27,
 | 
			
		||||
	0x17, 0x25, 0xc7, 0xc3, 0xcd, 0x84, 0xa8, 0x93, 0x60, 0x02, 0x4b, 0xca, 0x70, 0x89, 0x24, 0x27,
 | 
			
		||||
	0x21, 0xe4, 0x4a, 0x8b, 0x53, 0x8b, 0x52, 0x12, 0x4b, 0x12, 0x25, 0x98, 0xc1, 0xb2, 0xea, 0x5c,
 | 
			
		||||
	0xf2, 0xc8, 0xb2, 0x20, 0xd7, 0xe4, 0x97, 0xe7, 0xa5, 0x16, 0x15, 0x67, 0x64, 0x16, 0x40, 0x8d,
 | 
			
		||||
	0x61, 0x01, 0x2b, 0x94, 0xe0, 0x12, 0x40, 0xa8, 0x82, 0xca, 0xb0, 0x2a, 0x30, 0x6a, 0xf0, 0x38,
 | 
			
		||||
	0xb1, 0x7a, 0x30, 0x36, 0x30, 0x32, 0x00, 0x02, 0x00, 0x00, 0xff, 0xff, 0x03, 0x8c, 0xdb, 0x92,
 | 
			
		||||
	0xd3, 0x00, 0x00, 0x00,
 | 
			
		||||
	0xd1, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x57, 0x9a, 0xce, 0xc4, 0x25, 0xe4, 0x0a, 0x93, 0x76, 0x2c,
 | 
			
		||||
	0x28, 0x08, 0x01, 0x4b, 0x0a, 0x69, 0x71, 0x09, 0x42, 0x94, 0xc5, 0x97, 0xa5, 0x16, 0x15, 0x67,
 | 
			
		||||
	0xe6, 0xe7, 0xc5, 0xe7, 0xe5, 0x4b, 0x30, 0x2a, 0x30, 0x6a, 0xf0, 0x06, 0xf1, 0x43, 0x24, 0xc2,
 | 
			
		||||
	0x20, 0xe2, 0x7e, 0xf9, 0x42, 0xfa, 0x5c, 0xc2, 0xc9, 0x45, 0xc9, 0xf1, 0x70, 0x4b, 0x20, 0xf2,
 | 
			
		||||
	0x12, 0x4c, 0x60, 0xd5, 0x42, 0xc9, 0x45, 0xc9, 0xae, 0xa8, 0x32, 0x42, 0x86, 0x5c, 0x22, 0xc9,
 | 
			
		||||
	0x49, 0x08, 0xf5, 0xa5, 0xc5, 0xa9, 0x45, 0x29, 0x89, 0x25, 0x89, 0x12, 0xcc, 0x60, 0x1d, 0xc2,
 | 
			
		||||
	0xc9, 0x49, 0xae, 0xe8, 0x52, 0x42, 0x6e, 0x5c, 0xf2, 0xc8, 0x5a, 0x40, 0xfe, 0xc8, 0x2f, 0xcf,
 | 
			
		||||
	0x4b, 0x2d, 0x2a, 0xce, 0xc8, 0x2c, 0x80, 0xda, 0xc7, 0x02, 0xd6, 0x2d, 0x8b, 0xa4, 0xdb, 0x11,
 | 
			
		||||
	0x43, 0x91, 0x90, 0x26, 0x97, 0x00, 0xc2, 0x10, 0xa8, 0x46, 0x56, 0x05, 0x46, 0x0d, 0x9e, 0x20,
 | 
			
		||||
	0x7e, 0xb8, 0x38, 0x24, 0x08, 0x9c, 0x58, 0x3d, 0x18, 0x1b, 0x18, 0x19, 0x00, 0x01, 0x00, 0x00,
 | 
			
		||||
	0xff, 0xff, 0xe8, 0x03, 0x98, 0x21, 0x3d, 0x01, 0x00, 0x00,
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										1221
									
								
								vendor/github.com/Philipp15b/go-steam/protocol/protobuf/base.pb.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										1221
									
								
								vendor/github.com/Philipp15b/go-steam/protocol/protobuf/base.pb.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										2801
									
								
								vendor/github.com/Philipp15b/go-steam/protocol/protobuf/client_server.pb.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2801
									
								
								vendor/github.com/Philipp15b/go-steam/protocol/protobuf/client_server.pb.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										2860
									
								
								vendor/github.com/Philipp15b/go-steam/protocol/protobuf/client_server_2.pb.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2860
									
								
								vendor/github.com/Philipp15b/go-steam/protocol/protobuf/client_server_2.pb.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										531
									
								
								vendor/github.com/Philipp15b/go-steam/protocol/protobuf/client_server_friends.pb.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										531
									
								
								vendor/github.com/Philipp15b/go-steam/protocol/protobuf/client_server_friends.pb.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -22,10 +22,10 @@ const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
 | 
			
		||||
 | 
			
		||||
type CMsgClientFriendMsg struct {
 | 
			
		||||
	Steamid                *uint64  `protobuf:"fixed64,1,opt,name=steamid" json:"steamid,omitempty"`
 | 
			
		||||
	ChatEntryType          *int32   `protobuf:"varint,2,opt,name=chat_entry_type" json:"chat_entry_type,omitempty"`
 | 
			
		||||
	ChatEntryType          *int32   `protobuf:"varint,2,opt,name=chat_entry_type,json=chatEntryType" json:"chat_entry_type,omitempty"`
 | 
			
		||||
	Message                []byte   `protobuf:"bytes,3,opt,name=message" json:"message,omitempty"`
 | 
			
		||||
	Rtime32ServerTimestamp *uint32  `protobuf:"fixed32,4,opt,name=rtime32_server_timestamp" json:"rtime32_server_timestamp,omitempty"`
 | 
			
		||||
	EchoToSender           *bool    `protobuf:"varint,5,opt,name=echo_to_sender" json:"echo_to_sender,omitempty"`
 | 
			
		||||
	Rtime32ServerTimestamp *uint32  `protobuf:"fixed32,4,opt,name=rtime32_server_timestamp,json=rtime32ServerTimestamp" json:"rtime32_server_timestamp,omitempty"`
 | 
			
		||||
	EchoToSender           *bool    `protobuf:"varint,5,opt,name=echo_to_sender,json=echoToSender" json:"echo_to_sender,omitempty"`
 | 
			
		||||
	XXX_NoUnkeyedLiteral   struct{} `json:"-"`
 | 
			
		||||
	XXX_unrecognized       []byte   `json:"-"`
 | 
			
		||||
	XXX_sizecache          int32    `json:"-"`
 | 
			
		||||
@@ -92,11 +92,11 @@ func (m *CMsgClientFriendMsg) GetEchoToSender() bool {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type CMsgClientFriendMsgIncoming struct {
 | 
			
		||||
	SteamidFrom            *uint64  `protobuf:"fixed64,1,opt,name=steamid_from" json:"steamid_from,omitempty"`
 | 
			
		||||
	ChatEntryType          *int32   `protobuf:"varint,2,opt,name=chat_entry_type" json:"chat_entry_type,omitempty"`
 | 
			
		||||
	FromLimitedAccount     *bool    `protobuf:"varint,3,opt,name=from_limited_account" json:"from_limited_account,omitempty"`
 | 
			
		||||
	SteamidFrom            *uint64  `protobuf:"fixed64,1,opt,name=steamid_from,json=steamidFrom" json:"steamid_from,omitempty"`
 | 
			
		||||
	ChatEntryType          *int32   `protobuf:"varint,2,opt,name=chat_entry_type,json=chatEntryType" json:"chat_entry_type,omitempty"`
 | 
			
		||||
	FromLimitedAccount     *bool    `protobuf:"varint,3,opt,name=from_limited_account,json=fromLimitedAccount" json:"from_limited_account,omitempty"`
 | 
			
		||||
	Message                []byte   `protobuf:"bytes,4,opt,name=message" json:"message,omitempty"`
 | 
			
		||||
	Rtime32ServerTimestamp *uint32  `protobuf:"fixed32,5,opt,name=rtime32_server_timestamp" json:"rtime32_server_timestamp,omitempty"`
 | 
			
		||||
	Rtime32ServerTimestamp *uint32  `protobuf:"fixed32,5,opt,name=rtime32_server_timestamp,json=rtime32ServerTimestamp" json:"rtime32_server_timestamp,omitempty"`
 | 
			
		||||
	XXX_NoUnkeyedLiteral   struct{} `json:"-"`
 | 
			
		||||
	XXX_unrecognized       []byte   `json:"-"`
 | 
			
		||||
	XXX_sizecache          int32    `json:"-"`
 | 
			
		||||
@@ -163,8 +163,8 @@ func (m *CMsgClientFriendMsgIncoming) GetRtime32ServerTimestamp() uint32 {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type CMsgClientAddFriend struct {
 | 
			
		||||
	SteamidToAdd            *uint64  `protobuf:"fixed64,1,opt,name=steamid_to_add" json:"steamid_to_add,omitempty"`
 | 
			
		||||
	AccountnameOrEmailToAdd *string  `protobuf:"bytes,2,opt,name=accountname_or_email_to_add" json:"accountname_or_email_to_add,omitempty"`
 | 
			
		||||
	SteamidToAdd            *uint64  `protobuf:"fixed64,1,opt,name=steamid_to_add,json=steamidToAdd" json:"steamid_to_add,omitempty"`
 | 
			
		||||
	AccountnameOrEmailToAdd *string  `protobuf:"bytes,2,opt,name=accountname_or_email_to_add,json=accountnameOrEmailToAdd" json:"accountname_or_email_to_add,omitempty"`
 | 
			
		||||
	XXX_NoUnkeyedLiteral    struct{} `json:"-"`
 | 
			
		||||
	XXX_unrecognized        []byte   `json:"-"`
 | 
			
		||||
	XXX_sizecache           int32    `json:"-"`
 | 
			
		||||
@@ -211,8 +211,8 @@ func (m *CMsgClientAddFriend) GetAccountnameOrEmailToAdd() string {
 | 
			
		||||
 | 
			
		||||
type CMsgClientAddFriendResponse struct {
 | 
			
		||||
	Eresult              *int32   `protobuf:"varint,1,opt,name=eresult,def=2" json:"eresult,omitempty"`
 | 
			
		||||
	SteamIdAdded         *uint64  `protobuf:"fixed64,2,opt,name=steam_id_added" json:"steam_id_added,omitempty"`
 | 
			
		||||
	PersonaNameAdded     *string  `protobuf:"bytes,3,opt,name=persona_name_added" json:"persona_name_added,omitempty"`
 | 
			
		||||
	SteamIdAdded         *uint64  `protobuf:"fixed64,2,opt,name=steam_id_added,json=steamIdAdded" json:"steam_id_added,omitempty"`
 | 
			
		||||
	PersonaNameAdded     *string  `protobuf:"bytes,3,opt,name=persona_name_added,json=personaNameAdded" json:"persona_name_added,omitempty"`
 | 
			
		||||
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
 | 
			
		||||
	XXX_unrecognized     []byte   `json:"-"`
 | 
			
		||||
	XXX_sizecache        int32    `json:"-"`
 | 
			
		||||
@@ -355,9 +355,9 @@ func (m *CMsgClientHideFriend) GetHide() bool {
 | 
			
		||||
type CMsgClientFriendsList struct {
 | 
			
		||||
	Bincremental         *bool                           `protobuf:"varint,1,opt,name=bincremental" json:"bincremental,omitempty"`
 | 
			
		||||
	Friends              []*CMsgClientFriendsList_Friend `protobuf:"bytes,2,rep,name=friends" json:"friends,omitempty"`
 | 
			
		||||
	MaxFriendCount       *uint32                         `protobuf:"varint,3,opt,name=max_friend_count" json:"max_friend_count,omitempty"`
 | 
			
		||||
	ActiveFriendCount    *uint32                         `protobuf:"varint,4,opt,name=active_friend_count" json:"active_friend_count,omitempty"`
 | 
			
		||||
	FriendsLimitHit      *bool                           `protobuf:"varint,5,opt,name=friends_limit_hit" json:"friends_limit_hit,omitempty"`
 | 
			
		||||
	MaxFriendCount       *uint32                         `protobuf:"varint,3,opt,name=max_friend_count,json=maxFriendCount" json:"max_friend_count,omitempty"`
 | 
			
		||||
	ActiveFriendCount    *uint32                         `protobuf:"varint,4,opt,name=active_friend_count,json=activeFriendCount" json:"active_friend_count,omitempty"`
 | 
			
		||||
	FriendsLimitHit      *bool                           `protobuf:"varint,5,opt,name=friends_limit_hit,json=friendsLimitHit" json:"friends_limit_hit,omitempty"`
 | 
			
		||||
	XXX_NoUnkeyedLiteral struct{}                        `json:"-"`
 | 
			
		||||
	XXX_unrecognized     []byte                          `json:"-"`
 | 
			
		||||
	XXX_sizecache        int32                           `json:"-"`
 | 
			
		||||
@@ -826,7 +826,7 @@ func (m *CMsgClientSetPlayerNicknameResponse) GetEresult() uint32 {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type CMsgClientRequestFriendData struct {
 | 
			
		||||
	PersonaStateRequested *uint32  `protobuf:"varint,1,opt,name=persona_state_requested" json:"persona_state_requested,omitempty"`
 | 
			
		||||
	PersonaStateRequested *uint32  `protobuf:"varint,1,opt,name=persona_state_requested,json=personaStateRequested" json:"persona_state_requested,omitempty"`
 | 
			
		||||
	Friends               []uint64 `protobuf:"fixed64,2,rep,name=friends" json:"friends,omitempty"`
 | 
			
		||||
	XXX_NoUnkeyedLiteral  struct{} `json:"-"`
 | 
			
		||||
	XXX_unrecognized      []byte   `json:"-"`
 | 
			
		||||
@@ -873,14 +873,14 @@ func (m *CMsgClientRequestFriendData) GetFriends() []uint64 {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type CMsgClientChangeStatus struct {
 | 
			
		||||
	PersonaState         *uint32  `protobuf:"varint,1,opt,name=persona_state" json:"persona_state,omitempty"`
 | 
			
		||||
	PlayerName           *string  `protobuf:"bytes,2,opt,name=player_name" json:"player_name,omitempty"`
 | 
			
		||||
	IsAutoGeneratedName  *bool    `protobuf:"varint,3,opt,name=is_auto_generated_name" json:"is_auto_generated_name,omitempty"`
 | 
			
		||||
	HighPriority         *bool    `protobuf:"varint,4,opt,name=high_priority" json:"high_priority,omitempty"`
 | 
			
		||||
	PersonaSetByUser     *bool    `protobuf:"varint,5,opt,name=persona_set_by_user" json:"persona_set_by_user,omitempty"`
 | 
			
		||||
	PersonaStateFlags    *uint32  `protobuf:"varint,6,opt,name=persona_state_flags,def=0" json:"persona_state_flags,omitempty"`
 | 
			
		||||
	NeedPersonaResponse  *bool    `protobuf:"varint,7,opt,name=need_persona_response" json:"need_persona_response,omitempty"`
 | 
			
		||||
	IsClientIdle         *bool    `protobuf:"varint,8,opt,name=is_client_idle" json:"is_client_idle,omitempty"`
 | 
			
		||||
	PersonaState         *uint32  `protobuf:"varint,1,opt,name=persona_state,json=personaState" json:"persona_state,omitempty"`
 | 
			
		||||
	PlayerName           *string  `protobuf:"bytes,2,opt,name=player_name,json=playerName" json:"player_name,omitempty"`
 | 
			
		||||
	IsAutoGeneratedName  *bool    `protobuf:"varint,3,opt,name=is_auto_generated_name,json=isAutoGeneratedName" json:"is_auto_generated_name,omitempty"`
 | 
			
		||||
	HighPriority         *bool    `protobuf:"varint,4,opt,name=high_priority,json=highPriority" json:"high_priority,omitempty"`
 | 
			
		||||
	PersonaSetByUser     *bool    `protobuf:"varint,5,opt,name=persona_set_by_user,json=personaSetByUser" json:"persona_set_by_user,omitempty"`
 | 
			
		||||
	PersonaStateFlags    *uint32  `protobuf:"varint,6,opt,name=persona_state_flags,json=personaStateFlags,def=0" json:"persona_state_flags,omitempty"`
 | 
			
		||||
	NeedPersonaResponse  *bool    `protobuf:"varint,7,opt,name=need_persona_response,json=needPersonaResponse" json:"need_persona_response,omitempty"`
 | 
			
		||||
	IsClientIdle         *bool    `protobuf:"varint,8,opt,name=is_client_idle,json=isClientIdle" json:"is_client_idle,omitempty"`
 | 
			
		||||
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
 | 
			
		||||
	XXX_unrecognized     []byte   `json:"-"`
 | 
			
		||||
	XXX_sizecache        int32    `json:"-"`
 | 
			
		||||
@@ -971,7 +971,7 @@ func (m *CMsgClientChangeStatus) GetIsClientIdle() bool {
 | 
			
		||||
 | 
			
		||||
type CMsgPersonaChangeResponse struct {
 | 
			
		||||
	Result               *uint32  `protobuf:"varint,1,opt,name=result" json:"result,omitempty"`
 | 
			
		||||
	PlayerName           *string  `protobuf:"bytes,2,opt,name=player_name" json:"player_name,omitempty"`
 | 
			
		||||
	PlayerName           *string  `protobuf:"bytes,2,opt,name=player_name,json=playerName" json:"player_name,omitempty"`
 | 
			
		||||
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
 | 
			
		||||
	XXX_unrecognized     []byte   `json:"-"`
 | 
			
		||||
	XXX_sizecache        int32    `json:"-"`
 | 
			
		||||
@@ -1017,7 +1017,7 @@ func (m *CMsgPersonaChangeResponse) GetPlayerName() string {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type CMsgClientPersonaState struct {
 | 
			
		||||
	StatusFlags          *uint32                          `protobuf:"varint,1,opt,name=status_flags" json:"status_flags,omitempty"`
 | 
			
		||||
	StatusFlags          *uint32                          `protobuf:"varint,1,opt,name=status_flags,json=statusFlags" json:"status_flags,omitempty"`
 | 
			
		||||
	Friends              []*CMsgClientPersonaState_Friend `protobuf:"bytes,2,rep,name=friends" json:"friends,omitempty"`
 | 
			
		||||
	XXX_NoUnkeyedLiteral struct{}                         `json:"-"`
 | 
			
		||||
	XXX_unrecognized     []byte                           `json:"-"`
 | 
			
		||||
@@ -1065,34 +1065,33 @@ func (m *CMsgClientPersonaState) GetFriends() []*CMsgClientPersonaState_Friend {
 | 
			
		||||
 | 
			
		||||
type CMsgClientPersonaState_Friend struct {
 | 
			
		||||
	Friendid                   *uint64                                 `protobuf:"fixed64,1,opt,name=friendid" json:"friendid,omitempty"`
 | 
			
		||||
	PersonaState               *uint32                                 `protobuf:"varint,2,opt,name=persona_state" json:"persona_state,omitempty"`
 | 
			
		||||
	GamePlayedAppId            *uint32                                 `protobuf:"varint,3,opt,name=game_played_app_id" json:"game_played_app_id,omitempty"`
 | 
			
		||||
	GameServerIp               *uint32                                 `protobuf:"varint,4,opt,name=game_server_ip" json:"game_server_ip,omitempty"`
 | 
			
		||||
	GameServerPort             *uint32                                 `protobuf:"varint,5,opt,name=game_server_port" json:"game_server_port,omitempty"`
 | 
			
		||||
	PersonaStateFlags          *uint32                                 `protobuf:"varint,6,opt,name=persona_state_flags" json:"persona_state_flags,omitempty"`
 | 
			
		||||
	OnlineSessionInstances     *uint32                                 `protobuf:"varint,7,opt,name=online_session_instances" json:"online_session_instances,omitempty"`
 | 
			
		||||
	PublishedInstanceId        *uint32                                 `protobuf:"varint,8,opt,name=published_instance_id" json:"published_instance_id,omitempty"`
 | 
			
		||||
	PersonaSetByUser           *bool                                   `protobuf:"varint,10,opt,name=persona_set_by_user" json:"persona_set_by_user,omitempty"`
 | 
			
		||||
	PlayerName                 *string                                 `protobuf:"bytes,15,opt,name=player_name" json:"player_name,omitempty"`
 | 
			
		||||
	QueryPort                  *uint32                                 `protobuf:"varint,20,opt,name=query_port" json:"query_port,omitempty"`
 | 
			
		||||
	SteamidSource              *uint64                                 `protobuf:"fixed64,25,opt,name=steamid_source" json:"steamid_source,omitempty"`
 | 
			
		||||
	AvatarHash                 []byte                                  `protobuf:"bytes,31,opt,name=avatar_hash" json:"avatar_hash,omitempty"`
 | 
			
		||||
	LastLogoff                 *uint32                                 `protobuf:"varint,45,opt,name=last_logoff" json:"last_logoff,omitempty"`
 | 
			
		||||
	LastLogon                  *uint32                                 `protobuf:"varint,46,opt,name=last_logon" json:"last_logon,omitempty"`
 | 
			
		||||
	LastSeenOnline             *uint32                                 `protobuf:"varint,47,opt,name=last_seen_online" json:"last_seen_online,omitempty"`
 | 
			
		||||
	ClanRank                   *uint32                                 `protobuf:"varint,50,opt,name=clan_rank" json:"clan_rank,omitempty"`
 | 
			
		||||
	GameName                   *string                                 `protobuf:"bytes,55,opt,name=game_name" json:"game_name,omitempty"`
 | 
			
		||||
	PersonaState               *uint32                                 `protobuf:"varint,2,opt,name=persona_state,json=personaState" json:"persona_state,omitempty"`
 | 
			
		||||
	GamePlayedAppId            *uint32                                 `protobuf:"varint,3,opt,name=game_played_app_id,json=gamePlayedAppId" json:"game_played_app_id,omitempty"`
 | 
			
		||||
	GameServerIp               *uint32                                 `protobuf:"varint,4,opt,name=game_server_ip,json=gameServerIp" json:"game_server_ip,omitempty"`
 | 
			
		||||
	GameServerPort             *uint32                                 `protobuf:"varint,5,opt,name=game_server_port,json=gameServerPort" json:"game_server_port,omitempty"`
 | 
			
		||||
	PersonaStateFlags          *uint32                                 `protobuf:"varint,6,opt,name=persona_state_flags,json=personaStateFlags" json:"persona_state_flags,omitempty"`
 | 
			
		||||
	OnlineSessionInstances     *uint32                                 `protobuf:"varint,7,opt,name=online_session_instances,json=onlineSessionInstances" json:"online_session_instances,omitempty"`
 | 
			
		||||
	PersonaSetByUser           *bool                                   `protobuf:"varint,10,opt,name=persona_set_by_user,json=personaSetByUser" json:"persona_set_by_user,omitempty"`
 | 
			
		||||
	PlayerName                 *string                                 `protobuf:"bytes,15,opt,name=player_name,json=playerName" json:"player_name,omitempty"`
 | 
			
		||||
	QueryPort                  *uint32                                 `protobuf:"varint,20,opt,name=query_port,json=queryPort" json:"query_port,omitempty"`
 | 
			
		||||
	SteamidSource              *uint64                                 `protobuf:"fixed64,25,opt,name=steamid_source,json=steamidSource" json:"steamid_source,omitempty"`
 | 
			
		||||
	AvatarHash                 []byte                                  `protobuf:"bytes,31,opt,name=avatar_hash,json=avatarHash" json:"avatar_hash,omitempty"`
 | 
			
		||||
	LastLogoff                 *uint32                                 `protobuf:"varint,45,opt,name=last_logoff,json=lastLogoff" json:"last_logoff,omitempty"`
 | 
			
		||||
	LastLogon                  *uint32                                 `protobuf:"varint,46,opt,name=last_logon,json=lastLogon" json:"last_logon,omitempty"`
 | 
			
		||||
	LastSeenOnline             *uint32                                 `protobuf:"varint,47,opt,name=last_seen_online,json=lastSeenOnline" json:"last_seen_online,omitempty"`
 | 
			
		||||
	ClanRank                   *uint32                                 `protobuf:"varint,50,opt,name=clan_rank,json=clanRank" json:"clan_rank,omitempty"`
 | 
			
		||||
	GameName                   *string                                 `protobuf:"bytes,55,opt,name=game_name,json=gameName" json:"game_name,omitempty"`
 | 
			
		||||
	Gameid                     *uint64                                 `protobuf:"fixed64,56,opt,name=gameid" json:"gameid,omitempty"`
 | 
			
		||||
	GameDataBlob               []byte                                  `protobuf:"bytes,60,opt,name=game_data_blob" json:"game_data_blob,omitempty"`
 | 
			
		||||
	ClanData                   *CMsgClientPersonaState_Friend_ClanData `protobuf:"bytes,64,opt,name=clan_data" json:"clan_data,omitempty"`
 | 
			
		||||
	ClanTag                    *string                                 `protobuf:"bytes,65,opt,name=clan_tag" json:"clan_tag,omitempty"`
 | 
			
		||||
	RichPresence               []*CMsgClientPersonaState_Friend_KV     `protobuf:"bytes,71,rep,name=rich_presence" json:"rich_presence,omitempty"`
 | 
			
		||||
	BroadcastId                *uint64                                 `protobuf:"fixed64,72,opt,name=broadcast_id" json:"broadcast_id,omitempty"`
 | 
			
		||||
	GameLobbyId                *uint64                                 `protobuf:"fixed64,73,opt,name=game_lobby_id" json:"game_lobby_id,omitempty"`
 | 
			
		||||
	WatchingBroadcastAccountid *uint32                                 `protobuf:"varint,74,opt,name=watching_broadcast_accountid" json:"watching_broadcast_accountid,omitempty"`
 | 
			
		||||
	WatchingBroadcastAppid     *uint32                                 `protobuf:"varint,75,opt,name=watching_broadcast_appid" json:"watching_broadcast_appid,omitempty"`
 | 
			
		||||
	WatchingBroadcastViewers   *uint32                                 `protobuf:"varint,76,opt,name=watching_broadcast_viewers" json:"watching_broadcast_viewers,omitempty"`
 | 
			
		||||
	WatchingBroadcastTitle     *string                                 `protobuf:"bytes,77,opt,name=watching_broadcast_title" json:"watching_broadcast_title,omitempty"`
 | 
			
		||||
	GameDataBlob               []byte                                  `protobuf:"bytes,60,opt,name=game_data_blob,json=gameDataBlob" json:"game_data_blob,omitempty"`
 | 
			
		||||
	ClanData                   *CMsgClientPersonaState_Friend_ClanData `protobuf:"bytes,64,opt,name=clan_data,json=clanData" json:"clan_data,omitempty"`
 | 
			
		||||
	ClanTag                    *string                                 `protobuf:"bytes,65,opt,name=clan_tag,json=clanTag" json:"clan_tag,omitempty"`
 | 
			
		||||
	RichPresence               []*CMsgClientPersonaState_Friend_KV     `protobuf:"bytes,71,rep,name=rich_presence,json=richPresence" json:"rich_presence,omitempty"`
 | 
			
		||||
	BroadcastId                *uint64                                 `protobuf:"fixed64,72,opt,name=broadcast_id,json=broadcastId" json:"broadcast_id,omitempty"`
 | 
			
		||||
	GameLobbyId                *uint64                                 `protobuf:"fixed64,73,opt,name=game_lobby_id,json=gameLobbyId" json:"game_lobby_id,omitempty"`
 | 
			
		||||
	WatchingBroadcastAccountid *uint32                                 `protobuf:"varint,74,opt,name=watching_broadcast_accountid,json=watchingBroadcastAccountid" json:"watching_broadcast_accountid,omitempty"`
 | 
			
		||||
	WatchingBroadcastAppid     *uint32                                 `protobuf:"varint,75,opt,name=watching_broadcast_appid,json=watchingBroadcastAppid" json:"watching_broadcast_appid,omitempty"`
 | 
			
		||||
	WatchingBroadcastViewers   *uint32                                 `protobuf:"varint,76,opt,name=watching_broadcast_viewers,json=watchingBroadcastViewers" json:"watching_broadcast_viewers,omitempty"`
 | 
			
		||||
	WatchingBroadcastTitle     *string                                 `protobuf:"bytes,77,opt,name=watching_broadcast_title,json=watchingBroadcastTitle" json:"watching_broadcast_title,omitempty"`
 | 
			
		||||
	XXX_NoUnkeyedLiteral       struct{}                                `json:"-"`
 | 
			
		||||
	XXX_unrecognized           []byte                                  `json:"-"`
 | 
			
		||||
	XXX_sizecache              int32                                   `json:"-"`
 | 
			
		||||
@@ -1172,13 +1171,6 @@ func (m *CMsgClientPersonaState_Friend) GetOnlineSessionInstances() uint32 {
 | 
			
		||||
	return 0
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *CMsgClientPersonaState_Friend) GetPublishedInstanceId() uint32 {
 | 
			
		||||
	if m != nil && m.PublishedInstanceId != nil {
 | 
			
		||||
		return *m.PublishedInstanceId
 | 
			
		||||
	}
 | 
			
		||||
	return 0
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *CMsgClientPersonaState_Friend) GetPersonaSetByUser() bool {
 | 
			
		||||
	if m != nil && m.PersonaSetByUser != nil {
 | 
			
		||||
		return *m.PersonaSetByUser
 | 
			
		||||
@@ -1327,8 +1319,8 @@ func (m *CMsgClientPersonaState_Friend) GetWatchingBroadcastTitle() string {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type CMsgClientPersonaState_Friend_ClanData struct {
 | 
			
		||||
	OggAppId             *uint32  `protobuf:"varint,1,opt,name=ogg_app_id" json:"ogg_app_id,omitempty"`
 | 
			
		||||
	ChatGroupId          *uint64  `protobuf:"varint,2,opt,name=chat_group_id" json:"chat_group_id,omitempty"`
 | 
			
		||||
	OggAppId             *uint32  `protobuf:"varint,1,opt,name=ogg_app_id,json=oggAppId" json:"ogg_app_id,omitempty"`
 | 
			
		||||
	ChatGroupId          *uint64  `protobuf:"varint,2,opt,name=chat_group_id,json=chatGroupId" json:"chat_group_id,omitempty"`
 | 
			
		||||
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
 | 
			
		||||
	XXX_unrecognized     []byte   `json:"-"`
 | 
			
		||||
	XXX_sizecache        int32    `json:"-"`
 | 
			
		||||
@@ -1423,7 +1415,7 @@ func (m *CMsgClientPersonaState_Friend_KV) GetValue() string {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type CMsgClientFriendProfileInfo struct {
 | 
			
		||||
	SteamidFriend        *uint64  `protobuf:"fixed64,1,opt,name=steamid_friend" json:"steamid_friend,omitempty"`
 | 
			
		||||
	SteamidFriend        *uint64  `protobuf:"fixed64,1,opt,name=steamid_friend,json=steamidFriend" json:"steamid_friend,omitempty"`
 | 
			
		||||
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
 | 
			
		||||
	XXX_unrecognized     []byte   `json:"-"`
 | 
			
		||||
	XXX_sizecache        int32    `json:"-"`
 | 
			
		||||
@@ -1463,12 +1455,12 @@ func (m *CMsgClientFriendProfileInfo) GetSteamidFriend() uint64 {
 | 
			
		||||
 | 
			
		||||
type CMsgClientFriendProfileInfoResponse struct {
 | 
			
		||||
	Eresult              *int32   `protobuf:"varint,1,opt,name=eresult,def=2" json:"eresult,omitempty"`
 | 
			
		||||
	SteamidFriend        *uint64  `protobuf:"fixed64,2,opt,name=steamid_friend" json:"steamid_friend,omitempty"`
 | 
			
		||||
	TimeCreated          *uint32  `protobuf:"varint,3,opt,name=time_created" json:"time_created,omitempty"`
 | 
			
		||||
	RealName             *string  `protobuf:"bytes,4,opt,name=real_name" json:"real_name,omitempty"`
 | 
			
		||||
	CityName             *string  `protobuf:"bytes,5,opt,name=city_name" json:"city_name,omitempty"`
 | 
			
		||||
	StateName            *string  `protobuf:"bytes,6,opt,name=state_name" json:"state_name,omitempty"`
 | 
			
		||||
	CountryName          *string  `protobuf:"bytes,7,opt,name=country_name" json:"country_name,omitempty"`
 | 
			
		||||
	SteamidFriend        *uint64  `protobuf:"fixed64,2,opt,name=steamid_friend,json=steamidFriend" json:"steamid_friend,omitempty"`
 | 
			
		||||
	TimeCreated          *uint32  `protobuf:"varint,3,opt,name=time_created,json=timeCreated" json:"time_created,omitempty"`
 | 
			
		||||
	RealName             *string  `protobuf:"bytes,4,opt,name=real_name,json=realName" json:"real_name,omitempty"`
 | 
			
		||||
	CityName             *string  `protobuf:"bytes,5,opt,name=city_name,json=cityName" json:"city_name,omitempty"`
 | 
			
		||||
	StateName            *string  `protobuf:"bytes,6,opt,name=state_name,json=stateName" json:"state_name,omitempty"`
 | 
			
		||||
	CountryName          *string  `protobuf:"bytes,7,opt,name=country_name,json=countryName" json:"country_name,omitempty"`
 | 
			
		||||
	Headline             *string  `protobuf:"bytes,8,opt,name=headline" json:"headline,omitempty"`
 | 
			
		||||
	Summary              *string  `protobuf:"bytes,9,opt,name=summary" json:"summary,omitempty"`
 | 
			
		||||
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
 | 
			
		||||
@@ -1569,7 +1561,7 @@ func (m *CMsgClientFriendProfileInfoResponse) GetSummary() string {
 | 
			
		||||
type CMsgClientCreateFriendsGroup struct {
 | 
			
		||||
	Steamid              *uint64  `protobuf:"fixed64,1,opt,name=steamid" json:"steamid,omitempty"`
 | 
			
		||||
	Groupname            *string  `protobuf:"bytes,2,opt,name=groupname" json:"groupname,omitempty"`
 | 
			
		||||
	SteamidFriends       []uint64 `protobuf:"fixed64,3,rep,name=steamid_friends" json:"steamid_friends,omitempty"`
 | 
			
		||||
	SteamidFriends       []uint64 `protobuf:"fixed64,3,rep,name=steamid_friends,json=steamidFriends" json:"steamid_friends,omitempty"`
 | 
			
		||||
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
 | 
			
		||||
	XXX_unrecognized     []byte   `json:"-"`
 | 
			
		||||
	XXX_sizecache        int32    `json:"-"`
 | 
			
		||||
@@ -1757,8 +1749,8 @@ func (m *CMsgClientDeleteFriendsGroupResponse) GetEresult() uint32 {
 | 
			
		||||
type CMsgClientManageFriendsGroup struct {
 | 
			
		||||
	Groupid               *int32   `protobuf:"varint,1,opt,name=groupid" json:"groupid,omitempty"`
 | 
			
		||||
	Groupname             *string  `protobuf:"bytes,2,opt,name=groupname" json:"groupname,omitempty"`
 | 
			
		||||
	SteamidFriendsAdded   []uint64 `protobuf:"fixed64,3,rep,name=steamid_friends_added" json:"steamid_friends_added,omitempty"`
 | 
			
		||||
	SteamidFriendsRemoved []uint64 `protobuf:"fixed64,4,rep,name=steamid_friends_removed" json:"steamid_friends_removed,omitempty"`
 | 
			
		||||
	SteamidFriendsAdded   []uint64 `protobuf:"fixed64,3,rep,name=steamid_friends_added,json=steamidFriendsAdded" json:"steamid_friends_added,omitempty"`
 | 
			
		||||
	SteamidFriendsRemoved []uint64 `protobuf:"fixed64,4,rep,name=steamid_friends_removed,json=steamidFriendsRemoved" json:"steamid_friends_removed,omitempty"`
 | 
			
		||||
	XXX_NoUnkeyedLiteral  struct{} `json:"-"`
 | 
			
		||||
	XXX_unrecognized      []byte   `json:"-"`
 | 
			
		||||
	XXX_sizecache         int32    `json:"-"`
 | 
			
		||||
@@ -2063,6 +2055,8 @@ var xxx_messageInfo_CMsgClientGetEmoticonList proto.InternalMessageInfo
 | 
			
		||||
 | 
			
		||||
type CMsgClientEmoticonList struct {
 | 
			
		||||
	Emoticons            []*CMsgClientEmoticonList_Emoticon `protobuf:"bytes,1,rep,name=emoticons" json:"emoticons,omitempty"`
 | 
			
		||||
	Stickers             []*CMsgClientEmoticonList_Sticker  `protobuf:"bytes,2,rep,name=stickers" json:"stickers,omitempty"`
 | 
			
		||||
	Effects              []*CMsgClientEmoticonList_Effect   `protobuf:"bytes,3,rep,name=effects" json:"effects,omitempty"`
 | 
			
		||||
	XXX_NoUnkeyedLiteral struct{}                           `json:"-"`
 | 
			
		||||
	XXX_unrecognized     []byte                             `json:"-"`
 | 
			
		||||
	XXX_sizecache        int32                              `json:"-"`
 | 
			
		||||
@@ -2100,12 +2094,26 @@ func (m *CMsgClientEmoticonList) GetEmoticons() []*CMsgClientEmoticonList_Emotic
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *CMsgClientEmoticonList) GetStickers() []*CMsgClientEmoticonList_Sticker {
 | 
			
		||||
	if m != nil {
 | 
			
		||||
		return m.Stickers
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *CMsgClientEmoticonList) GetEffects() []*CMsgClientEmoticonList_Effect {
 | 
			
		||||
	if m != nil {
 | 
			
		||||
		return m.Effects
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type CMsgClientEmoticonList_Emoticon struct {
 | 
			
		||||
	Name                 *string  `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
 | 
			
		||||
	Count                *int32   `protobuf:"varint,2,opt,name=count" json:"count,omitempty"`
 | 
			
		||||
	TimeLastUsed         *uint32  `protobuf:"varint,3,opt,name=time_last_used" json:"time_last_used,omitempty"`
 | 
			
		||||
	UseCount             *uint32  `protobuf:"varint,4,opt,name=use_count" json:"use_count,omitempty"`
 | 
			
		||||
	TimeReceived         *uint32  `protobuf:"varint,5,opt,name=time_received" json:"time_received,omitempty"`
 | 
			
		||||
	TimeLastUsed         *uint32  `protobuf:"varint,3,opt,name=time_last_used,json=timeLastUsed" json:"time_last_used,omitempty"`
 | 
			
		||||
	UseCount             *uint32  `protobuf:"varint,4,opt,name=use_count,json=useCount" json:"use_count,omitempty"`
 | 
			
		||||
	TimeReceived         *uint32  `protobuf:"varint,5,opt,name=time_received,json=timeReceived" json:"time_received,omitempty"`
 | 
			
		||||
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
 | 
			
		||||
	XXX_unrecognized     []byte   `json:"-"`
 | 
			
		||||
	XXX_sizecache        int32    `json:"-"`
 | 
			
		||||
@@ -2171,6 +2179,140 @@ func (m *CMsgClientEmoticonList_Emoticon) GetTimeReceived() uint32 {
 | 
			
		||||
	return 0
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type CMsgClientEmoticonList_Sticker struct {
 | 
			
		||||
	Name                 *string  `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
 | 
			
		||||
	Count                *int32   `protobuf:"varint,2,opt,name=count" json:"count,omitempty"`
 | 
			
		||||
	TimeReceived         *uint32  `protobuf:"varint,3,opt,name=time_received,json=timeReceived" json:"time_received,omitempty"`
 | 
			
		||||
	Appid                *uint32  `protobuf:"varint,4,opt,name=appid" json:"appid,omitempty"`
 | 
			
		||||
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
 | 
			
		||||
	XXX_unrecognized     []byte   `json:"-"`
 | 
			
		||||
	XXX_sizecache        int32    `json:"-"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *CMsgClientEmoticonList_Sticker) Reset()         { *m = CMsgClientEmoticonList_Sticker{} }
 | 
			
		||||
func (m *CMsgClientEmoticonList_Sticker) String() string { return proto.CompactTextString(m) }
 | 
			
		||||
func (*CMsgClientEmoticonList_Sticker) ProtoMessage()    {}
 | 
			
		||||
func (*CMsgClientEmoticonList_Sticker) Descriptor() ([]byte, []int) {
 | 
			
		||||
	return fileDescriptor_4f7c18b08a29999e, []int{28, 1}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *CMsgClientEmoticonList_Sticker) XXX_Unmarshal(b []byte) error {
 | 
			
		||||
	return xxx_messageInfo_CMsgClientEmoticonList_Sticker.Unmarshal(m, b)
 | 
			
		||||
}
 | 
			
		||||
func (m *CMsgClientEmoticonList_Sticker) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
 | 
			
		||||
	return xxx_messageInfo_CMsgClientEmoticonList_Sticker.Marshal(b, m, deterministic)
 | 
			
		||||
}
 | 
			
		||||
func (m *CMsgClientEmoticonList_Sticker) XXX_Merge(src proto.Message) {
 | 
			
		||||
	xxx_messageInfo_CMsgClientEmoticonList_Sticker.Merge(m, src)
 | 
			
		||||
}
 | 
			
		||||
func (m *CMsgClientEmoticonList_Sticker) XXX_Size() int {
 | 
			
		||||
	return xxx_messageInfo_CMsgClientEmoticonList_Sticker.Size(m)
 | 
			
		||||
}
 | 
			
		||||
func (m *CMsgClientEmoticonList_Sticker) XXX_DiscardUnknown() {
 | 
			
		||||
	xxx_messageInfo_CMsgClientEmoticonList_Sticker.DiscardUnknown(m)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var xxx_messageInfo_CMsgClientEmoticonList_Sticker proto.InternalMessageInfo
 | 
			
		||||
 | 
			
		||||
func (m *CMsgClientEmoticonList_Sticker) GetName() string {
 | 
			
		||||
	if m != nil && m.Name != nil {
 | 
			
		||||
		return *m.Name
 | 
			
		||||
	}
 | 
			
		||||
	return ""
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *CMsgClientEmoticonList_Sticker) GetCount() int32 {
 | 
			
		||||
	if m != nil && m.Count != nil {
 | 
			
		||||
		return *m.Count
 | 
			
		||||
	}
 | 
			
		||||
	return 0
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *CMsgClientEmoticonList_Sticker) GetTimeReceived() uint32 {
 | 
			
		||||
	if m != nil && m.TimeReceived != nil {
 | 
			
		||||
		return *m.TimeReceived
 | 
			
		||||
	}
 | 
			
		||||
	return 0
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *CMsgClientEmoticonList_Sticker) GetAppid() uint32 {
 | 
			
		||||
	if m != nil && m.Appid != nil {
 | 
			
		||||
		return *m.Appid
 | 
			
		||||
	}
 | 
			
		||||
	return 0
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type CMsgClientEmoticonList_Effect struct {
 | 
			
		||||
	Name                 *string  `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
 | 
			
		||||
	Count                *int32   `protobuf:"varint,2,opt,name=count" json:"count,omitempty"`
 | 
			
		||||
	TimeReceived         *uint32  `protobuf:"varint,3,opt,name=time_received,json=timeReceived" json:"time_received,omitempty"`
 | 
			
		||||
	InfiniteUse          *bool    `protobuf:"varint,4,opt,name=infinite_use,json=infiniteUse" json:"infinite_use,omitempty"`
 | 
			
		||||
	Appid                *uint32  `protobuf:"varint,5,opt,name=appid" json:"appid,omitempty"`
 | 
			
		||||
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
 | 
			
		||||
	XXX_unrecognized     []byte   `json:"-"`
 | 
			
		||||
	XXX_sizecache        int32    `json:"-"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *CMsgClientEmoticonList_Effect) Reset()         { *m = CMsgClientEmoticonList_Effect{} }
 | 
			
		||||
func (m *CMsgClientEmoticonList_Effect) String() string { return proto.CompactTextString(m) }
 | 
			
		||||
func (*CMsgClientEmoticonList_Effect) ProtoMessage()    {}
 | 
			
		||||
func (*CMsgClientEmoticonList_Effect) Descriptor() ([]byte, []int) {
 | 
			
		||||
	return fileDescriptor_4f7c18b08a29999e, []int{28, 2}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *CMsgClientEmoticonList_Effect) XXX_Unmarshal(b []byte) error {
 | 
			
		||||
	return xxx_messageInfo_CMsgClientEmoticonList_Effect.Unmarshal(m, b)
 | 
			
		||||
}
 | 
			
		||||
func (m *CMsgClientEmoticonList_Effect) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
 | 
			
		||||
	return xxx_messageInfo_CMsgClientEmoticonList_Effect.Marshal(b, m, deterministic)
 | 
			
		||||
}
 | 
			
		||||
func (m *CMsgClientEmoticonList_Effect) XXX_Merge(src proto.Message) {
 | 
			
		||||
	xxx_messageInfo_CMsgClientEmoticonList_Effect.Merge(m, src)
 | 
			
		||||
}
 | 
			
		||||
func (m *CMsgClientEmoticonList_Effect) XXX_Size() int {
 | 
			
		||||
	return xxx_messageInfo_CMsgClientEmoticonList_Effect.Size(m)
 | 
			
		||||
}
 | 
			
		||||
func (m *CMsgClientEmoticonList_Effect) XXX_DiscardUnknown() {
 | 
			
		||||
	xxx_messageInfo_CMsgClientEmoticonList_Effect.DiscardUnknown(m)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var xxx_messageInfo_CMsgClientEmoticonList_Effect proto.InternalMessageInfo
 | 
			
		||||
 | 
			
		||||
func (m *CMsgClientEmoticonList_Effect) GetName() string {
 | 
			
		||||
	if m != nil && m.Name != nil {
 | 
			
		||||
		return *m.Name
 | 
			
		||||
	}
 | 
			
		||||
	return ""
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *CMsgClientEmoticonList_Effect) GetCount() int32 {
 | 
			
		||||
	if m != nil && m.Count != nil {
 | 
			
		||||
		return *m.Count
 | 
			
		||||
	}
 | 
			
		||||
	return 0
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *CMsgClientEmoticonList_Effect) GetTimeReceived() uint32 {
 | 
			
		||||
	if m != nil && m.TimeReceived != nil {
 | 
			
		||||
		return *m.TimeReceived
 | 
			
		||||
	}
 | 
			
		||||
	return 0
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *CMsgClientEmoticonList_Effect) GetInfiniteUse() bool {
 | 
			
		||||
	if m != nil && m.InfiniteUse != nil {
 | 
			
		||||
		return *m.InfiniteUse
 | 
			
		||||
	}
 | 
			
		||||
	return false
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *CMsgClientEmoticonList_Effect) GetAppid() uint32 {
 | 
			
		||||
	if m != nil && m.Appid != nil {
 | 
			
		||||
		return *m.Appid
 | 
			
		||||
	}
 | 
			
		||||
	return 0
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func init() {
 | 
			
		||||
	proto.RegisterType((*CMsgClientFriendMsg)(nil), "CMsgClientFriendMsg")
 | 
			
		||||
	proto.RegisterType((*CMsgClientFriendMsgIncoming)(nil), "CMsgClientFriendMsgIncoming")
 | 
			
		||||
@@ -2209,6 +2351,8 @@ func init() {
 | 
			
		||||
	proto.RegisterType((*CMsgClientGetEmoticonList)(nil), "CMsgClientGetEmoticonList")
 | 
			
		||||
	proto.RegisterType((*CMsgClientEmoticonList)(nil), "CMsgClientEmoticonList")
 | 
			
		||||
	proto.RegisterType((*CMsgClientEmoticonList_Emoticon)(nil), "CMsgClientEmoticonList.Emoticon")
 | 
			
		||||
	proto.RegisterType((*CMsgClientEmoticonList_Sticker)(nil), "CMsgClientEmoticonList.Sticker")
 | 
			
		||||
	proto.RegisterType((*CMsgClientEmoticonList_Effect)(nil), "CMsgClientEmoticonList.Effect")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func init() {
 | 
			
		||||
@@ -2216,106 +2360,141 @@ func init() {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var fileDescriptor_4f7c18b08a29999e = []byte{
 | 
			
		||||
	// 1607 bytes of a gzipped FileDescriptorProto
 | 
			
		||||
	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x57, 0x4b, 0x73, 0x1b, 0xc7,
 | 
			
		||||
	0x11, 0xce, 0x8a, 0x24, 0x1e, 0x0d, 0x82, 0xa4, 0x96, 0x0f, 0xad, 0x40, 0x3d, 0x90, 0xb5, 0xab,
 | 
			
		||||
	0x8c, 0x4a, 0x25, 0x70, 0x8a, 0x2a, 0xd9, 0x8e, 0x2a, 0x0f, 0xd9, 0x54, 0x2c, 0x2a, 0x32, 0x1d,
 | 
			
		||||
	0x95, 0x94, 0xf2, 0x25, 0x87, 0xa9, 0xc1, 0x6e, 0x13, 0x98, 0xd2, 0xee, 0x2c, 0x3c, 0x33, 0x4b,
 | 
			
		||||
	0x07, 0xb7, 0x54, 0x8e, 0xf9, 0x0f, 0xf9, 0x1f, 0xa9, 0xdc, 0xf3, 0x27, 0x72, 0xc9, 0x3d, 0x97,
 | 
			
		||||
	0xfc, 0x82, 0x54, 0xa5, 0xa6, 0x67, 0x16, 0x5c, 0x10, 0x00, 0x69, 0xdf, 0x80, 0x9e, 0xe9, 0xaf,
 | 
			
		||||
	0xbf, 0xee, 0xe9, 0xd7, 0xc2, 0x40, 0x1b, 0xe4, 0x79, 0x8e, 0x5a, 0xf3, 0x31, 0x6a, 0x96, 0x64,
 | 
			
		||||
	0x02, 0xa5, 0xd1, 0xa8, 0x2e, 0x51, 0xb1, 0x0b, 0x25, 0x50, 0xa6, 0x7a, 0x38, 0x55, 0x85, 0x29,
 | 
			
		||||
	0x7a, 0xd1, 0xe2, 0xcd, 0x11, 0xd7, 0xe8, 0x4e, 0xe2, 0xbf, 0x06, 0xb0, 0x7f, 0x7a, 0xae, 0xc7,
 | 
			
		||||
	0xa7, 0xa4, 0xfc, 0x25, 0x69, 0x9d, 0xeb, 0x71, 0xb8, 0x0b, 0x4d, 0xd2, 0x11, 0x69, 0x14, 0xf4,
 | 
			
		||||
	0x83, 0x41, 0x23, 0xbc, 0x07, 0xbb, 0xc9, 0x84, 0x1b, 0x86, 0xd2, 0xa8, 0x19, 0x33, 0xb3, 0x29,
 | 
			
		||||
	0x46, 0x77, 0xfa, 0xc1, 0x60, 0xcb, 0xde, 0xf4, 0xc0, 0xd1, 0x46, 0x3f, 0x18, 0x6c, 0x87, 0x7d,
 | 
			
		||||
	0x88, 0x94, 0x11, 0x39, 0x3e, 0x39, 0x61, 0x9e, 0x8c, 0xfd, 0xa7, 0x0d, 0xcf, 0xa7, 0xd1, 0x66,
 | 
			
		||||
	0x3f, 0x18, 0x34, 0xc3, 0x23, 0xd8, 0xc1, 0x64, 0x52, 0x30, 0x53, 0x30, 0x8d, 0x32, 0x45, 0x15,
 | 
			
		||||
	0x6d, 0xf5, 0x83, 0x41, 0x2b, 0xfe, 0x5b, 0x00, 0xc7, 0x2b, 0xc8, 0xbc, 0x92, 0x49, 0x91, 0x0b,
 | 
			
		||||
	0x39, 0x0e, 0x0f, 0x60, 0xdb, 0x93, 0x62, 0x17, 0xaa, 0xc8, 0x6f, 0x63, 0xf6, 0x00, 0x0e, 0xec,
 | 
			
		||||
	0x35, 0x96, 0x89, 0x5c, 0x18, 0x4c, 0x19, 0x4f, 0x92, 0xa2, 0x94, 0x86, 0x68, 0xb6, 0xea, 0xbc,
 | 
			
		||||
	0x37, 0x6f, 0xe5, 0x6d, 0xf9, 0x35, 0xe3, 0xb7, 0xf5, 0x58, 0x7d, 0x9e, 0xa6, 0x8e, 0xa1, 0x75,
 | 
			
		||||
	0xa7, 0xa2, 0x65, 0x0a, 0xc6, 0xd3, 0x2a, 0x64, 0x1f, 0xc0, 0xb1, 0x37, 0x29, 0x79, 0x8e, 0xac,
 | 
			
		||||
	0x50, 0x0c, 0x73, 0x2e, 0xb2, 0xea, 0x92, 0x25, 0xd9, 0x8e, 0xb1, 0xee, 0xf2, 0x1c, 0xf3, 0x2d,
 | 
			
		||||
	0xea, 0x69, 0x21, 0x35, 0x86, 0x21, 0x34, 0x51, 0xa1, 0x2e, 0x33, 0x43, 0xa0, 0x5b, 0xcf, 0x82,
 | 
			
		||||
	0x93, 0xb9, 0x3d, 0x26, 0x52, 0x0b, 0x84, 0x0e, 0xaa, 0x11, 0xf6, 0x20, 0x9c, 0xa2, 0xd2, 0x85,
 | 
			
		||||
	0xe4, 0x8c, 0x0c, 0xba, 0xb3, 0x0d, 0x32, 0xf3, 0x13, 0x38, 0xba, 0x32, 0xf3, 0x16, 0xf3, 0xe2,
 | 
			
		||||
	0x12, 0x3d, 0xfb, 0x3d, 0x68, 0xb9, 0x64, 0xa9, 0x9e, 0x3a, 0xfe, 0x04, 0x0e, 0xae, 0xee, 0x9e,
 | 
			
		||||
	0x89, 0x74, 0xed, 0xcd, 0x70, 0x1b, 0x36, 0x27, 0x22, 0x75, 0xf1, 0x6e, 0xc5, 0xff, 0x09, 0xe0,
 | 
			
		||||
	0xf0, 0xfa, 0xf3, 0xe9, 0xaf, 0x84, 0x36, 0xf6, 0xe1, 0x46, 0x42, 0x26, 0x0a, 0x73, 0x94, 0x86,
 | 
			
		||||
	0x67, 0xa4, 0xdd, 0x0a, 0x87, 0xd0, 0xf4, 0x69, 0x1a, 0xdd, 0xe9, 0x6f, 0x0c, 0x3a, 0x27, 0x0f,
 | 
			
		||||
	0x87, 0x2b, 0xd5, 0x87, 0xde, 0x7e, 0x04, 0x7b, 0x39, 0xff, 0x93, 0x4f, 0x6d, 0x76, 0xf5, 0x96,
 | 
			
		||||
	0xdd, 0xf0, 0x18, 0xf6, 0x79, 0x62, 0xc4, 0x25, 0x2e, 0x1e, 0x6e, 0xd2, 0xe1, 0x7d, 0xb8, 0xeb,
 | 
			
		||||
	0xcd, 0xb8, 0x4c, 0x60, 0x13, 0x61, 0x5c, 0xc2, 0xf5, 0x7e, 0x01, 0x0d, 0x8f, 0x1d, 0x02, 0x94,
 | 
			
		||||
	0xd9, 0x35, 0xef, 0x8e, 0x61, 0x1f, 0x9d, 0x48, 0x61, 0xc6, 0x8d, 0x28, 0xa4, 0x9e, 0x88, 0x29,
 | 
			
		||||
	0x39, 0xdb, 0x8d, 0xff, 0x79, 0x67, 0x39, 0x57, 0xf5, 0x4b, 0x55, 0x94, 0x53, 0xe7, 0xf2, 0x1e,
 | 
			
		||||
	0xb4, 0x46, 0xca, 0xc6, 0x79, 0xee, 0xee, 0xf5, 0x20, 0x50, 0xd0, 0xc2, 0x5f, 0xc3, 0xb6, 0xb3,
 | 
			
		||||
	0xe1, 0x74, 0xa3, 0x0d, 0x8a, 0xc4, 0x60, 0x78, 0x03, 0xb6, 0x8f, 0x07, 0x09, 0xc2, 0x33, 0xe8,
 | 
			
		||||
	0xe4, 0x98, 0x8f, 0x50, 0x59, 0x6e, 0x3a, 0xda, 0x24, 0xf5, 0x27, 0xdf, 0x57, 0x5d, 0x9f, 0xcf,
 | 
			
		||||
	0x75, 0x7b, 0x4f, 0xa1, 0x53, 0x07, 0xde, 0x83, 0x96, 0xa4, 0x5f, 0xaf, 0x5e, 0xb8, 0xd4, 0x73,
 | 
			
		||||
	0xe5, 0xa7, 0x48, 0xf6, 0x35, 0xcf, 0xdd, 0xab, 0xb7, 0x7b, 0xbf, 0x82, 0xa3, 0xd5, 0x80, 0xe1,
 | 
			
		||||
	0x5d, 0x68, 0x97, 0xd9, 0x3b, 0x9b, 0xa9, 0x1e, 0xa2, 0xb1, 0x00, 0x4a, 0x45, 0x1a, 0xff, 0x23,
 | 
			
		||||
	0x80, 0x07, 0x57, 0x64, 0xdf, 0x64, 0x7c, 0x86, 0xea, 0x6b, 0x91, 0xbc, 0xb7, 0x19, 0x4c, 0x81,
 | 
			
		||||
	0xdc, 0x85, 0xe6, 0x62, 0x1c, 0xf7, 0xa1, 0xb3, 0x1c, 0xc6, 0xdf, 0x40, 0x5b, 0x7a, 0xad, 0x2a,
 | 
			
		||||
	0x86, 0x3f, 0x1d, 0xde, 0x84, 0x3b, 0x5c, 0x14, 0xf5, 0x9e, 0xc0, 0xce, 0xa2, 0x64, 0xb9, 0x05,
 | 
			
		||||
	0x5a, 0xf2, 0xfe, 0xd0, 0x57, 0xd5, 0xf3, 0x7a, 0x0e, 0xbc, 0x43, 0xf3, 0x43, 0x10, 0x5c, 0xf9,
 | 
			
		||||
	0x7f, 0x02, 0x1f, 0xdc, 0x80, 0x30, 0x6f, 0x03, 0xbb, 0x8b, 0x6d, 0xa0, 0x1b, 0xff, 0xbe, 0x6e,
 | 
			
		||||
	0xf9, 0x2d, 0x7e, 0x5b, 0xa2, 0xf6, 0x2f, 0xfd, 0x82, 0x1b, 0x1e, 0x3e, 0x86, 0x7b, 0x55, 0x2b,
 | 
			
		||||
	0xd0, 0x86, 0x1b, 0x64, 0xca, 0x5d, 0x41, 0xc7, 0xa4, 0x6b, 0x01, 0xeb, 0xb5, 0xd7, 0x88, 0xff,
 | 
			
		||||
	0x1b, 0xd4, 0x3b, 0xc4, 0xe9, 0x84, 0xcb, 0x31, 0xbe, 0x33, 0xdc, 0x94, 0x3a, 0x3c, 0x84, 0xee,
 | 
			
		||||
	0x02, 0x98, 0x87, 0xd8, 0x87, 0xce, 0x94, 0xd8, 0xb2, 0x2b, 0x7f, 0xc2, 0x47, 0x70, 0x24, 0x34,
 | 
			
		||||
	0xe3, 0xa5, 0x29, 0xd8, 0x18, 0x25, 0x2a, 0x6e, 0x1b, 0xef, 0x3c, 0x62, 0x2d, 0x8b, 0x35, 0x11,
 | 
			
		||||
	0xe3, 0x09, 0x9b, 0x2a, 0x51, 0x28, 0x61, 0x66, 0x54, 0xa3, 0x2d, 0x5b, 0x6a, 0x73, 0x13, 0x68,
 | 
			
		||||
	0xd8, 0x68, 0xc6, 0x4a, 0x5d, 0x8d, 0x85, 0xf0, 0x51, 0xed, 0x90, 0x9c, 0xb9, 0xc8, 0xf8, 0x58,
 | 
			
		||||
	0x47, 0x0d, 0xcb, 0xe2, 0x59, 0xf0, 0xf3, 0xf0, 0x21, 0x1c, 0x4a, 0xc4, 0x94, 0x55, 0x97, 0x94,
 | 
			
		||||
	0x8f, 0x5a, 0xd4, 0x24, 0xf5, 0x23, 0xd8, 0x11, 0xd5, 0x74, 0x64, 0x22, 0xcd, 0x30, 0x6a, 0x51,
 | 
			
		||||
	0xbb, 0x7a, 0x0e, 0xf7, 0xad, 0xc3, 0x6f, 0x9c, 0x96, 0xf3, 0x78, 0x1e, 0xf0, 0x1d, 0x68, 0xd4,
 | 
			
		||||
	0xe3, 0xbd, 0xd2, 0xd9, 0xf8, 0xdf, 0xcd, 0x7a, 0xcc, 0x3c, 0x90, 0x0d, 0x1a, 0xba, 0x5a, 0xb1,
 | 
			
		||||
	0xd1, 0xf3, 0x64, 0x1d, 0xca, 0xc7, 0xd7, 0x3b, 0xde, 0xa3, 0xe1, 0x6a, 0x7d, 0x5f, 0xa3, 0xbd,
 | 
			
		||||
	0xff, 0x35, 0xe6, 0x1d, 0x6a, 0xb9, 0xfb, 0x2e, 0xbd, 0x0b, 0x75, 0x26, 0x3b, 0x06, 0xc6, 0xb6,
 | 
			
		||||
	0xfd, 0x13, 0xdf, 0x94, 0xf1, 0xe9, 0x94, 0x89, 0xd4, 0x37, 0xca, 0x23, 0xd8, 0xa1, 0x33, 0x3f,
 | 
			
		||||
	0xe0, 0xc4, 0xd4, 0xf7, 0xc8, 0x08, 0xf6, 0xea, 0xf2, 0x69, 0xa1, 0x5c, 0x8b, 0xec, 0x2e, 0xbc,
 | 
			
		||||
	0xcc, 0xf5, 0xe0, 0xdb, 0x91, 0x59, 0xc8, 0x4c, 0x48, 0xab, 0xa8, 0xb5, 0x28, 0x24, 0x13, 0x52,
 | 
			
		||||
	0x1b, 0x2e, 0x13, 0xd4, 0x14, 0xfc, 0xae, 0x7d, 0x9b, 0x69, 0x39, 0xca, 0x84, 0x9e, 0x60, 0x3a,
 | 
			
		||||
	0x3f, 0xb4, 0x7c, 0x5a, 0x4b, 0xe8, 0xb5, 0x77, 0x87, 0xaa, 0xd0, 0xeb, 0x31, 0xdf, 0xa5, 0x04,
 | 
			
		||||
	0x0b, 0x01, 0xbe, 0x2d, 0x51, 0xcd, 0x1c, 0xc7, 0x83, 0xca, 0xab, 0x6a, 0x00, 0xeb, 0xa2, 0x54,
 | 
			
		||||
	0x09, 0x46, 0xf7, 0x29, 0x40, 0xfb, 0xd0, 0xe1, 0x97, 0xdc, 0x70, 0xc5, 0x26, 0x5c, 0x4f, 0xa2,
 | 
			
		||||
	0xc7, 0x34, 0xe6, 0xf7, 0xa1, 0x93, 0x71, 0x6d, 0x58, 0x56, 0x8c, 0x8b, 0x8b, 0x8b, 0xe8, 0x67,
 | 
			
		||||
	0x84, 0x10, 0x02, 0xcc, 0x85, 0x32, 0x1a, 0x56, 0x31, 0x21, 0x99, 0x46, 0x94, 0xcc, 0xb9, 0x19,
 | 
			
		||||
	0x7d, 0x4c, 0x27, 0x77, 0xa1, 0x9d, 0x64, 0x5c, 0x32, 0xc5, 0xe5, 0xfb, 0xe8, 0xa4, 0x12, 0x51,
 | 
			
		||||
	0x00, 0x89, 0xe9, 0xa7, 0xc4, 0x74, 0x07, 0x1a, 0x56, 0x24, 0xd2, 0xe8, 0x33, 0x62, 0x53, 0xc5,
 | 
			
		||||
	0x3e, 0xe5, 0x86, 0xb3, 0x51, 0x56, 0x8c, 0xa2, 0x5f, 0x12, 0xa1, 0x67, 0x1e, 0xcd, 0xca, 0xa3,
 | 
			
		||||
	0xe7, 0xfd, 0x60, 0xd0, 0x39, 0xf9, 0xe8, 0xe6, 0xb4, 0x18, 0x9e, 0x66, 0x5c, 0x52, 0x9d, 0xef,
 | 
			
		||||
	0x41, 0x8b, 0x74, 0x0d, 0x1f, 0x47, 0x9f, 0x93, 0xd5, 0xcf, 0xa0, 0xab, 0x44, 0x62, 0x0b, 0x0c,
 | 
			
		||||
	0x35, 0xca, 0x04, 0xa3, 0x97, 0x94, 0x68, 0x3f, 0xbe, 0x05, 0xf1, 0xf5, 0x37, 0x34, 0x9f, 0x54,
 | 
			
		||||
	0xc1, 0xd3, 0xc4, 0x3a, 0x2d, 0xd2, 0xe8, 0xac, 0x4a, 0x32, 0x62, 0x9d, 0x15, 0xa3, 0xd1, 0xcc,
 | 
			
		||||
	0x8a, 0x5f, 0x91, 0xf8, 0x43, 0x78, 0xf0, 0x1d, 0x37, 0xc9, 0x44, 0xc8, 0x31, 0xbb, 0xd2, 0xf2,
 | 
			
		||||
	0xeb, 0x8e, 0x48, 0xa3, 0xdf, 0x55, 0xf9, 0xb1, 0xea, 0xd6, 0x74, 0x2a, 0xd2, 0xe8, 0x35, 0xdd,
 | 
			
		||||
	0x88, 0xa1, 0xb7, 0xe2, 0xc6, 0xa5, 0xc0, 0xef, 0x50, 0xe9, 0xe8, 0xab, 0x1b, 0x50, 0x8c, 0x30,
 | 
			
		||||
	0x19, 0x46, 0xe7, 0x34, 0x83, 0x9e, 0x42, 0x6b, 0x1e, 0x92, 0x10, 0xa0, 0x18, 0x8f, 0xab, 0xb4,
 | 
			
		||||
	0x77, 0x75, 0x77, 0x08, 0x5d, 0x5a, 0x11, 0xc7, 0x76, 0xf4, 0x58, 0xb1, 0xad, 0x94, 0xcd, 0x5e,
 | 
			
		||||
	0x1f, 0xee, 0xbc, 0xfe, 0x26, 0xec, 0xc0, 0xc6, 0x7b, 0x9c, 0xd1, 0xcd, 0x76, 0xd8, 0x85, 0xad,
 | 
			
		||||
	0x4b, 0x9e, 0x95, 0x55, 0x85, 0x3f, 0x5d, 0x1e, 0xf2, 0x6f, 0x54, 0x71, 0x21, 0x32, 0x7c, 0x25,
 | 
			
		||||
	0x2f, 0x8a, 0x7a, 0xe2, 0xb9, 0xda, 0xf4, 0x1b, 0xd4, 0xbf, 0x82, 0x7a, 0x5b, 0x5f, 0xd2, 0xfb,
 | 
			
		||||
	0x5e, 0xdb, 0xdd, 0x15, 0xa6, 0xdb, 0xee, 0x0e, 0x60, 0xdb, 0xee, 0xa3, 0x2c, 0x51, 0x68, 0x9b,
 | 
			
		||||
	0xaa, 0x2f, 0xe8, 0xbb, 0xd0, 0x56, 0xc8, 0x33, 0x97, 0x77, 0x9b, 0xe4, 0x82, 0xcd, 0x4e, 0x61,
 | 
			
		||||
	0x66, 0x4e, 0xb4, 0x55, 0x15, 0x8d, 0x2b, 0x5e, 0x92, 0x35, 0x48, 0x76, 0x00, 0xdb, 0xf4, 0x58,
 | 
			
		||||
	0xca, 0xdf, 0x6c, 0x92, 0x74, 0x0f, 0x5a, 0x13, 0xe4, 0x29, 0x25, 0x7b, 0x8b, 0x24, 0x76, 0x88,
 | 
			
		||||
	0x95, 0x79, 0xce, 0xd5, 0x2c, 0x6a, 0x53, 0x4c, 0xfe, 0x58, 0x1f, 0xd8, 0xa7, 0xc4, 0xa6, 0xbe,
 | 
			
		||||
	0x63, 0x2c, 0x4f, 0x3d, 0x5b, 0x1b, 0xf6, 0xa4, 0x36, 0x26, 0xee, 0xc1, 0xee, 0xa2, 0x93, 0x6e,
 | 
			
		||||
	0x68, 0x37, 0xe2, 0x33, 0xf8, 0xf0, 0x26, 0xf0, 0xb5, 0x03, 0xd1, 0x0a, 0xc8, 0x88, 0x7f, 0xdc,
 | 
			
		||||
	0xad, 0xf8, 0x79, 0x9d, 0xe6, 0x0b, 0xcc, 0xf0, 0x36, 0x9a, 0x4b, 0x08, 0x9f, 0xd6, 0xb9, 0x2c,
 | 
			
		||||
	0x23, 0xac, 0x1f, 0xce, 0x7f, 0x59, 0xd8, 0x69, 0xce, 0xb9, 0xe4, 0xe3, 0x25, 0xdb, 0x95, 0x29,
 | 
			
		||||
	0xb7, 0x5a, 0xad, 0x08, 0xd1, 0x43, 0x38, 0xbc, 0x16, 0xa2, 0xf9, 0x42, 0xbf, 0x31, 0x68, 0xd8,
 | 
			
		||||
	0x09, 0x7f, 0xfd, 0x98, 0xd6, 0x24, 0x4c, 0x69, 0x07, 0x6c, 0x2c, 0xb2, 0x5f, 0xe6, 0xb0, 0x9e,
 | 
			
		||||
	0xfd, 0x17, 0xd0, 0x5b, 0xf1, 0x45, 0xf2, 0x87, 0x62, 0x0d, 0xf5, 0x7d, 0xe8, 0x78, 0x22, 0xd4,
 | 
			
		||||
	0xba, 0x29, 0x59, 0xe3, 0xa7, 0x10, 0xaf, 0xc7, 0x58, 0x6f, 0xfa, 0x25, 0x3c, 0x5e, 0xfd, 0x95,
 | 
			
		||||
	0xf2, 0xa5, 0x2a, 0xf2, 0x1f, 0x62, 0xff, 0x19, 0x7c, 0x74, 0x0b, 0xd0, 0x7a, 0x12, 0xc7, 0x6e,
 | 
			
		||||
	0x2f, 0x70, 0xba, 0x2f, 0xd1, 0xfc, 0x36, 0x2f, 0x8c, 0x48, 0x0a, 0x69, 0xb7, 0xc6, 0xf8, 0xef,
 | 
			
		||||
	0x0b, 0x6b, 0x52, 0xfd, 0x28, 0x7c, 0x02, 0x6d, 0xf4, 0xff, 0xed, 0xbc, 0xb7, 0x5d, 0xb7, 0x3f,
 | 
			
		||||
	0x5c, 0x7d, 0x77, 0x58, 0xfd, 0xe9, 0x09, 0x68, 0x55, 0xbf, 0xed, 0xd7, 0x14, 0xbd, 0xff, 0xbc,
 | 
			
		||||
	0x13, 0xb9, 0xaf, 0x18, 0xf7, 0x31, 0x7b, 0x04, 0x3b, 0x54, 0xfe, 0x34, 0x92, 0x4a, 0x5d, 0x6f,
 | 
			
		||||
	0x00, 0xa5, 0xc6, 0x85, 0x0f, 0x9e, 0x43, 0xe8, 0xd2, 0x55, 0x85, 0x09, 0x0a, 0x9b, 0x10, 0x34,
 | 
			
		||||
	0xc9, 0xbf, 0xd8, 0x3a, 0x0b, 0xfe, 0x1c, 0xfc, 0xe8, 0xff, 0x01, 0x00, 0x00, 0xff, 0xff, 0xbe,
 | 
			
		||||
	0x80, 0x1e, 0x5f, 0x36, 0x10, 0x00, 0x00,
 | 
			
		||||
	// 2171 bytes of a gzipped FileDescriptorProto
 | 
			
		||||
	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x58, 0xdd, 0x6e, 0x1b, 0xb9,
 | 
			
		||||
	0x15, 0xae, 0xe4, 0x3f, 0xf9, 0x48, 0x72, 0x36, 0x74, 0xe2, 0x4c, 0x94, 0x6c, 0xe2, 0x4c, 0xd2,
 | 
			
		||||
	0xc6, 0x68, 0xb3, 0x6a, 0xea, 0x14, 0xbb, 0xc1, 0x36, 0xd8, 0xc6, 0xb1, 0xe3, 0x44, 0x1b, 0x7b,
 | 
			
		||||
	0xd7, 0x18, 0x39, 0x41, 0xb1, 0x40, 0x31, 0xa0, 0x66, 0x28, 0x89, 0xf0, 0xfc, 0x68, 0x49, 0xca,
 | 
			
		||||
	0xbb, 0xba, 0x6a, 0x9f, 0xa0, 0xe8, 0x03, 0xf4, 0xa6, 0x17, 0xbd, 0xe8, 0x4b, 0xf4, 0xa2, 0x6f,
 | 
			
		||||
	0xd0, 0x9b, 0x3e, 0x46, 0x81, 0x02, 0x7d, 0x80, 0xe2, 0x90, 0x9c, 0xd1, 0x8c, 0x25, 0xff, 0xf4,
 | 
			
		||||
	0xe7, 0x6e, 0xf8, 0x9d, 0xff, 0x43, 0x9e, 0xc3, 0xc3, 0x81, 0x2d, 0xa9, 0x18, 0x8d, 0x63, 0x26,
 | 
			
		||||
	0x25, 0x1d, 0x30, 0xe9, 0x07, 0x11, 0x67, 0x89, 0x92, 0x4c, 0x9c, 0x32, 0xe1, 0xf7, 0x05, 0x67,
 | 
			
		||||
	0x49, 0x28, 0xdb, 0x23, 0x91, 0xaa, 0xb4, 0xe5, 0x94, 0x39, 0x7b, 0x54, 0x32, 0x43, 0x71, 0xff,
 | 
			
		||||
	0x56, 0x81, 0xf5, 0xdd, 0x43, 0x39, 0xd8, 0xd5, 0xc2, 0xfb, 0x5a, 0xea, 0x50, 0x0e, 0x88, 0x03,
 | 
			
		||||
	0x2b, 0x5a, 0x86, 0x87, 0x4e, 0x65, 0xb3, 0xb2, 0xb5, 0xec, 0x65, 0x4b, 0xf2, 0x23, 0xb8, 0x16,
 | 
			
		||||
	0x0c, 0xa9, 0xf2, 0x59, 0xa2, 0xc4, 0xc4, 0x57, 0x93, 0x11, 0x73, 0xaa, 0x9b, 0x95, 0xad, 0x25,
 | 
			
		||||
	0xaf, 0x89, 0xf0, 0x6b, 0x44, 0x8f, 0x27, 0x23, 0x86, 0x1a, 0xac, 0x41, 0x67, 0x61, 0xb3, 0xb2,
 | 
			
		||||
	0xd5, 0xf0, 0xb2, 0x25, 0x79, 0x0e, 0x8e, 0x50, 0x3c, 0x66, 0xcf, 0xb6, 0x7d, 0xeb, 0x2d, 0xae,
 | 
			
		||||
	0xa4, 0xa2, 0xf1, 0xc8, 0x59, 0xdc, 0xac, 0x6c, 0xad, 0x78, 0x1b, 0x96, 0xde, 0xd5, 0xe4, 0xe3,
 | 
			
		||||
	0x8c, 0x4a, 0x1e, 0xc1, 0x1a, 0x0b, 0x86, 0xa9, 0xaf, 0x52, 0x5f, 0xb2, 0x24, 0x64, 0xc2, 0x59,
 | 
			
		||||
	0xda, 0xac, 0x6c, 0xd5, 0xbc, 0x06, 0xa2, 0xc7, 0x69, 0x57, 0x63, 0xee, 0x3f, 0x2a, 0x70, 0x67,
 | 
			
		||||
	0x4e, 0x4c, 0x9d, 0x24, 0x48, 0x63, 0x9e, 0x0c, 0xc8, 0x03, 0x68, 0xd8, 0x60, 0xfc, 0xbe, 0x48,
 | 
			
		||||
	0x63, 0x1b, 0x60, 0xdd, 0x62, 0xfb, 0x22, 0x8d, 0xaf, 0x1c, 0xe4, 0x53, 0xb8, 0x81, 0x2a, 0xfc,
 | 
			
		||||
	0x88, 0xc7, 0x5c, 0xb1, 0xd0, 0xa7, 0x41, 0x90, 0x8e, 0x13, 0xa5, 0x23, 0xae, 0x79, 0x04, 0x69,
 | 
			
		||||
	0x07, 0x86, 0xb4, 0x63, 0x28, 0xc5, 0xb4, 0x2c, 0x5e, 0x3d, 0x2d, 0x4b, 0x17, 0xa5, 0xc5, 0x9d,
 | 
			
		||||
	0x14, 0xf7, 0x70, 0x27, 0x0c, 0x4d, 0xc8, 0x98, 0xad, 0x2c, 0x4e, 0x95, 0xfa, 0x34, 0xcc, 0xb6,
 | 
			
		||||
	0x32, 0x8b, 0xfe, 0x38, 0xdd, 0x09, 0x43, 0xf2, 0x02, 0xee, 0x58, 0xaf, 0x13, 0x1a, 0x33, 0x3f,
 | 
			
		||||
	0x15, 0x3e, 0x8b, 0x29, 0x8f, 0x32, 0x11, 0x0c, 0x7b, 0xd5, 0xbb, 0x55, 0x60, 0xf9, 0x5a, 0xbc,
 | 
			
		||||
	0x46, 0x06, 0x2d, 0xed, 0xfe, 0xae, 0x94, 0xeb, 0xdc, 0xb6, 0xc7, 0xe4, 0x28, 0x4d, 0x24, 0x23,
 | 
			
		||||
	0x77, 0x60, 0x85, 0x09, 0x26, 0xc7, 0x91, 0xd2, 0xc6, 0x97, 0x3e, 0xaf, 0x6c, 0x7b, 0x19, 0x92,
 | 
			
		||||
	0x3b, 0xe8, 0xf3, 0x10, 0x6d, 0x31, 0x63, 0x2d, 0x73, 0xb0, 0x13, 0xee, 0x20, 0x46, 0x9e, 0x00,
 | 
			
		||||
	0x19, 0x31, 0x21, 0xd3, 0x84, 0xfa, 0xda, 0x43, 0xc3, 0xb9, 0xa0, 0xfd, 0xfa, 0xc8, 0x52, 0xbe,
 | 
			
		||||
	0xa2, 0x31, 0xd3, 0xdc, 0xee, 0xcf, 0x61, 0x63, 0xea, 0x8f, 0xc7, 0xe2, 0xf4, 0x94, 0xd9, 0x74,
 | 
			
		||||
	0xb4, 0xa0, 0x66, 0xaa, 0x22, 0x3f, 0xd3, 0xf9, 0xda, 0xdd, 0x87, 0x1b, 0x53, 0xa9, 0xb7, 0x3c,
 | 
			
		||||
	0xbc, 0x82, 0x0c, 0x21, 0xb0, 0x38, 0xe4, 0xa1, 0x39, 0x18, 0x35, 0x4f, 0x7f, 0xbb, 0x7f, 0xaf,
 | 
			
		||||
	0xc2, 0xcd, 0xb3, 0x47, 0x4f, 0x1e, 0x70, 0xa9, 0x88, 0x0b, 0x8d, 0x1e, 0x4f, 0x02, 0xc1, 0x62,
 | 
			
		||||
	0x96, 0x28, 0x1a, 0x69, 0x6d, 0x35, 0xaf, 0x84, 0x91, 0xcf, 0x60, 0xc5, 0xd6, 0xad, 0x53, 0xdd,
 | 
			
		||||
	0x5c, 0xd8, 0xaa, 0x6f, 0x7f, 0xdc, 0x9e, 0xab, 0xac, 0x6d, 0x93, 0x9c, 0x71, 0x93, 0x2d, 0xf8,
 | 
			
		||||
	0x28, 0xa6, 0xdf, 0xdb, 0xa2, 0xf7, 0xa7, 0x47, 0xb0, 0xe9, 0xad, 0xc5, 0xf4, 0x7b, 0xc3, 0xbd,
 | 
			
		||||
	0xab, 0x8f, 0x5f, 0x1b, 0xd6, 0x69, 0xa0, 0xf8, 0x29, 0x2b, 0x33, 0x2f, 0x6a, 0xe6, 0xeb, 0x86,
 | 
			
		||||
	0x54, 0xe4, 0xff, 0x31, 0x5c, 0xb7, 0x46, 0xcc, 0x19, 0xf7, 0x87, 0x5c, 0xd9, 0xa2, 0xbb, 0xd6,
 | 
			
		||||
	0xcf, 0x3c, 0x8a, 0xb9, 0x7a, 0xcb, 0x55, 0xeb, 0x1b, 0x58, 0xb6, 0x69, 0xbb, 0x07, 0x30, 0x8e,
 | 
			
		||||
	0xce, 0x24, 0xae, 0x80, 0x90, 0xa7, 0xb0, 0xce, 0xcc, 0x42, 0xb0, 0x88, 0x2a, 0x9e, 0x26, 0x72,
 | 
			
		||||
	0xc8, 0x47, 0x3a, 0x93, 0x4d, 0x6f, 0x1e, 0xc9, 0xfd, 0xd3, 0xc2, 0x6c, 0x4d, 0xcb, 0x37, 0x22,
 | 
			
		||||
	0x1d, 0x8f, 0x4c, 0x7a, 0x5b, 0x50, 0xeb, 0x09, 0xdc, 0xed, 0x3c, 0xb5, 0xf9, 0x7a, 0x26, 0xf5,
 | 
			
		||||
	0xd5, 0x39, 0xa9, 0x3f, 0x80, 0x86, 0xb1, 0x6a, 0x74, 0x3a, 0x0b, 0x3a, 0xff, 0x5b, 0xed, 0x0b,
 | 
			
		||||
	0x6c, 0xda, 0x5d, 0xd0, 0x80, 0x57, 0x92, 0x26, 0xef, 0xa1, 0x1e, 0xb3, 0xb8, 0xc7, 0x04, 0xfa,
 | 
			
		||||
	0x2e, 0x9d, 0x45, 0xad, 0xec, 0xd9, 0x55, 0x95, 0xc9, 0xc3, 0x5c, 0xd6, 0x2b, 0xea, 0x69, 0x1d,
 | 
			
		||||
	0x42, 0xbd, 0xc0, 0x86, 0x31, 0x27, 0xfa, 0xab, 0xb3, 0x67, 0x8a, 0xcb, 0xcb, 0xd7, 0x18, 0xb3,
 | 
			
		||||
	0x54, 0x42, 0xaf, 0xb0, 0x36, 0x6c, 0x19, 0x97, 0xb0, 0x96, 0x07, 0x1b, 0xf3, 0xad, 0x92, 0xbb,
 | 
			
		||||
	0xb0, 0x3a, 0x8e, 0xba, 0xba, 0x08, 0xf7, 0xec, 0xf6, 0x4d, 0x81, 0x92, 0xdd, 0x6a, 0xd9, 0x2e,
 | 
			
		||||
	0xf6, 0xde, 0xbb, 0xd3, 0x30, 0x8f, 0x22, 0x3a, 0x61, 0xe2, 0x2b, 0x1e, 0x9c, 0x60, 0xe5, 0xea,
 | 
			
		||||
	0x8d, 0x72, 0x60, 0xa5, 0xbc, 0x4f, 0xd9, 0x92, 0x6c, 0x42, 0x7d, 0x76, 0x97, 0x8a, 0x10, 0xf9,
 | 
			
		||||
	0x12, 0x56, 0x13, 0xab, 0x2b, 0xdb, 0xa1, 0x27, 0xed, 0x8b, 0xac, 0xb5, 0xcb, 0x90, 0x37, 0x15,
 | 
			
		||||
	0x6f, 0xed, 0xc3, 0x5a, 0x99, 0x78, 0xc1, 0x95, 0x87, 0x01, 0x5b, 0x2e, 0xdb, 0x77, 0xf2, 0xb5,
 | 
			
		||||
	0xdb, 0x2d, 0x9e, 0xcb, 0x2e, 0x53, 0xff, 0x95, 0xd2, 0xea, 0x19, 0xa5, 0xbf, 0x84, 0x87, 0x17,
 | 
			
		||||
	0x28, 0xcd, 0x9b, 0xab, 0x53, 0x6e, 0xae, 0xcd, 0xbc, 0xb3, 0xba, 0x69, 0xd1, 0x2b, 0x8f, 0x7d,
 | 
			
		||||
	0x3b, 0x66, 0xd2, 0x9e, 0xb9, 0x3d, 0xaa, 0x28, 0xf9, 0x14, 0x6e, 0x65, 0x2d, 0x55, 0x2a, 0xaa,
 | 
			
		||||
	0x98, 0x2f, 0x0c, 0x0b, 0x0b, 0xad, 0xa2, 0x9b, 0x96, 0xdc, 0x45, 0xaa, 0x97, 0x11, 0xd1, 0x60,
 | 
			
		||||
	0xb1, 0x41, 0x2d, 0xe7, 0x1d, 0xc8, 0xfd, 0x57, 0xb5, 0xd8, 0x77, 0x77, 0x87, 0x34, 0x19, 0x30,
 | 
			
		||||
	0x14, 0x1e, 0x4b, 0xf2, 0x10, 0x9a, 0x25, 0x63, 0xd6, 0x44, 0xa3, 0x68, 0x82, 0xdc, 0x87, 0xfa,
 | 
			
		||||
	0x48, 0x07, 0xe9, 0x17, 0x12, 0x02, 0x06, 0xc2, 0xc3, 0x4a, 0x9e, 0xc1, 0x06, 0x97, 0x3e, 0x1d,
 | 
			
		||||
	0xab, 0xd4, 0x1f, 0xb0, 0x84, 0x09, 0x8a, 0xd7, 0x6d, 0xbe, 0x23, 0x35, 0x6f, 0x9d, 0xcb, 0x9d,
 | 
			
		||||
	0xb1, 0x4a, 0xdf, 0x64, 0x34, 0x2d, 0xf4, 0x10, 0x9a, 0x43, 0x3e, 0x18, 0xfa, 0x23, 0xc1, 0x53,
 | 
			
		||||
	0xc1, 0xd5, 0x44, 0xf7, 0xb9, 0x9a, 0xd7, 0x40, 0xf0, 0xc8, 0x62, 0xe4, 0x13, 0x58, 0xcf, 0xfd,
 | 
			
		||||
	0x63, 0xca, 0xef, 0x4d, 0xfc, 0xb1, 0xcc, 0x27, 0x8b, 0xec, 0x82, 0xe9, 0x32, 0xf5, 0x6a, 0xf2,
 | 
			
		||||
	0x5e, 0x32, 0x41, 0x7e, 0x56, 0x60, 0xd7, 0xb9, 0xeb, 0x47, 0x74, 0x20, 0x9d, 0x65, 0x0c, 0xea,
 | 
			
		||||
	0xf3, 0xca, 0x53, 0xef, 0x7a, 0x31, 0xae, 0x7d, 0xa4, 0x91, 0x6d, 0xb8, 0x99, 0x30, 0x16, 0xfa,
 | 
			
		||||
	0x99, 0x9c, 0xb0, 0x1b, 0xe8, 0xac, 0x18, 0xd7, 0x91, 0x78, 0x64, 0x68, 0xf9, 0xde, 0x3e, 0x82,
 | 
			
		||||
	0x35, 0x9e, 0xcd, 0x74, 0x3e, 0x0f, 0x23, 0xe6, 0xd4, 0x8c, 0xef, 0x5c, 0x9a, 0x1c, 0x77, 0xc2,
 | 
			
		||||
	0x88, 0xb9, 0xc7, 0x70, 0x1b, 0xb3, 0x6e, 0x85, 0x4d, 0xda, 0x73, 0x15, 0x1b, 0xb0, 0x5c, 0x3a,
 | 
			
		||||
	0x1d, 0x76, 0x75, 0x69, 0xae, 0xdd, 0x3f, 0xd6, 0x8b, 0x9b, 0x79, 0x54, 0xdc, 0x27, 0x3d, 0x3b,
 | 
			
		||||
	0xe1, 0xb6, 0xda, 0xb0, 0x8d, 0xe6, 0xba, 0xc1, 0x4c, 0xb4, 0xcf, 0xcf, 0xde, 0x62, 0xf7, 0xda,
 | 
			
		||||
	0xf3, 0x95, 0x9d, 0xbd, 0xc6, 0x5a, 0x7f, 0x86, 0xfc, 0x06, 0xb9, 0xe8, 0xe2, 0x9d, 0x39, 0x50,
 | 
			
		||||
	0xd5, 0x39, 0x07, 0xea, 0x27, 0x40, 0x06, 0x38, 0x2d, 0xe8, 0xb0, 0x42, 0x9f, 0x8e, 0x46, 0x3e,
 | 
			
		||||
	0x0f, 0xed, 0xa5, 0x78, 0x0d, 0x29, 0xba, 0xa6, 0xc2, 0x9d, 0xd1, 0xa8, 0xa3, 0x27, 0x25, 0xcd,
 | 
			
		||||
	0x6c, 0xe7, 0x2e, 0x3e, 0xb2, 0x17, 0x62, 0x03, 0x51, 0x33, 0x6d, 0x75, 0x46, 0x78, 0xcb, 0x16,
 | 
			
		||||
	0xb9, 0x46, 0xa9, 0x30, 0x57, 0x61, 0xd3, 0x5b, 0x9b, 0xf2, 0x1d, 0xa5, 0x42, 0xdf, 0xb2, 0xe7,
 | 
			
		||||
	0x9e, 0x91, 0x79, 0x07, 0xe4, 0x39, 0x38, 0x69, 0x12, 0xf1, 0x04, 0x75, 0x4b, 0xc9, 0xd3, 0xc4,
 | 
			
		||||
	0xe7, 0x89, 0x54, 0x34, 0x09, 0x98, 0xd4, 0x67, 0xa4, 0xe9, 0x6d, 0x18, 0x7a, 0xd7, 0x90, 0x3b,
 | 
			
		||||
	0x19, 0xf5, 0xbc, 0xc3, 0x0b, 0xe7, 0x1c, 0xde, 0x33, 0x5b, 0x7f, 0x6d, 0xa6, 0xcc, 0x3e, 0x06,
 | 
			
		||||
	0xf8, 0x76, 0xcc, 0xc4, 0xc4, 0x44, 0x77, 0x43, 0xdb, 0x5e, 0xd5, 0x88, 0x0e, 0xec, 0x87, 0xd3,
 | 
			
		||||
	0x91, 0x52, 0xa6, 0x63, 0x11, 0x30, 0xe7, 0xb6, 0xde, 0x9c, 0xa6, 0x45, 0xbb, 0x1a, 0x44, 0x33,
 | 
			
		||||
	0xf4, 0x94, 0x2a, 0x2a, 0xfc, 0x21, 0x95, 0x43, 0xe7, 0xbe, 0x1e, 0x74, 0xc1, 0x40, 0x6f, 0xa9,
 | 
			
		||||
	0x1c, 0x22, 0x43, 0x44, 0xa5, 0xf2, 0xa3, 0x74, 0x90, 0xf6, 0xfb, 0xce, 0x27, 0xda, 0x0e, 0x20,
 | 
			
		||||
	0x74, 0xa0, 0x11, 0xf4, 0x23, 0x67, 0x48, 0x9c, 0xb6, 0xf1, 0x23, 0xa3, 0x27, 0xb8, 0x15, 0x9a,
 | 
			
		||||
	0x2c, 0x19, 0x4b, 0x7c, 0x93, 0x1a, 0xe7, 0xa7, 0x66, 0x2b, 0x10, 0xef, 0x32, 0x96, 0x7c, 0xad,
 | 
			
		||||
	0x51, 0x72, 0x07, 0x56, 0x83, 0x88, 0x26, 0xbe, 0xa0, 0xc9, 0x89, 0xb3, 0xad, 0x59, 0x6a, 0x08,
 | 
			
		||||
	0x78, 0x34, 0x39, 0x41, 0xa2, 0xde, 0x51, 0x9d, 0x8c, 0xcf, 0x4c, 0x13, 0x46, 0x40, 0xa7, 0x62,
 | 
			
		||||
	0x03, 0x96, 0xf1, 0x9b, 0x87, 0xce, 0x73, 0x1d, 0xa3, 0x5d, 0xe5, 0x87, 0x25, 0xa4, 0x8a, 0xfa,
 | 
			
		||||
	0xbd, 0x28, 0xed, 0x39, 0x2f, 0x74, 0x7c, 0xfa, 0xb0, 0x60, 0x7b, 0x7d, 0x15, 0xa5, 0x3d, 0xb2,
 | 
			
		||||
	0x67, 0xed, 0x22, 0x97, 0xf3, 0x72, 0xb3, 0xb2, 0x55, 0xdf, 0x7e, 0x7c, 0x71, 0x1d, 0xb4, 0x77,
 | 
			
		||||
	0x23, 0x9a, 0xa0, 0xbc, 0x71, 0x50, 0x37, 0xea, 0xdb, 0xa0, 0xbf, 0x7d, 0x45, 0x07, 0xce, 0x8e,
 | 
			
		||||
	0xf6, 0x6f, 0x05, 0xd7, 0xc7, 0x74, 0x40, 0xf6, 0xa1, 0x29, 0x78, 0x80, 0xbd, 0x8d, 0x49, 0x96,
 | 
			
		||||
	0x04, 0xcc, 0x79, 0xa3, 0x8b, 0xed, 0xc1, 0x25, 0x46, 0xde, 0x7d, 0xf0, 0x1a, 0x28, 0x77, 0x64,
 | 
			
		||||
	0xc5, 0xb0, 0xa2, 0x7b, 0x22, 0xa5, 0x61, 0x80, 0xf9, 0xe4, 0xa1, 0xf3, 0xd6, 0xbc, 0x86, 0x72,
 | 
			
		||||
	0xac, 0x13, 0x12, 0x17, 0x9a, 0x3a, 0xe2, 0x28, 0xed, 0xf5, 0x26, 0xc8, 0xd3, 0x31, 0x3c, 0x08,
 | 
			
		||||
	0x1e, 0x20, 0xd6, 0x09, 0xc9, 0x4b, 0xb8, 0xfb, 0x1d, 0x55, 0xc1, 0x90, 0x27, 0x03, 0x7f, 0xaa,
 | 
			
		||||
	0xcf, 0x3e, 0x1b, 0x78, 0xe8, 0x7c, 0xa9, 0x53, 0xdf, 0xca, 0x78, 0x5e, 0x65, 0x2c, 0x3b, 0x19,
 | 
			
		||||
	0x07, 0x16, 0xc1, 0x3c, 0x0d, 0xa3, 0x11, 0x0f, 0x9d, 0x77, 0xa6, 0x08, 0x66, 0xa5, 0x91, 0x4a,
 | 
			
		||||
	0x5e, 0x40, 0x6b, 0x8e, 0xe4, 0x29, 0x67, 0xdf, 0x31, 0x21, 0x9d, 0x03, 0x2d, 0xeb, 0xcc, 0xc8,
 | 
			
		||||
	0x7e, 0x30, 0xf4, 0x73, 0xec, 0x2a, 0xae, 0x22, 0xe6, 0x1c, 0xea, 0x9c, 0xcf, 0xda, 0x3d, 0x46,
 | 
			
		||||
	0x6a, 0xeb, 0x00, 0x6a, 0xd9, 0x9e, 0x91, 0xbb, 0x00, 0xe9, 0x60, 0x90, 0xf5, 0x19, 0xd3, 0x16,
 | 
			
		||||
	0x6b, 0xe9, 0x60, 0x60, 0x1a, 0x8c, 0x0b, 0xfa, 0xe1, 0xe8, 0x0f, 0x70, 0x4c, 0x42, 0x06, 0x6c,
 | 
			
		||||
	0x59, 0x8b, 0x5e, 0x1d, 0x41, 0x33, 0x3a, 0x85, 0xad, 0x27, 0x50, 0x7d, 0xf7, 0x81, 0x7c, 0x04,
 | 
			
		||||
	0x0b, 0x27, 0x6c, 0xa2, 0x15, 0xac, 0x7a, 0xf8, 0x49, 0x6e, 0xc0, 0xd2, 0x29, 0x8d, 0xc6, 0x59,
 | 
			
		||||
	0xa3, 0x36, 0x0b, 0x77, 0x6f, 0x76, 0x1e, 0x3e, 0x12, 0x69, 0x9f, 0x47, 0xac, 0x93, 0xf4, 0xd3,
 | 
			
		||||
	0x62, 0xa1, 0x9a, 0xbe, 0x69, 0xbb, 0x68, 0x33, 0x7f, 0xe5, 0x22, 0xe8, 0xfe, 0xa5, 0x5a, 0x9c,
 | 
			
		||||
	0x34, 0x66, 0xd4, 0x5c, 0xed, 0x19, 0x37, 0x6b, 0xab, 0x3a, 0xc7, 0x16, 0x1e, 0x34, 0x7c, 0xbe,
 | 
			
		||||
	0xfa, 0x81, 0x60, 0x78, 0x41, 0xdb, 0x5e, 0x5c, 0x47, 0x6c, 0xd7, 0x40, 0x58, 0x8f, 0x82, 0xd1,
 | 
			
		||||
	0xc8, 0xd4, 0xe3, 0xa2, 0xa9, 0x47, 0x04, 0x74, 0x3d, 0x62, 0x25, 0x73, 0x35, 0x31, 0xc4, 0x25,
 | 
			
		||||
	0x43, 0x44, 0x20, 0xeb, 0x5b, 0xa6, 0xd3, 0x6a, 0xea, 0xb2, 0xa6, 0xae, 0x6a, 0x44, 0x93, 0x1f,
 | 
			
		||||
	0x40, 0x43, 0x1f, 0x33, 0x61, 0xc5, 0x57, 0x34, 0x43, 0xdd, 0x62, 0x9a, 0xa5, 0x05, 0xb5, 0x21,
 | 
			
		||||
	0xa3, 0xa1, 0x6e, 0x25, 0x35, 0xa3, 0x3d, 0x5b, 0xeb, 0x29, 0x6e, 0x1c, 0xc7, 0x54, 0x4c, 0x9c,
 | 
			
		||||
	0x55, 0x53, 0x85, 0x76, 0xe9, 0xfe, 0xa6, 0x38, 0xee, 0x9a, 0x30, 0x8a, 0xb3, 0xfd, 0x05, 0xf3,
 | 
			
		||||
	0xdf, 0x5d, 0x58, 0xd5, 0xa7, 0xa1, 0x70, 0x07, 0x4f, 0x01, 0xf2, 0x18, 0xae, 0x95, 0x73, 0x6a,
 | 
			
		||||
	0x06, 0xde, 0x65, 0x6f, 0xad, 0x94, 0x54, 0xe9, 0x7e, 0x03, 0x8f, 0x2e, 0x72, 0xe0, 0xf2, 0x59,
 | 
			
		||||
	0x11, 0x29, 0xda, 0xae, 0x3d, 0x95, 0x4b, 0x5e, 0xb6, 0x74, 0xbd, 0x62, 0x70, 0x7b, 0x2c, 0x62,
 | 
			
		||||
	0x57, 0x0e, 0xee, 0x7c, 0x9d, 0x2f, 0x8b, 0xfe, 0xce, 0xea, 0xbc, 0xc2, 0x6c, 0xfb, 0xd7, 0xd2,
 | 
			
		||||
	0x13, 0xe3, 0x90, 0x26, 0x74, 0x30, 0xe3, 0x56, 0x66, 0xbc, 0x52, 0x32, 0x7e, 0x49, 0xce, 0xb7,
 | 
			
		||||
	0xe1, 0xe6, 0x99, 0x9c, 0xe7, 0xff, 0x1a, 0x30, 0xf3, 0xeb, 0xe5, 0xcc, 0x9b, 0x9f, 0x13, 0x9f,
 | 
			
		||||
	0xc2, 0xad, 0xb3, 0x32, 0xfa, 0x3d, 0xc3, 0x42, 0xfd, 0xea, 0x5b, 0xf6, 0x6e, 0x96, 0xa5, 0xcc,
 | 
			
		||||
	0x1f, 0x89, 0x33, 0x69, 0x98, 0x8d, 0xe1, 0x0a, 0x69, 0xf8, 0x15, 0xb4, 0xe6, 0xfc, 0x78, 0x39,
 | 
			
		||||
	0x4e, 0x2f, 0xcb, 0xc1, 0x26, 0x64, 0x7f, 0xba, 0xf4, 0xa4, 0x50, 0x2d, 0xfd, 0xfc, 0x42, 0xc8,
 | 
			
		||||
	0xfd, 0x02, 0xdc, 0xf3, 0x35, 0x5f, 0xc1, 0xb3, 0x5f, 0xc3, 0xfd, 0xf9, 0xbf, 0x60, 0xf6, 0x45,
 | 
			
		||||
	0x1a, 0xff, 0xef, 0xee, 0xed, 0xc2, 0xe3, 0x4b, 0xd4, 0x5f, 0xc1, 0xc7, 0x3b, 0x66, 0x70, 0x36,
 | 
			
		||||
	0x4a, 0xde, 0x30, 0xf5, 0x3a, 0x4e, 0x15, 0x0f, 0xd2, 0x04, 0x5f, 0x8d, 0xee, 0x3f, 0x17, 0x8b,
 | 
			
		||||
	0xf3, 0x6f, 0x91, 0x44, 0xbe, 0x80, 0x55, 0x66, 0xd7, 0x38, 0xfc, 0xe2, 0x8d, 0xbb, 0xd9, 0x9e,
 | 
			
		||||
	0xcf, 0xdb, 0xce, 0x16, 0xde, 0x54, 0x84, 0xfc, 0x02, 0x6a, 0x52, 0xf1, 0xe0, 0x04, 0x2f, 0x26,
 | 
			
		||||
	0x33, 0x1d, 0xdf, 0x3f, 0x4f, 0xbc, 0x6b, 0xf8, 0xbc, 0x5c, 0x00, 0x27, 0x6b, 0xd6, 0xef, 0xb3,
 | 
			
		||||
	0x40, 0x65, 0xaf, 0xdf, 0x7b, 0xe7, 0x9a, 0xd6, 0x6c, 0x5e, 0xc6, 0xde, 0xfa, 0x43, 0x05, 0x6a,
 | 
			
		||||
	0x19, 0x03, 0x21, 0xb0, 0xa8, 0x0b, 0xc0, 0xdc, 0x31, 0xfa, 0x1b, 0x2f, 0x19, 0xf3, 0x27, 0xc8,
 | 
			
		||||
	0x94, 0xab, 0x59, 0xe0, 0xa8, 0xa3, 0x5b, 0xb6, 0x9e, 0xb5, 0xc6, 0x32, 0x6f, 0xda, 0xba, 0x91,
 | 
			
		||||
	0x1f, 0x50, 0xa9, 0xde, 0x4b, 0xd3, 0xb5, 0xc7, 0x92, 0x95, 0xfe, 0x24, 0xd5, 0xc6, 0x92, 0x99,
 | 
			
		||||
	0x1f, 0x48, 0x0f, 0xa1, 0xa9, 0x55, 0x08, 0x16, 0x30, 0x8e, 0x65, 0xb1, 0x34, 0xd5, 0xe0, 0x59,
 | 
			
		||||
	0xac, 0x95, 0xc0, 0x8a, 0x8d, 0xf6, 0x3f, 0x70, 0x6e, 0x46, 0xf3, 0xc2, 0xac, 0x66, 0x14, 0x35,
 | 
			
		||||
	0x13, 0x84, 0xf1, 0xcb, 0x2c, 0x5a, 0xbf, 0xaf, 0xc0, 0xb2, 0x49, 0xd1, 0xff, 0xdb, 0xde, 0x03,
 | 
			
		||||
	0x68, 0xf0, 0xa4, 0xcf, 0x13, 0xae, 0x18, 0x26, 0xcc, 0x3e, 0x38, 0xeb, 0x19, 0xf6, 0x5e, 0xb2,
 | 
			
		||||
	0xa9, 0x4b, 0x4b, 0x05, 0x97, 0x5e, 0x2d, 0xbd, 0xad, 0xfc, 0xb6, 0xf2, 0x83, 0x7f, 0x07, 0x00,
 | 
			
		||||
	0x00, 0xff, 0xff, 0xc5, 0x50, 0x67, 0x9b, 0xd4, 0x17, 0x00, 0x00,
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										680
									
								
								vendor/github.com/Philipp15b/go-steam/protocol/protobuf/client_server_login.pb.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										680
									
								
								vendor/github.com/Philipp15b/go-steam/protocol/protobuf/client_server_login.pb.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -52,7 +52,7 @@ func (m *CMsgClientHeartBeat) XXX_DiscardUnknown() {
 | 
			
		||||
var xxx_messageInfo_CMsgClientHeartBeat proto.InternalMessageInfo
 | 
			
		||||
 | 
			
		||||
type CMsgClientServerTimestampRequest struct {
 | 
			
		||||
	ClientRequestTimestamp *uint64  `protobuf:"varint,1,opt,name=client_request_timestamp" json:"client_request_timestamp,omitempty"`
 | 
			
		||||
	ClientRequestTimestamp *uint64  `protobuf:"varint,1,opt,name=client_request_timestamp,json=clientRequestTimestamp" json:"client_request_timestamp,omitempty"`
 | 
			
		||||
	XXX_NoUnkeyedLiteral   struct{} `json:"-"`
 | 
			
		||||
	XXX_unrecognized       []byte   `json:"-"`
 | 
			
		||||
	XXX_sizecache          int32    `json:"-"`
 | 
			
		||||
@@ -91,8 +91,8 @@ func (m *CMsgClientServerTimestampRequest) GetClientRequestTimestamp() uint64 {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type CMsgClientServerTimestampResponse struct {
 | 
			
		||||
	ClientRequestTimestamp *uint64  `protobuf:"varint,1,opt,name=client_request_timestamp" json:"client_request_timestamp,omitempty"`
 | 
			
		||||
	ServerTimestampMs      *uint64  `protobuf:"varint,2,opt,name=server_timestamp_ms" json:"server_timestamp_ms,omitempty"`
 | 
			
		||||
	ClientRequestTimestamp *uint64  `protobuf:"varint,1,opt,name=client_request_timestamp,json=clientRequestTimestamp" json:"client_request_timestamp,omitempty"`
 | 
			
		||||
	ServerTimestampMs      *uint64  `protobuf:"varint,2,opt,name=server_timestamp_ms,json=serverTimestampMs" json:"server_timestamp_ms,omitempty"`
 | 
			
		||||
	XXX_NoUnkeyedLiteral   struct{} `json:"-"`
 | 
			
		||||
	XXX_unrecognized       []byte   `json:"-"`
 | 
			
		||||
	XXX_sizecache          int32    `json:"-"`
 | 
			
		||||
@@ -137,66 +137,141 @@ func (m *CMsgClientServerTimestampResponse) GetServerTimestampMs() uint64 {
 | 
			
		||||
	return 0
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type CMsgClientSecret struct {
 | 
			
		||||
	Version              *uint32  `protobuf:"varint,1,opt,name=version" json:"version,omitempty"`
 | 
			
		||||
	Appid                *uint32  `protobuf:"varint,2,opt,name=appid" json:"appid,omitempty"`
 | 
			
		||||
	Deviceid             *uint32  `protobuf:"varint,3,opt,name=deviceid" json:"deviceid,omitempty"`
 | 
			
		||||
	Nonce                *uint64  `protobuf:"fixed64,4,opt,name=nonce" json:"nonce,omitempty"`
 | 
			
		||||
	Hmac                 []byte   `protobuf:"bytes,5,opt,name=hmac" json:"hmac,omitempty"`
 | 
			
		||||
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
 | 
			
		||||
	XXX_unrecognized     []byte   `json:"-"`
 | 
			
		||||
	XXX_sizecache        int32    `json:"-"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *CMsgClientSecret) Reset()         { *m = CMsgClientSecret{} }
 | 
			
		||||
func (m *CMsgClientSecret) String() string { return proto.CompactTextString(m) }
 | 
			
		||||
func (*CMsgClientSecret) ProtoMessage()    {}
 | 
			
		||||
func (*CMsgClientSecret) Descriptor() ([]byte, []int) {
 | 
			
		||||
	return fileDescriptor_c98cb07f62c057af, []int{3}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *CMsgClientSecret) XXX_Unmarshal(b []byte) error {
 | 
			
		||||
	return xxx_messageInfo_CMsgClientSecret.Unmarshal(m, b)
 | 
			
		||||
}
 | 
			
		||||
func (m *CMsgClientSecret) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
 | 
			
		||||
	return xxx_messageInfo_CMsgClientSecret.Marshal(b, m, deterministic)
 | 
			
		||||
}
 | 
			
		||||
func (m *CMsgClientSecret) XXX_Merge(src proto.Message) {
 | 
			
		||||
	xxx_messageInfo_CMsgClientSecret.Merge(m, src)
 | 
			
		||||
}
 | 
			
		||||
func (m *CMsgClientSecret) XXX_Size() int {
 | 
			
		||||
	return xxx_messageInfo_CMsgClientSecret.Size(m)
 | 
			
		||||
}
 | 
			
		||||
func (m *CMsgClientSecret) XXX_DiscardUnknown() {
 | 
			
		||||
	xxx_messageInfo_CMsgClientSecret.DiscardUnknown(m)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var xxx_messageInfo_CMsgClientSecret proto.InternalMessageInfo
 | 
			
		||||
 | 
			
		||||
func (m *CMsgClientSecret) GetVersion() uint32 {
 | 
			
		||||
	if m != nil && m.Version != nil {
 | 
			
		||||
		return *m.Version
 | 
			
		||||
	}
 | 
			
		||||
	return 0
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *CMsgClientSecret) GetAppid() uint32 {
 | 
			
		||||
	if m != nil && m.Appid != nil {
 | 
			
		||||
		return *m.Appid
 | 
			
		||||
	}
 | 
			
		||||
	return 0
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *CMsgClientSecret) GetDeviceid() uint32 {
 | 
			
		||||
	if m != nil && m.Deviceid != nil {
 | 
			
		||||
		return *m.Deviceid
 | 
			
		||||
	}
 | 
			
		||||
	return 0
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *CMsgClientSecret) GetNonce() uint64 {
 | 
			
		||||
	if m != nil && m.Nonce != nil {
 | 
			
		||||
		return *m.Nonce
 | 
			
		||||
	}
 | 
			
		||||
	return 0
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *CMsgClientSecret) GetHmac() []byte {
 | 
			
		||||
	if m != nil {
 | 
			
		||||
		return m.Hmac
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type CMsgClientLogon struct {
 | 
			
		||||
	ProtocolVersion                   *uint32  `protobuf:"varint,1,opt,name=protocol_version" json:"protocol_version,omitempty"`
 | 
			
		||||
	ObfustucatedPrivateIp             *uint32  `protobuf:"varint,2,opt,name=obfustucated_private_ip" json:"obfustucated_private_ip,omitempty"`
 | 
			
		||||
	CellId                            *uint32  `protobuf:"varint,3,opt,name=cell_id" json:"cell_id,omitempty"`
 | 
			
		||||
	LastSessionId                     *uint32  `protobuf:"varint,4,opt,name=last_session_id" json:"last_session_id,omitempty"`
 | 
			
		||||
	ClientPackageVersion              *uint32  `protobuf:"varint,5,opt,name=client_package_version" json:"client_package_version,omitempty"`
 | 
			
		||||
	ClientLanguage                    *string  `protobuf:"bytes,6,opt,name=client_language" json:"client_language,omitempty"`
 | 
			
		||||
	ClientOsType                      *uint32  `protobuf:"varint,7,opt,name=client_os_type" json:"client_os_type,omitempty"`
 | 
			
		||||
	ShouldRememberPassword            *bool    `protobuf:"varint,8,opt,name=should_remember_password,def=0" json:"should_remember_password,omitempty"`
 | 
			
		||||
	WineVersion                       *string  `protobuf:"bytes,9,opt,name=wine_version" json:"wine_version,omitempty"`
 | 
			
		||||
	PingMsFromCellSearch              *uint32  `protobuf:"varint,10,opt,name=ping_ms_from_cell_search" json:"ping_ms_from_cell_search,omitempty"`
 | 
			
		||||
	PublicIp                          *uint32  `protobuf:"varint,20,opt,name=public_ip" json:"public_ip,omitempty"`
 | 
			
		||||
	QosLevel                          *uint32  `protobuf:"varint,21,opt,name=qos_level" json:"qos_level,omitempty"`
 | 
			
		||||
	ClientSuppliedSteamId             *uint64  `protobuf:"fixed64,22,opt,name=client_supplied_steam_id" json:"client_supplied_steam_id,omitempty"`
 | 
			
		||||
	MachineId                         []byte   `protobuf:"bytes,30,opt,name=machine_id" json:"machine_id,omitempty"`
 | 
			
		||||
	LauncherType                      *uint32  `protobuf:"varint,31,opt,name=launcher_type,def=0" json:"launcher_type,omitempty"`
 | 
			
		||||
	UiMode                            *uint32  `protobuf:"varint,32,opt,name=ui_mode,def=0" json:"ui_mode,omitempty"`
 | 
			
		||||
	ChatMode                          *uint32  `protobuf:"varint,33,opt,name=chat_mode,def=0" json:"chat_mode,omitempty"`
 | 
			
		||||
	Steam2AuthTicket                  []byte   `protobuf:"bytes,41,opt,name=steam2_auth_ticket" json:"steam2_auth_ticket,omitempty"`
 | 
			
		||||
	EmailAddress                      *string  `protobuf:"bytes,42,opt,name=email_address" json:"email_address,omitempty"`
 | 
			
		||||
	Rtime32AccountCreation            *uint32  `protobuf:"fixed32,43,opt,name=rtime32_account_creation" json:"rtime32_account_creation,omitempty"`
 | 
			
		||||
	AccountName                       *string  `protobuf:"bytes,50,opt,name=account_name" json:"account_name,omitempty"`
 | 
			
		||||
	Password                          *string  `protobuf:"bytes,51,opt,name=password" json:"password,omitempty"`
 | 
			
		||||
	GameServerToken                   *string  `protobuf:"bytes,52,opt,name=game_server_token" json:"game_server_token,omitempty"`
 | 
			
		||||
	LoginKey                          *string  `protobuf:"bytes,60,opt,name=login_key" json:"login_key,omitempty"`
 | 
			
		||||
	WasConvertedDeprecatedMsg         *bool    `protobuf:"varint,70,opt,name=was_converted_deprecated_msg,def=0" json:"was_converted_deprecated_msg,omitempty"`
 | 
			
		||||
	AnonUserTargetAccountName         *string  `protobuf:"bytes,80,opt,name=anon_user_target_account_name" json:"anon_user_target_account_name,omitempty"`
 | 
			
		||||
	ResolvedUserSteamId               *uint64  `protobuf:"fixed64,81,opt,name=resolved_user_steam_id" json:"resolved_user_steam_id,omitempty"`
 | 
			
		||||
	EresultSentryfile                 *int32   `protobuf:"varint,82,opt,name=eresult_sentryfile" json:"eresult_sentryfile,omitempty"`
 | 
			
		||||
	ShaSentryfile                     []byte   `protobuf:"bytes,83,opt,name=sha_sentryfile" json:"sha_sentryfile,omitempty"`
 | 
			
		||||
	AuthCode                          *string  `protobuf:"bytes,84,opt,name=auth_code" json:"auth_code,omitempty"`
 | 
			
		||||
	OtpType                           *int32   `protobuf:"varint,85,opt,name=otp_type" json:"otp_type,omitempty"`
 | 
			
		||||
	OtpValue                          *uint32  `protobuf:"varint,86,opt,name=otp_value" json:"otp_value,omitempty"`
 | 
			
		||||
	OtpIdentifier                     *string  `protobuf:"bytes,87,opt,name=otp_identifier" json:"otp_identifier,omitempty"`
 | 
			
		||||
	Steam2TicketRequest               *bool    `protobuf:"varint,88,opt,name=steam2_ticket_request" json:"steam2_ticket_request,omitempty"`
 | 
			
		||||
	SonyPsnTicket                     []byte   `protobuf:"bytes,90,opt,name=sony_psn_ticket" json:"sony_psn_ticket,omitempty"`
 | 
			
		||||
	SonyPsnServiceId                  *string  `protobuf:"bytes,91,opt,name=sony_psn_service_id" json:"sony_psn_service_id,omitempty"`
 | 
			
		||||
	CreateNewPsnLinkedAccountIfNeeded *bool    `protobuf:"varint,92,opt,name=create_new_psn_linked_account_if_needed,def=0" json:"create_new_psn_linked_account_if_needed,omitempty"`
 | 
			
		||||
	SonyPsnName                       *string  `protobuf:"bytes,93,opt,name=sony_psn_name" json:"sony_psn_name,omitempty"`
 | 
			
		||||
	GameServerAppId                   *int32   `protobuf:"varint,94,opt,name=game_server_app_id" json:"game_server_app_id,omitempty"`
 | 
			
		||||
	SteamguardDontRememberComputer    *bool    `protobuf:"varint,95,opt,name=steamguard_dont_remember_computer" json:"steamguard_dont_remember_computer,omitempty"`
 | 
			
		||||
	MachineName                       *string  `protobuf:"bytes,96,opt,name=machine_name" json:"machine_name,omitempty"`
 | 
			
		||||
	MachineNameUserchosen             *string  `protobuf:"bytes,97,opt,name=machine_name_userchosen" json:"machine_name_userchosen,omitempty"`
 | 
			
		||||
	CountryOverride                   *string  `protobuf:"bytes,98,opt,name=country_override" json:"country_override,omitempty"`
 | 
			
		||||
	IsSteamBox                        *bool    `protobuf:"varint,99,opt,name=is_steam_box" json:"is_steam_box,omitempty"`
 | 
			
		||||
	ClientInstanceId                  *uint64  `protobuf:"varint,100,opt,name=client_instance_id" json:"client_instance_id,omitempty"`
 | 
			
		||||
	TwoFactorCode                     *string  `protobuf:"bytes,101,opt,name=two_factor_code" json:"two_factor_code,omitempty"`
 | 
			
		||||
	SupportsRateLimitResponse         *bool    `protobuf:"varint,102,opt,name=supports_rate_limit_response" json:"supports_rate_limit_response,omitempty"`
 | 
			
		||||
	WebLogonNonce                     *string  `protobuf:"bytes,103,opt,name=web_logon_nonce" json:"web_logon_nonce,omitempty"`
 | 
			
		||||
	PriorityReason                    *int32   `protobuf:"varint,104,opt,name=priority_reason" json:"priority_reason,omitempty"`
 | 
			
		||||
	XXX_NoUnkeyedLiteral              struct{} `json:"-"`
 | 
			
		||||
	XXX_unrecognized                  []byte   `json:"-"`
 | 
			
		||||
	XXX_sizecache                     int32    `json:"-"`
 | 
			
		||||
	ProtocolVersion                   *uint32           `protobuf:"varint,1,opt,name=protocol_version,json=protocolVersion" json:"protocol_version,omitempty"`
 | 
			
		||||
	DeprecatedObfustucatedPrivateIp   *uint32           `protobuf:"varint,2,opt,name=deprecated_obfustucated_private_ip,json=deprecatedObfustucatedPrivateIp" json:"deprecated_obfustucated_private_ip,omitempty"`
 | 
			
		||||
	CellId                            *uint32           `protobuf:"varint,3,opt,name=cell_id,json=cellId" json:"cell_id,omitempty"`
 | 
			
		||||
	LastSessionId                     *uint32           `protobuf:"varint,4,opt,name=last_session_id,json=lastSessionId" json:"last_session_id,omitempty"`
 | 
			
		||||
	ClientPackageVersion              *uint32           `protobuf:"varint,5,opt,name=client_package_version,json=clientPackageVersion" json:"client_package_version,omitempty"`
 | 
			
		||||
	ClientLanguage                    *string           `protobuf:"bytes,6,opt,name=client_language,json=clientLanguage" json:"client_language,omitempty"`
 | 
			
		||||
	ClientOsType                      *uint32           `protobuf:"varint,7,opt,name=client_os_type,json=clientOsType" json:"client_os_type,omitempty"`
 | 
			
		||||
	ShouldRememberPassword            *bool             `protobuf:"varint,8,opt,name=should_remember_password,json=shouldRememberPassword,def=0" json:"should_remember_password,omitempty"`
 | 
			
		||||
	WineVersion                       *string           `protobuf:"bytes,9,opt,name=wine_version,json=wineVersion" json:"wine_version,omitempty"`
 | 
			
		||||
	Deprecated_10                     *uint32           `protobuf:"varint,10,opt,name=deprecated_10,json=deprecated10" json:"deprecated_10,omitempty"`
 | 
			
		||||
	ObfuscatedPrivateIp               *CMsgIPAddress    `protobuf:"bytes,11,opt,name=obfuscated_private_ip,json=obfuscatedPrivateIp" json:"obfuscated_private_ip,omitempty"`
 | 
			
		||||
	DeprecatedPublicIp                *uint32           `protobuf:"varint,20,opt,name=deprecated_public_ip,json=deprecatedPublicIp" json:"deprecated_public_ip,omitempty"`
 | 
			
		||||
	QosLevel                          *uint32           `protobuf:"varint,21,opt,name=qos_level,json=qosLevel" json:"qos_level,omitempty"`
 | 
			
		||||
	ClientSuppliedSteamId             *uint64           `protobuf:"fixed64,22,opt,name=client_supplied_steam_id,json=clientSuppliedSteamId" json:"client_supplied_steam_id,omitempty"`
 | 
			
		||||
	PublicIp                          *CMsgIPAddress    `protobuf:"bytes,23,opt,name=public_ip,json=publicIp" json:"public_ip,omitempty"`
 | 
			
		||||
	MachineId                         []byte            `protobuf:"bytes,30,opt,name=machine_id,json=machineId" json:"machine_id,omitempty"`
 | 
			
		||||
	LauncherType                      *uint32           `protobuf:"varint,31,opt,name=launcher_type,json=launcherType,def=0" json:"launcher_type,omitempty"`
 | 
			
		||||
	UiMode                            *uint32           `protobuf:"varint,32,opt,name=ui_mode,json=uiMode,def=0" json:"ui_mode,omitempty"`
 | 
			
		||||
	ChatMode                          *uint32           `protobuf:"varint,33,opt,name=chat_mode,json=chatMode,def=0" json:"chat_mode,omitempty"`
 | 
			
		||||
	Steam2AuthTicket                  []byte            `protobuf:"bytes,41,opt,name=steam2_auth_ticket,json=steam2AuthTicket" json:"steam2_auth_ticket,omitempty"`
 | 
			
		||||
	EmailAddress                      *string           `protobuf:"bytes,42,opt,name=email_address,json=emailAddress" json:"email_address,omitempty"`
 | 
			
		||||
	Rtime32AccountCreation            *uint32           `protobuf:"fixed32,43,opt,name=rtime32_account_creation,json=rtime32AccountCreation" json:"rtime32_account_creation,omitempty"`
 | 
			
		||||
	AccountName                       *string           `protobuf:"bytes,50,opt,name=account_name,json=accountName" json:"account_name,omitempty"`
 | 
			
		||||
	Password                          *string           `protobuf:"bytes,51,opt,name=password" json:"password,omitempty"`
 | 
			
		||||
	GameServerToken                   *string           `protobuf:"bytes,52,opt,name=game_server_token,json=gameServerToken" json:"game_server_token,omitempty"`
 | 
			
		||||
	LoginKey                          *string           `protobuf:"bytes,60,opt,name=login_key,json=loginKey" json:"login_key,omitempty"`
 | 
			
		||||
	WasConvertedDeprecatedMsg         *bool             `protobuf:"varint,70,opt,name=was_converted_deprecated_msg,json=wasConvertedDeprecatedMsg,def=0" json:"was_converted_deprecated_msg,omitempty"`
 | 
			
		||||
	AnonUserTargetAccountName         *string           `protobuf:"bytes,80,opt,name=anon_user_target_account_name,json=anonUserTargetAccountName" json:"anon_user_target_account_name,omitempty"`
 | 
			
		||||
	ResolvedUserSteamId               *uint64           `protobuf:"fixed64,81,opt,name=resolved_user_steam_id,json=resolvedUserSteamId" json:"resolved_user_steam_id,omitempty"`
 | 
			
		||||
	EresultSentryfile                 *int32            `protobuf:"varint,82,opt,name=eresult_sentryfile,json=eresultSentryfile" json:"eresult_sentryfile,omitempty"`
 | 
			
		||||
	ShaSentryfile                     []byte            `protobuf:"bytes,83,opt,name=sha_sentryfile,json=shaSentryfile" json:"sha_sentryfile,omitempty"`
 | 
			
		||||
	AuthCode                          *string           `protobuf:"bytes,84,opt,name=auth_code,json=authCode" json:"auth_code,omitempty"`
 | 
			
		||||
	OtpType                           *int32            `protobuf:"varint,85,opt,name=otp_type,json=otpType" json:"otp_type,omitempty"`
 | 
			
		||||
	OtpValue                          *uint32           `protobuf:"varint,86,opt,name=otp_value,json=otpValue" json:"otp_value,omitempty"`
 | 
			
		||||
	OtpIdentifier                     *string           `protobuf:"bytes,87,opt,name=otp_identifier,json=otpIdentifier" json:"otp_identifier,omitempty"`
 | 
			
		||||
	Steam2TicketRequest               *bool             `protobuf:"varint,88,opt,name=steam2_ticket_request,json=steam2TicketRequest" json:"steam2_ticket_request,omitempty"`
 | 
			
		||||
	SonyPsnTicket                     []byte            `protobuf:"bytes,90,opt,name=sony_psn_ticket,json=sonyPsnTicket" json:"sony_psn_ticket,omitempty"`
 | 
			
		||||
	SonyPsnServiceId                  *string           `protobuf:"bytes,91,opt,name=sony_psn_service_id,json=sonyPsnServiceId" json:"sony_psn_service_id,omitempty"`
 | 
			
		||||
	CreateNewPsnLinkedAccountIfNeeded *bool             `protobuf:"varint,92,opt,name=create_new_psn_linked_account_if_needed,json=createNewPsnLinkedAccountIfNeeded,def=0" json:"create_new_psn_linked_account_if_needed,omitempty"`
 | 
			
		||||
	SonyPsnName                       *string           `protobuf:"bytes,93,opt,name=sony_psn_name,json=sonyPsnName" json:"sony_psn_name,omitempty"`
 | 
			
		||||
	GameServerAppId                   *int32            `protobuf:"varint,94,opt,name=game_server_app_id,json=gameServerAppId" json:"game_server_app_id,omitempty"`
 | 
			
		||||
	SteamguardDontRememberComputer    *bool             `protobuf:"varint,95,opt,name=steamguard_dont_remember_computer,json=steamguardDontRememberComputer" json:"steamguard_dont_remember_computer,omitempty"`
 | 
			
		||||
	MachineName                       *string           `protobuf:"bytes,96,opt,name=machine_name,json=machineName" json:"machine_name,omitempty"`
 | 
			
		||||
	MachineNameUserchosen             *string           `protobuf:"bytes,97,opt,name=machine_name_userchosen,json=machineNameUserchosen" json:"machine_name_userchosen,omitempty"`
 | 
			
		||||
	CountryOverride                   *string           `protobuf:"bytes,98,opt,name=country_override,json=countryOverride" json:"country_override,omitempty"`
 | 
			
		||||
	IsSteamBox                        *bool             `protobuf:"varint,99,opt,name=is_steam_box,json=isSteamBox" json:"is_steam_box,omitempty"`
 | 
			
		||||
	ClientInstanceId                  *uint64           `protobuf:"varint,100,opt,name=client_instance_id,json=clientInstanceId" json:"client_instance_id,omitempty"`
 | 
			
		||||
	TwoFactorCode                     *string           `protobuf:"bytes,101,opt,name=two_factor_code,json=twoFactorCode" json:"two_factor_code,omitempty"`
 | 
			
		||||
	SupportsRateLimitResponse         *bool             `protobuf:"varint,102,opt,name=supports_rate_limit_response,json=supportsRateLimitResponse" json:"supports_rate_limit_response,omitempty"`
 | 
			
		||||
	WebLogonNonce                     *string           `protobuf:"bytes,103,opt,name=web_logon_nonce,json=webLogonNonce" json:"web_logon_nonce,omitempty"`
 | 
			
		||||
	PriorityReason                    *int32            `protobuf:"varint,104,opt,name=priority_reason,json=priorityReason" json:"priority_reason,omitempty"`
 | 
			
		||||
	EmbeddedClientSecret              *CMsgClientSecret `protobuf:"bytes,105,opt,name=embedded_client_secret,json=embeddedClientSecret" json:"embedded_client_secret,omitempty"`
 | 
			
		||||
	DisablePartnerAutogrants          *bool             `protobuf:"varint,106,opt,name=disable_partner_autogrants,json=disablePartnerAutogrants" json:"disable_partner_autogrants,omitempty"`
 | 
			
		||||
	XXX_NoUnkeyedLiteral              struct{}          `json:"-"`
 | 
			
		||||
	XXX_unrecognized                  []byte            `json:"-"`
 | 
			
		||||
	XXX_sizecache                     int32             `json:"-"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *CMsgClientLogon) Reset()         { *m = CMsgClientLogon{} }
 | 
			
		||||
func (m *CMsgClientLogon) String() string { return proto.CompactTextString(m) }
 | 
			
		||||
func (*CMsgClientLogon) ProtoMessage()    {}
 | 
			
		||||
func (*CMsgClientLogon) Descriptor() ([]byte, []int) {
 | 
			
		||||
	return fileDescriptor_c98cb07f62c057af, []int{3}
 | 
			
		||||
	return fileDescriptor_c98cb07f62c057af, []int{4}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *CMsgClientLogon) XXX_Unmarshal(b []byte) error {
 | 
			
		||||
@@ -231,9 +306,9 @@ func (m *CMsgClientLogon) GetProtocolVersion() uint32 {
 | 
			
		||||
	return 0
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *CMsgClientLogon) GetObfustucatedPrivateIp() uint32 {
 | 
			
		||||
	if m != nil && m.ObfustucatedPrivateIp != nil {
 | 
			
		||||
		return *m.ObfustucatedPrivateIp
 | 
			
		||||
func (m *CMsgClientLogon) GetDeprecatedObfustucatedPrivateIp() uint32 {
 | 
			
		||||
	if m != nil && m.DeprecatedObfustucatedPrivateIp != nil {
 | 
			
		||||
		return *m.DeprecatedObfustucatedPrivateIp
 | 
			
		||||
	}
 | 
			
		||||
	return 0
 | 
			
		||||
}
 | 
			
		||||
@@ -287,16 +362,23 @@ func (m *CMsgClientLogon) GetWineVersion() string {
 | 
			
		||||
	return ""
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *CMsgClientLogon) GetPingMsFromCellSearch() uint32 {
 | 
			
		||||
	if m != nil && m.PingMsFromCellSearch != nil {
 | 
			
		||||
		return *m.PingMsFromCellSearch
 | 
			
		||||
func (m *CMsgClientLogon) GetDeprecated_10() uint32 {
 | 
			
		||||
	if m != nil && m.Deprecated_10 != nil {
 | 
			
		||||
		return *m.Deprecated_10
 | 
			
		||||
	}
 | 
			
		||||
	return 0
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *CMsgClientLogon) GetPublicIp() uint32 {
 | 
			
		||||
	if m != nil && m.PublicIp != nil {
 | 
			
		||||
		return *m.PublicIp
 | 
			
		||||
func (m *CMsgClientLogon) GetObfuscatedPrivateIp() *CMsgIPAddress {
 | 
			
		||||
	if m != nil {
 | 
			
		||||
		return m.ObfuscatedPrivateIp
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *CMsgClientLogon) GetDeprecatedPublicIp() uint32 {
 | 
			
		||||
	if m != nil && m.DeprecatedPublicIp != nil {
 | 
			
		||||
		return *m.DeprecatedPublicIp
 | 
			
		||||
	}
 | 
			
		||||
	return 0
 | 
			
		||||
}
 | 
			
		||||
@@ -315,6 +397,13 @@ func (m *CMsgClientLogon) GetClientSuppliedSteamId() uint64 {
 | 
			
		||||
	return 0
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *CMsgClientLogon) GetPublicIp() *CMsgIPAddress {
 | 
			
		||||
	if m != nil {
 | 
			
		||||
		return m.PublicIp
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *CMsgClientLogon) GetMachineId() []byte {
 | 
			
		||||
	if m != nil {
 | 
			
		||||
		return m.MachineId
 | 
			
		||||
@@ -567,40 +656,55 @@ func (m *CMsgClientLogon) GetPriorityReason() int32 {
 | 
			
		||||
	return 0
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *CMsgClientLogon) GetEmbeddedClientSecret() *CMsgClientSecret {
 | 
			
		||||
	if m != nil {
 | 
			
		||||
		return m.EmbeddedClientSecret
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *CMsgClientLogon) GetDisablePartnerAutogrants() bool {
 | 
			
		||||
	if m != nil && m.DisablePartnerAutogrants != nil {
 | 
			
		||||
		return *m.DisablePartnerAutogrants
 | 
			
		||||
	}
 | 
			
		||||
	return false
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type CMsgClientLogonResponse struct {
 | 
			
		||||
	Eresult                     *int32   `protobuf:"varint,1,opt,name=eresult,def=2" json:"eresult,omitempty"`
 | 
			
		||||
	OutOfGameHeartbeatSeconds   *int32   `protobuf:"varint,2,opt,name=out_of_game_heartbeat_seconds" json:"out_of_game_heartbeat_seconds,omitempty"`
 | 
			
		||||
	InGameHeartbeatSeconds      *int32   `protobuf:"varint,3,opt,name=in_game_heartbeat_seconds" json:"in_game_heartbeat_seconds,omitempty"`
 | 
			
		||||
	PublicIp                    *uint32  `protobuf:"varint,4,opt,name=public_ip" json:"public_ip,omitempty"`
 | 
			
		||||
	Rtime32ServerTime           *uint32  `protobuf:"fixed32,5,opt,name=rtime32_server_time" json:"rtime32_server_time,omitempty"`
 | 
			
		||||
	AccountFlags                *uint32  `protobuf:"varint,6,opt,name=account_flags" json:"account_flags,omitempty"`
 | 
			
		||||
	CellId                      *uint32  `protobuf:"varint,7,opt,name=cell_id" json:"cell_id,omitempty"`
 | 
			
		||||
	EmailDomain                 *string  `protobuf:"bytes,8,opt,name=email_domain" json:"email_domain,omitempty"`
 | 
			
		||||
	Steam2Ticket                []byte   `protobuf:"bytes,9,opt,name=steam2_ticket" json:"steam2_ticket,omitempty"`
 | 
			
		||||
	EresultExtended             *int32   `protobuf:"varint,10,opt,name=eresult_extended" json:"eresult_extended,omitempty"`
 | 
			
		||||
	WebapiAuthenticateUserNonce *string  `protobuf:"bytes,11,opt,name=webapi_authenticate_user_nonce" json:"webapi_authenticate_user_nonce,omitempty"`
 | 
			
		||||
	CellIdPingThreshold         *uint32  `protobuf:"varint,12,opt,name=cell_id_ping_threshold" json:"cell_id_ping_threshold,omitempty"`
 | 
			
		||||
	UsePics                     *bool    `protobuf:"varint,13,opt,name=use_pics" json:"use_pics,omitempty"`
 | 
			
		||||
	VanityUrl                   *string  `protobuf:"bytes,14,opt,name=vanity_url" json:"vanity_url,omitempty"`
 | 
			
		||||
	ClientSuppliedSteamid       *uint64  `protobuf:"fixed64,20,opt,name=client_supplied_steamid" json:"client_supplied_steamid,omitempty"`
 | 
			
		||||
	IpCountryCode               *string  `protobuf:"bytes,21,opt,name=ip_country_code" json:"ip_country_code,omitempty"`
 | 
			
		||||
	ParentalSettings            []byte   `protobuf:"bytes,22,opt,name=parental_settings" json:"parental_settings,omitempty"`
 | 
			
		||||
	ParentalSettingSignature    []byte   `protobuf:"bytes,23,opt,name=parental_setting_signature" json:"parental_setting_signature,omitempty"`
 | 
			
		||||
	CountLoginfailuresToMigrate *int32   `protobuf:"varint,24,opt,name=count_loginfailures_to_migrate" json:"count_loginfailures_to_migrate,omitempty"`
 | 
			
		||||
	CountDisconnectsToMigrate   *int32   `protobuf:"varint,25,opt,name=count_disconnects_to_migrate" json:"count_disconnects_to_migrate,omitempty"`
 | 
			
		||||
	OgsDataReportTimeWindow     *int32   `protobuf:"varint,26,opt,name=ogs_data_report_time_window" json:"ogs_data_report_time_window,omitempty"`
 | 
			
		||||
	ClientInstanceId            *uint64  `protobuf:"varint,27,opt,name=client_instance_id" json:"client_instance_id,omitempty"`
 | 
			
		||||
	ForceClientUpdateCheck      *bool    `protobuf:"varint,28,opt,name=force_client_update_check" json:"force_client_update_check,omitempty"`
 | 
			
		||||
	XXX_NoUnkeyedLiteral        struct{} `json:"-"`
 | 
			
		||||
	XXX_unrecognized            []byte   `json:"-"`
 | 
			
		||||
	XXX_sizecache               int32    `json:"-"`
 | 
			
		||||
	Eresult                     *int32         `protobuf:"varint,1,opt,name=eresult,def=2" json:"eresult,omitempty"`
 | 
			
		||||
	OutOfGameHeartbeatSeconds   *int32         `protobuf:"varint,2,opt,name=out_of_game_heartbeat_seconds,json=outOfGameHeartbeatSeconds" json:"out_of_game_heartbeat_seconds,omitempty"`
 | 
			
		||||
	InGameHeartbeatSeconds      *int32         `protobuf:"varint,3,opt,name=in_game_heartbeat_seconds,json=inGameHeartbeatSeconds" json:"in_game_heartbeat_seconds,omitempty"`
 | 
			
		||||
	DeprecatedPublicIp          *uint32        `protobuf:"varint,4,opt,name=deprecated_public_ip,json=deprecatedPublicIp" json:"deprecated_public_ip,omitempty"`
 | 
			
		||||
	Rtime32ServerTime           *uint32        `protobuf:"fixed32,5,opt,name=rtime32_server_time,json=rtime32ServerTime" json:"rtime32_server_time,omitempty"`
 | 
			
		||||
	AccountFlags                *uint32        `protobuf:"varint,6,opt,name=account_flags,json=accountFlags" json:"account_flags,omitempty"`
 | 
			
		||||
	CellId                      *uint32        `protobuf:"varint,7,opt,name=cell_id,json=cellId" json:"cell_id,omitempty"`
 | 
			
		||||
	EmailDomain                 *string        `protobuf:"bytes,8,opt,name=email_domain,json=emailDomain" json:"email_domain,omitempty"`
 | 
			
		||||
	Steam2Ticket                []byte         `protobuf:"bytes,9,opt,name=steam2_ticket,json=steam2Ticket" json:"steam2_ticket,omitempty"`
 | 
			
		||||
	EresultExtended             *int32         `protobuf:"varint,10,opt,name=eresult_extended,json=eresultExtended" json:"eresult_extended,omitempty"`
 | 
			
		||||
	WebapiAuthenticateUserNonce *string        `protobuf:"bytes,11,opt,name=webapi_authenticate_user_nonce,json=webapiAuthenticateUserNonce" json:"webapi_authenticate_user_nonce,omitempty"`
 | 
			
		||||
	CellIdPingThreshold         *uint32        `protobuf:"varint,12,opt,name=cell_id_ping_threshold,json=cellIdPingThreshold" json:"cell_id_ping_threshold,omitempty"`
 | 
			
		||||
	DeprecatedUsePics           *bool          `protobuf:"varint,13,opt,name=deprecated_use_pics,json=deprecatedUsePics" json:"deprecated_use_pics,omitempty"`
 | 
			
		||||
	VanityUrl                   *string        `protobuf:"bytes,14,opt,name=vanity_url,json=vanityUrl" json:"vanity_url,omitempty"`
 | 
			
		||||
	PublicIp                    *CMsgIPAddress `protobuf:"bytes,15,opt,name=public_ip,json=publicIp" json:"public_ip,omitempty"`
 | 
			
		||||
	ClientSuppliedSteamid       *uint64        `protobuf:"fixed64,20,opt,name=client_supplied_steamid,json=clientSuppliedSteamid" json:"client_supplied_steamid,omitempty"`
 | 
			
		||||
	IpCountryCode               *string        `protobuf:"bytes,21,opt,name=ip_country_code,json=ipCountryCode" json:"ip_country_code,omitempty"`
 | 
			
		||||
	ParentalSettings            []byte         `protobuf:"bytes,22,opt,name=parental_settings,json=parentalSettings" json:"parental_settings,omitempty"`
 | 
			
		||||
	ParentalSettingSignature    []byte         `protobuf:"bytes,23,opt,name=parental_setting_signature,json=parentalSettingSignature" json:"parental_setting_signature,omitempty"`
 | 
			
		||||
	CountLoginfailuresToMigrate *int32         `protobuf:"varint,24,opt,name=count_loginfailures_to_migrate,json=countLoginfailuresToMigrate" json:"count_loginfailures_to_migrate,omitempty"`
 | 
			
		||||
	CountDisconnectsToMigrate   *int32         `protobuf:"varint,25,opt,name=count_disconnects_to_migrate,json=countDisconnectsToMigrate" json:"count_disconnects_to_migrate,omitempty"`
 | 
			
		||||
	OgsDataReportTimeWindow     *int32         `protobuf:"varint,26,opt,name=ogs_data_report_time_window,json=ogsDataReportTimeWindow" json:"ogs_data_report_time_window,omitempty"`
 | 
			
		||||
	ClientInstanceId            *uint64        `protobuf:"varint,27,opt,name=client_instance_id,json=clientInstanceId" json:"client_instance_id,omitempty"`
 | 
			
		||||
	ForceClientUpdateCheck      *bool          `protobuf:"varint,28,opt,name=force_client_update_check,json=forceClientUpdateCheck" json:"force_client_update_check,omitempty"`
 | 
			
		||||
	XXX_NoUnkeyedLiteral        struct{}       `json:"-"`
 | 
			
		||||
	XXX_unrecognized            []byte         `json:"-"`
 | 
			
		||||
	XXX_sizecache               int32          `json:"-"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *CMsgClientLogonResponse) Reset()         { *m = CMsgClientLogonResponse{} }
 | 
			
		||||
func (m *CMsgClientLogonResponse) String() string { return proto.CompactTextString(m) }
 | 
			
		||||
func (*CMsgClientLogonResponse) ProtoMessage()    {}
 | 
			
		||||
func (*CMsgClientLogonResponse) Descriptor() ([]byte, []int) {
 | 
			
		||||
	return fileDescriptor_c98cb07f62c057af, []int{4}
 | 
			
		||||
	return fileDescriptor_c98cb07f62c057af, []int{5}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *CMsgClientLogonResponse) XXX_Unmarshal(b []byte) error {
 | 
			
		||||
@@ -644,9 +748,9 @@ func (m *CMsgClientLogonResponse) GetInGameHeartbeatSeconds() int32 {
 | 
			
		||||
	return 0
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *CMsgClientLogonResponse) GetPublicIp() uint32 {
 | 
			
		||||
	if m != nil && m.PublicIp != nil {
 | 
			
		||||
		return *m.PublicIp
 | 
			
		||||
func (m *CMsgClientLogonResponse) GetDeprecatedPublicIp() uint32 {
 | 
			
		||||
	if m != nil && m.DeprecatedPublicIp != nil {
 | 
			
		||||
		return *m.DeprecatedPublicIp
 | 
			
		||||
	}
 | 
			
		||||
	return 0
 | 
			
		||||
}
 | 
			
		||||
@@ -707,9 +811,9 @@ func (m *CMsgClientLogonResponse) GetCellIdPingThreshold() uint32 {
 | 
			
		||||
	return 0
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *CMsgClientLogonResponse) GetUsePics() bool {
 | 
			
		||||
	if m != nil && m.UsePics != nil {
 | 
			
		||||
		return *m.UsePics
 | 
			
		||||
func (m *CMsgClientLogonResponse) GetDeprecatedUsePics() bool {
 | 
			
		||||
	if m != nil && m.DeprecatedUsePics != nil {
 | 
			
		||||
		return *m.DeprecatedUsePics
 | 
			
		||||
	}
 | 
			
		||||
	return false
 | 
			
		||||
}
 | 
			
		||||
@@ -721,6 +825,13 @@ func (m *CMsgClientLogonResponse) GetVanityUrl() string {
 | 
			
		||||
	return ""
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *CMsgClientLogonResponse) GetPublicIp() *CMsgIPAddress {
 | 
			
		||||
	if m != nil {
 | 
			
		||||
		return m.PublicIp
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *CMsgClientLogonResponse) GetClientSuppliedSteamid() uint64 {
 | 
			
		||||
	if m != nil && m.ClientSuppliedSteamid != nil {
 | 
			
		||||
		return *m.ClientSuppliedSteamid
 | 
			
		||||
@@ -785,7 +896,7 @@ func (m *CMsgClientLogonResponse) GetForceClientUpdateCheck() bool {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type CMsgClientRequestWebAPIAuthenticateUserNonce struct {
 | 
			
		||||
	TokenType            *int32   `protobuf:"varint,1,opt,name=token_type,def=-1" json:"token_type,omitempty"`
 | 
			
		||||
	TokenType            *int32   `protobuf:"varint,1,opt,name=token_type,json=tokenType,def=-1" json:"token_type,omitempty"`
 | 
			
		||||
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
 | 
			
		||||
	XXX_unrecognized     []byte   `json:"-"`
 | 
			
		||||
	XXX_sizecache        int32    `json:"-"`
 | 
			
		||||
@@ -799,7 +910,7 @@ func (m *CMsgClientRequestWebAPIAuthenticateUserNonce) String() string {
 | 
			
		||||
}
 | 
			
		||||
func (*CMsgClientRequestWebAPIAuthenticateUserNonce) ProtoMessage() {}
 | 
			
		||||
func (*CMsgClientRequestWebAPIAuthenticateUserNonce) Descriptor() ([]byte, []int) {
 | 
			
		||||
	return fileDescriptor_c98cb07f62c057af, []int{5}
 | 
			
		||||
	return fileDescriptor_c98cb07f62c057af, []int{6}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *CMsgClientRequestWebAPIAuthenticateUserNonce) XXX_Unmarshal(b []byte) error {
 | 
			
		||||
@@ -831,8 +942,8 @@ func (m *CMsgClientRequestWebAPIAuthenticateUserNonce) GetTokenType() int32 {
 | 
			
		||||
 | 
			
		||||
type CMsgClientRequestWebAPIAuthenticateUserNonceResponse struct {
 | 
			
		||||
	Eresult                     *int32   `protobuf:"varint,1,opt,name=eresult,def=2" json:"eresult,omitempty"`
 | 
			
		||||
	WebapiAuthenticateUserNonce *string  `protobuf:"bytes,11,opt,name=webapi_authenticate_user_nonce" json:"webapi_authenticate_user_nonce,omitempty"`
 | 
			
		||||
	TokenType                   *int32   `protobuf:"varint,3,opt,name=token_type,def=-1" json:"token_type,omitempty"`
 | 
			
		||||
	WebapiAuthenticateUserNonce *string  `protobuf:"bytes,11,opt,name=webapi_authenticate_user_nonce,json=webapiAuthenticateUserNonce" json:"webapi_authenticate_user_nonce,omitempty"`
 | 
			
		||||
	TokenType                   *int32   `protobuf:"varint,3,opt,name=token_type,json=tokenType,def=-1" json:"token_type,omitempty"`
 | 
			
		||||
	XXX_NoUnkeyedLiteral        struct{} `json:"-"`
 | 
			
		||||
	XXX_unrecognized            []byte   `json:"-"`
 | 
			
		||||
	XXX_sizecache               int32    `json:"-"`
 | 
			
		||||
@@ -846,7 +957,7 @@ func (m *CMsgClientRequestWebAPIAuthenticateUserNonceResponse) String() string {
 | 
			
		||||
}
 | 
			
		||||
func (*CMsgClientRequestWebAPIAuthenticateUserNonceResponse) ProtoMessage() {}
 | 
			
		||||
func (*CMsgClientRequestWebAPIAuthenticateUserNonceResponse) Descriptor() ([]byte, []int) {
 | 
			
		||||
	return fileDescriptor_c98cb07f62c057af, []int{6}
 | 
			
		||||
	return fileDescriptor_c98cb07f62c057af, []int{7}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *CMsgClientRequestWebAPIAuthenticateUserNonceResponse) XXX_Unmarshal(b []byte) error {
 | 
			
		||||
@@ -901,7 +1012,7 @@ func (m *CMsgClientLogOff) Reset()         { *m = CMsgClientLogOff{} }
 | 
			
		||||
func (m *CMsgClientLogOff) String() string { return proto.CompactTextString(m) }
 | 
			
		||||
func (*CMsgClientLogOff) ProtoMessage()    {}
 | 
			
		||||
func (*CMsgClientLogOff) Descriptor() ([]byte, []int) {
 | 
			
		||||
	return fileDescriptor_c98cb07f62c057af, []int{7}
 | 
			
		||||
	return fileDescriptor_c98cb07f62c057af, []int{8}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *CMsgClientLogOff) XXX_Unmarshal(b []byte) error {
 | 
			
		||||
@@ -933,7 +1044,7 @@ func (m *CMsgClientLoggedOff) Reset()         { *m = CMsgClientLoggedOff{} }
 | 
			
		||||
func (m *CMsgClientLoggedOff) String() string { return proto.CompactTextString(m) }
 | 
			
		||||
func (*CMsgClientLoggedOff) ProtoMessage()    {}
 | 
			
		||||
func (*CMsgClientLoggedOff) Descriptor() ([]byte, []int) {
 | 
			
		||||
	return fileDescriptor_c98cb07f62c057af, []int{8}
 | 
			
		||||
	return fileDescriptor_c98cb07f62c057af, []int{9}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *CMsgClientLoggedOff) XXX_Unmarshal(b []byte) error {
 | 
			
		||||
@@ -964,8 +1075,8 @@ func (m *CMsgClientLoggedOff) GetEresult() int32 {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type CMsgClientNewLoginKey struct {
 | 
			
		||||
	UniqueId             *uint32  `protobuf:"varint,1,opt,name=unique_id" json:"unique_id,omitempty"`
 | 
			
		||||
	LoginKey             *string  `protobuf:"bytes,2,opt,name=login_key" json:"login_key,omitempty"`
 | 
			
		||||
	UniqueId             *uint32  `protobuf:"varint,1,opt,name=unique_id,json=uniqueId" json:"unique_id,omitempty"`
 | 
			
		||||
	LoginKey             *string  `protobuf:"bytes,2,opt,name=login_key,json=loginKey" json:"login_key,omitempty"`
 | 
			
		||||
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
 | 
			
		||||
	XXX_unrecognized     []byte   `json:"-"`
 | 
			
		||||
	XXX_sizecache        int32    `json:"-"`
 | 
			
		||||
@@ -975,7 +1086,7 @@ func (m *CMsgClientNewLoginKey) Reset()         { *m = CMsgClientNewLoginKey{} }
 | 
			
		||||
func (m *CMsgClientNewLoginKey) String() string { return proto.CompactTextString(m) }
 | 
			
		||||
func (*CMsgClientNewLoginKey) ProtoMessage()    {}
 | 
			
		||||
func (*CMsgClientNewLoginKey) Descriptor() ([]byte, []int) {
 | 
			
		||||
	return fileDescriptor_c98cb07f62c057af, []int{9}
 | 
			
		||||
	return fileDescriptor_c98cb07f62c057af, []int{10}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *CMsgClientNewLoginKey) XXX_Unmarshal(b []byte) error {
 | 
			
		||||
@@ -1011,7 +1122,7 @@ func (m *CMsgClientNewLoginKey) GetLoginKey() string {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type CMsgClientNewLoginKeyAccepted struct {
 | 
			
		||||
	UniqueId             *uint32  `protobuf:"varint,1,opt,name=unique_id" json:"unique_id,omitempty"`
 | 
			
		||||
	UniqueId             *uint32  `protobuf:"varint,1,opt,name=unique_id,json=uniqueId" json:"unique_id,omitempty"`
 | 
			
		||||
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
 | 
			
		||||
	XXX_unrecognized     []byte   `json:"-"`
 | 
			
		||||
	XXX_sizecache        int32    `json:"-"`
 | 
			
		||||
@@ -1021,7 +1132,7 @@ func (m *CMsgClientNewLoginKeyAccepted) Reset()         { *m = CMsgClientNewLogi
 | 
			
		||||
func (m *CMsgClientNewLoginKeyAccepted) String() string { return proto.CompactTextString(m) }
 | 
			
		||||
func (*CMsgClientNewLoginKeyAccepted) ProtoMessage()    {}
 | 
			
		||||
func (*CMsgClientNewLoginKeyAccepted) Descriptor() ([]byte, []int) {
 | 
			
		||||
	return fileDescriptor_c98cb07f62c057af, []int{10}
 | 
			
		||||
	return fileDescriptor_c98cb07f62c057af, []int{11}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *CMsgClientNewLoginKeyAccepted) XXX_Unmarshal(b []byte) error {
 | 
			
		||||
@@ -1050,18 +1161,18 @@ func (m *CMsgClientNewLoginKeyAccepted) GetUniqueId() uint32 {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type CMsgClientAccountInfo struct {
 | 
			
		||||
	PersonaName                     *string  `protobuf:"bytes,1,opt,name=persona_name" json:"persona_name,omitempty"`
 | 
			
		||||
	IpCountry                       *string  `protobuf:"bytes,2,opt,name=ip_country" json:"ip_country,omitempty"`
 | 
			
		||||
	CountAuthedComputers            *int32   `protobuf:"varint,5,opt,name=count_authed_computers" json:"count_authed_computers,omitempty"`
 | 
			
		||||
	AccountFlags                    *uint32  `protobuf:"varint,7,opt,name=account_flags" json:"account_flags,omitempty"`
 | 
			
		||||
	FacebookId                      *uint64  `protobuf:"varint,8,opt,name=facebook_id" json:"facebook_id,omitempty"`
 | 
			
		||||
	FacebookName                    *string  `protobuf:"bytes,9,opt,name=facebook_name" json:"facebook_name,omitempty"`
 | 
			
		||||
	SteamguardNotifyNewmachines     *bool    `protobuf:"varint,14,opt,name=steamguard_notify_newmachines" json:"steamguard_notify_newmachines,omitempty"`
 | 
			
		||||
	SteamguardMachineNameUserChosen *string  `protobuf:"bytes,15,opt,name=steamguard_machine_name_user_chosen" json:"steamguard_machine_name_user_chosen,omitempty"`
 | 
			
		||||
	IsPhoneVerified                 *bool    `protobuf:"varint,16,opt,name=is_phone_verified" json:"is_phone_verified,omitempty"`
 | 
			
		||||
	TwoFactorState                  *uint32  `protobuf:"varint,17,opt,name=two_factor_state" json:"two_factor_state,omitempty"`
 | 
			
		||||
	IsPhoneIdentifying              *bool    `protobuf:"varint,18,opt,name=is_phone_identifying" json:"is_phone_identifying,omitempty"`
 | 
			
		||||
	IsPhoneNeedingReverify          *bool    `protobuf:"varint,19,opt,name=is_phone_needing_reverify" json:"is_phone_needing_reverify,omitempty"`
 | 
			
		||||
	PersonaName                     *string  `protobuf:"bytes,1,opt,name=persona_name,json=personaName" json:"persona_name,omitempty"`
 | 
			
		||||
	IpCountry                       *string  `protobuf:"bytes,2,opt,name=ip_country,json=ipCountry" json:"ip_country,omitempty"`
 | 
			
		||||
	CountAuthedComputers            *int32   `protobuf:"varint,5,opt,name=count_authed_computers,json=countAuthedComputers" json:"count_authed_computers,omitempty"`
 | 
			
		||||
	AccountFlags                    *uint32  `protobuf:"varint,7,opt,name=account_flags,json=accountFlags" json:"account_flags,omitempty"`
 | 
			
		||||
	FacebookId                      *uint64  `protobuf:"varint,8,opt,name=facebook_id,json=facebookId" json:"facebook_id,omitempty"`
 | 
			
		||||
	FacebookName                    *string  `protobuf:"bytes,9,opt,name=facebook_name,json=facebookName" json:"facebook_name,omitempty"`
 | 
			
		||||
	SteamguardNotifyNewmachines     *bool    `protobuf:"varint,14,opt,name=steamguard_notify_newmachines,json=steamguardNotifyNewmachines" json:"steamguard_notify_newmachines,omitempty"`
 | 
			
		||||
	SteamguardMachineNameUserChosen *string  `protobuf:"bytes,15,opt,name=steamguard_machine_name_user_chosen,json=steamguardMachineNameUserChosen" json:"steamguard_machine_name_user_chosen,omitempty"`
 | 
			
		||||
	IsPhoneVerified                 *bool    `protobuf:"varint,16,opt,name=is_phone_verified,json=isPhoneVerified" json:"is_phone_verified,omitempty"`
 | 
			
		||||
	TwoFactorState                  *uint32  `protobuf:"varint,17,opt,name=two_factor_state,json=twoFactorState" json:"two_factor_state,omitempty"`
 | 
			
		||||
	IsPhoneIdentifying              *bool    `protobuf:"varint,18,opt,name=is_phone_identifying,json=isPhoneIdentifying" json:"is_phone_identifying,omitempty"`
 | 
			
		||||
	IsPhoneNeedingReverify          *bool    `protobuf:"varint,19,opt,name=is_phone_needing_reverify,json=isPhoneNeedingReverify" json:"is_phone_needing_reverify,omitempty"`
 | 
			
		||||
	XXX_NoUnkeyedLiteral            struct{} `json:"-"`
 | 
			
		||||
	XXX_unrecognized                []byte   `json:"-"`
 | 
			
		||||
	XXX_sizecache                   int32    `json:"-"`
 | 
			
		||||
@@ -1071,7 +1182,7 @@ func (m *CMsgClientAccountInfo) Reset()         { *m = CMsgClientAccountInfo{} }
 | 
			
		||||
func (m *CMsgClientAccountInfo) String() string { return proto.CompactTextString(m) }
 | 
			
		||||
func (*CMsgClientAccountInfo) ProtoMessage()    {}
 | 
			
		||||
func (*CMsgClientAccountInfo) Descriptor() ([]byte, []int) {
 | 
			
		||||
	return fileDescriptor_c98cb07f62c057af, []int{11}
 | 
			
		||||
	return fileDescriptor_c98cb07f62c057af, []int{12}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *CMsgClientAccountInfo) XXX_Unmarshal(b []byte) error {
 | 
			
		||||
@@ -1176,10 +1287,89 @@ func (m *CMsgClientAccountInfo) GetIsPhoneNeedingReverify() bool {
 | 
			
		||||
	return false
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type CMsgClientChallengeRequest struct {
 | 
			
		||||
	Steamid              *uint64  `protobuf:"fixed64,1,opt,name=steamid" json:"steamid,omitempty"`
 | 
			
		||||
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
 | 
			
		||||
	XXX_unrecognized     []byte   `json:"-"`
 | 
			
		||||
	XXX_sizecache        int32    `json:"-"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *CMsgClientChallengeRequest) Reset()         { *m = CMsgClientChallengeRequest{} }
 | 
			
		||||
func (m *CMsgClientChallengeRequest) String() string { return proto.CompactTextString(m) }
 | 
			
		||||
func (*CMsgClientChallengeRequest) ProtoMessage()    {}
 | 
			
		||||
func (*CMsgClientChallengeRequest) Descriptor() ([]byte, []int) {
 | 
			
		||||
	return fileDescriptor_c98cb07f62c057af, []int{13}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *CMsgClientChallengeRequest) XXX_Unmarshal(b []byte) error {
 | 
			
		||||
	return xxx_messageInfo_CMsgClientChallengeRequest.Unmarshal(m, b)
 | 
			
		||||
}
 | 
			
		||||
func (m *CMsgClientChallengeRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
 | 
			
		||||
	return xxx_messageInfo_CMsgClientChallengeRequest.Marshal(b, m, deterministic)
 | 
			
		||||
}
 | 
			
		||||
func (m *CMsgClientChallengeRequest) XXX_Merge(src proto.Message) {
 | 
			
		||||
	xxx_messageInfo_CMsgClientChallengeRequest.Merge(m, src)
 | 
			
		||||
}
 | 
			
		||||
func (m *CMsgClientChallengeRequest) XXX_Size() int {
 | 
			
		||||
	return xxx_messageInfo_CMsgClientChallengeRequest.Size(m)
 | 
			
		||||
}
 | 
			
		||||
func (m *CMsgClientChallengeRequest) XXX_DiscardUnknown() {
 | 
			
		||||
	xxx_messageInfo_CMsgClientChallengeRequest.DiscardUnknown(m)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var xxx_messageInfo_CMsgClientChallengeRequest proto.InternalMessageInfo
 | 
			
		||||
 | 
			
		||||
func (m *CMsgClientChallengeRequest) GetSteamid() uint64 {
 | 
			
		||||
	if m != nil && m.Steamid != nil {
 | 
			
		||||
		return *m.Steamid
 | 
			
		||||
	}
 | 
			
		||||
	return 0
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type CMsgClientChallengeResponse struct {
 | 
			
		||||
	Challenge            *uint64  `protobuf:"fixed64,1,opt,name=challenge" json:"challenge,omitempty"`
 | 
			
		||||
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
 | 
			
		||||
	XXX_unrecognized     []byte   `json:"-"`
 | 
			
		||||
	XXX_sizecache        int32    `json:"-"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *CMsgClientChallengeResponse) Reset()         { *m = CMsgClientChallengeResponse{} }
 | 
			
		||||
func (m *CMsgClientChallengeResponse) String() string { return proto.CompactTextString(m) }
 | 
			
		||||
func (*CMsgClientChallengeResponse) ProtoMessage()    {}
 | 
			
		||||
func (*CMsgClientChallengeResponse) Descriptor() ([]byte, []int) {
 | 
			
		||||
	return fileDescriptor_c98cb07f62c057af, []int{14}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *CMsgClientChallengeResponse) XXX_Unmarshal(b []byte) error {
 | 
			
		||||
	return xxx_messageInfo_CMsgClientChallengeResponse.Unmarshal(m, b)
 | 
			
		||||
}
 | 
			
		||||
func (m *CMsgClientChallengeResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
 | 
			
		||||
	return xxx_messageInfo_CMsgClientChallengeResponse.Marshal(b, m, deterministic)
 | 
			
		||||
}
 | 
			
		||||
func (m *CMsgClientChallengeResponse) XXX_Merge(src proto.Message) {
 | 
			
		||||
	xxx_messageInfo_CMsgClientChallengeResponse.Merge(m, src)
 | 
			
		||||
}
 | 
			
		||||
func (m *CMsgClientChallengeResponse) XXX_Size() int {
 | 
			
		||||
	return xxx_messageInfo_CMsgClientChallengeResponse.Size(m)
 | 
			
		||||
}
 | 
			
		||||
func (m *CMsgClientChallengeResponse) XXX_DiscardUnknown() {
 | 
			
		||||
	xxx_messageInfo_CMsgClientChallengeResponse.DiscardUnknown(m)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var xxx_messageInfo_CMsgClientChallengeResponse proto.InternalMessageInfo
 | 
			
		||||
 | 
			
		||||
func (m *CMsgClientChallengeResponse) GetChallenge() uint64 {
 | 
			
		||||
	if m != nil && m.Challenge != nil {
 | 
			
		||||
		return *m.Challenge
 | 
			
		||||
	}
 | 
			
		||||
	return 0
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func init() {
 | 
			
		||||
	proto.RegisterType((*CMsgClientHeartBeat)(nil), "CMsgClientHeartBeat")
 | 
			
		||||
	proto.RegisterType((*CMsgClientServerTimestampRequest)(nil), "CMsgClientServerTimestampRequest")
 | 
			
		||||
	proto.RegisterType((*CMsgClientServerTimestampResponse)(nil), "CMsgClientServerTimestampResponse")
 | 
			
		||||
	proto.RegisterType((*CMsgClientSecret)(nil), "CMsgClientSecret")
 | 
			
		||||
	proto.RegisterType((*CMsgClientLogon)(nil), "CMsgClientLogon")
 | 
			
		||||
	proto.RegisterType((*CMsgClientLogonResponse)(nil), "CMsgClientLogonResponse")
 | 
			
		||||
	proto.RegisterType((*CMsgClientRequestWebAPIAuthenticateUserNonce)(nil), "CMsgClientRequestWebAPIAuthenticateUserNonce")
 | 
			
		||||
@@ -1189,6 +1379,8 @@ func init() {
 | 
			
		||||
	proto.RegisterType((*CMsgClientNewLoginKey)(nil), "CMsgClientNewLoginKey")
 | 
			
		||||
	proto.RegisterType((*CMsgClientNewLoginKeyAccepted)(nil), "CMsgClientNewLoginKeyAccepted")
 | 
			
		||||
	proto.RegisterType((*CMsgClientAccountInfo)(nil), "CMsgClientAccountInfo")
 | 
			
		||||
	proto.RegisterType((*CMsgClientChallengeRequest)(nil), "CMsgClientChallengeRequest")
 | 
			
		||||
	proto.RegisterType((*CMsgClientChallengeResponse)(nil), "CMsgClientChallengeResponse")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func init() {
 | 
			
		||||
@@ -1196,99 +1388,151 @@ func init() {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var fileDescriptor_c98cb07f62c057af = []byte{
 | 
			
		||||
	// 1495 bytes of a gzipped FileDescriptorProto
 | 
			
		||||
	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x56, 0x5b, 0x73, 0x13, 0x47,
 | 
			
		||||
	0x16, 0x5e, 0x01, 0xc2, 0xd6, 0xc1, 0xc6, 0xf2, 0xd8, 0xb2, 0xdb, 0x57, 0x64, 0x71, 0x33, 0xcb,
 | 
			
		||||
	0xee, 0xd6, 0xae, 0xa1, 0xf6, 0x81, 0x4a, 0x1e, 0x0c, 0x29, 0x0a, 0x2a, 0x04, 0x08, 0x97, 0x90,
 | 
			
		||||
	0xca, 0xad, 0xd3, 0xea, 0x39, 0x33, 0xea, 0xf2, 0x4c, 0xf7, 0xd0, 0xdd, 0x23, 0xa1, 0xb7, 0x3c,
 | 
			
		||||
	0xe7, 0xcf, 0xe4, 0x7f, 0xe4, 0xc7, 0xe4, 0x37, 0xa4, 0xfa, 0x8c, 0x46, 0x92, 0xc1, 0x21, 0xc9,
 | 
			
		||||
	0xeb, 0xe9, 0xd3, 0xe7, 0xfa, 0x7d, 0x5f, 0x37, 0xdc, 0x70, 0x1e, 0x45, 0x9e, 0xa3, 0x73, 0x22,
 | 
			
		||||
	0x45, 0xc7, 0x65, 0xa6, 0x50, 0x7b, 0x87, 0x76, 0x88, 0x96, 0x67, 0x26, 0x55, 0xfa, 0x3f, 0x85,
 | 
			
		||||
	0x35, 0xde, 0x6c, 0xb3, 0xd3, 0x7e, 0x7d, 0xe1, 0xb0, 0x3a, 0xe9, 0x75, 0x60, 0xed, 0xc1, 0x17,
 | 
			
		||||
	0x2e, 0x7d, 0x40, 0x37, 0x1f, 0xa1, 0xb0, 0xfe, 0x3e, 0x0a, 0xdf, 0xfb, 0x0c, 0xba, 0x33, 0xf3,
 | 
			
		||||
	0x4b, 0x0a, 0xf8, 0x4a, 0xe5, 0xe8, 0xbc, 0xc8, 0x8b, 0x17, 0xf8, 0xb6, 0x44, 0xe7, 0xa3, 0x2e,
 | 
			
		||||
	0xb0, 0x2a, 0x21, 0xb7, 0x95, 0x85, 0xfb, 0xda, 0x85, 0x35, 0xba, 0x8d, 0xc3, 0x0b, 0xbd, 0x3e,
 | 
			
		||||
	0x1c, 0x7c, 0x24, 0x8a, 0x2b, 0x8c, 0x76, 0xf8, 0xe7, 0x61, 0xa2, 0x1d, 0x58, 0x9b, 0xf4, 0x34,
 | 
			
		||||
	0x3d, 0xe1, 0xb9, 0x63, 0xe7, 0x28, 0xc7, 0xaf, 0x00, 0x2b, 0xb3, 0x24, 0x4f, 0x4c, 0x6a, 0x74,
 | 
			
		||||
	0xc4, 0xa0, 0x4d, 0xdd, 0x49, 0x93, 0xf1, 0x21, 0x5a, 0xa7, 0x8c, 0xa6, 0x50, 0xcb, 0xd1, 0x15,
 | 
			
		||||
	0xd8, 0x34, 0xfd, 0xa4, 0x74, 0xbe, 0x94, 0xc2, 0x63, 0xcc, 0x0b, 0xab, 0x86, 0xc2, 0x23, 0x57,
 | 
			
		||||
	0x05, 0x85, 0x5b, 0x8e, 0x56, 0x60, 0x41, 0x62, 0x96, 0x71, 0x15, 0xb3, 0xf3, 0x64, 0xd8, 0x84,
 | 
			
		||||
	0x95, 0x4c, 0x38, 0xcf, 0x1d, 0xba, 0x10, 0x27, 0x1c, 0x5c, 0xa0, 0x83, 0x7d, 0xd8, 0x98, 0xd4,
 | 
			
		||||
	0x5d, 0x08, 0x79, 0x22, 0x52, 0x9c, 0xa6, 0x6a, 0xd6, 0x17, 0x27, 0xe7, 0x99, 0xd0, 0x69, 0x29,
 | 
			
		||||
	0x52, 0x64, 0x17, 0xbb, 0x8d, 0xc3, 0x56, 0xb4, 0x01, 0x97, 0x27, 0x07, 0xc6, 0x71, 0x3f, 0x2e,
 | 
			
		||||
	0x90, 0x2d, 0xd0, 0x85, 0x9b, 0xc0, 0xdc, 0xc0, 0x94, 0x59, 0xcc, 0x2d, 0xe6, 0x98, 0xf7, 0xd1,
 | 
			
		||||
	0xf2, 0x42, 0x38, 0x37, 0x32, 0x36, 0x66, 0x8b, 0xdd, 0xc6, 0xe1, 0xe2, 0xbd, 0x66, 0x22, 0x32,
 | 
			
		||||
	0x87, 0xd1, 0x3a, 0x2c, 0x8d, 0x94, 0x9e, 0xe5, 0x6b, 0x51, 0xd8, 0x2e, 0xb0, 0x42, 0xe9, 0x94,
 | 
			
		||||
	0xe7, 0x8e, 0x27, 0xd6, 0xe4, 0x9c, 0xda, 0x70, 0x28, 0xac, 0x1c, 0x30, 0xa0, 0x04, 0xab, 0xd0,
 | 
			
		||||
	0x2a, 0xca, 0x7e, 0xa6, 0x64, 0x68, 0x77, 0xbd, 0x36, 0xbd, 0x35, 0x8e, 0x67, 0x38, 0xc4, 0x8c,
 | 
			
		||||
	0x75, 0xc8, 0x34, 0xdb, 0x87, 0x2b, 0x8b, 0x22, 0x53, 0x18, 0x73, 0x42, 0x4f, 0xe8, 0x7c, 0xa3,
 | 
			
		||||
	0xdb, 0x38, 0xbc, 0x18, 0x45, 0x00, 0xb9, 0x90, 0x83, 0x50, 0x82, 0x8a, 0xd9, 0x7e, 0xb7, 0x71,
 | 
			
		||||
	0xb8, 0x14, 0x31, 0x58, 0xce, 0x44, 0xa9, 0xe5, 0x20, 0x6c, 0x29, 0xf4, 0x74, 0x25, 0x04, 0xbb,
 | 
			
		||||
	0xd7, 0xf8, 0x6f, 0x14, 0xc1, 0x42, 0xa9, 0x78, 0x6e, 0x62, 0x64, 0xdd, 0xda, 0xb6, 0x0e, 0x2d,
 | 
			
		||||
	0x39, 0x10, 0xbe, 0xb2, 0x1e, 0xd4, 0xd6, 0x6d, 0x88, 0x28, 0xd3, 0x11, 0x17, 0xa5, 0x1f, 0x70,
 | 
			
		||||
	0xaf, 0xe4, 0x09, 0x7a, 0x76, 0x8b, 0xe2, 0x77, 0x60, 0x19, 0x73, 0xa1, 0x32, 0x2e, 0xe2, 0xd8,
 | 
			
		||||
	0xa2, 0x73, 0xec, 0x9f, 0x75, 0xd3, 0x36, 0x80, 0xe2, 0xce, 0x11, 0x17, 0x52, 0x9a, 0x52, 0x7b,
 | 
			
		||||
	0x2e, 0x2d, 0x0a, 0x1f, 0xc6, 0x72, 0xbb, 0xdb, 0x38, 0x5c, 0x08, 0xc3, 0xaa, 0x4f, 0xb4, 0xc8,
 | 
			
		||||
	0x91, 0x1d, 0xd1, 0xbd, 0x36, 0x2c, 0x4e, 0x67, 0x7b, 0x87, 0x2c, 0x5b, 0xb0, 0x9a, 0x8a, 0x1c,
 | 
			
		||||
	0x79, 0x8d, 0x34, 0x73, 0x82, 0x9a, 0xdd, 0xa5, 0xa3, 0x55, 0x68, 0x11, 0x99, 0xf8, 0x09, 0x8e,
 | 
			
		||||
	0xd9, 0x27, 0x64, 0xba, 0x0d, 0xbb, 0x23, 0xe1, 0xb8, 0x34, 0x7a, 0x88, 0x36, 0x00, 0x29, 0xc6,
 | 
			
		||||
	0xc2, 0x62, 0x85, 0xa9, 0xdc, 0xa5, 0xec, 0xe1, 0xfc, 0xbe, 0xae, 0xc3, 0x9e, 0xd0, 0x46, 0xf3,
 | 
			
		||||
	0xd2, 0x85, 0xc0, 0xc2, 0xa6, 0xe8, 0xf9, 0xa9, 0x9a, 0x9e, 0x53, 0xcc, 0x7d, 0xd8, 0xb0, 0xe8,
 | 
			
		||||
	0x4c, 0x36, 0xc4, 0xb8, 0x72, 0x9d, 0x8e, 0xfd, 0x4b, 0x1a, 0xfb, 0x36, 0x44, 0x68, 0xd1, 0x95,
 | 
			
		||||
	0x59, 0x00, 0xa3, 0xf6, 0x76, 0x9c, 0xa8, 0x0c, 0xd9, 0x8b, 0x6e, 0xe3, 0xb0, 0x19, 0x30, 0xe5,
 | 
			
		||||
	0x06, 0x62, 0xde, 0xfe, 0x92, 0xc6, 0xb6, 0x0a, 0x2d, 0x9a, 0xa5, 0x0c, 0x83, 0x7e, 0x55, 0xb7,
 | 
			
		||||
	0x6e, 0x7c, 0x51, 0x2d, 0xe9, 0x35, 0x5d, 0x5e, 0x85, 0x56, 0xb0, 0x0c, 0x45, 0x56, 0x22, 0xfb,
 | 
			
		||||
	0x8a, 0x40, 0xb0, 0x01, 0x97, 0x83, 0x49, 0xc5, 0xa8, 0xbd, 0x4a, 0x14, 0x5a, 0xf6, 0x86, 0x2e,
 | 
			
		||||
	0xef, 0x41, 0x67, 0xb2, 0xa2, 0x6a, 0x3b, 0x35, 0x67, 0xd9, 0xd7, 0xa1, 0xe1, 0x80, 0x79, 0x67,
 | 
			
		||||
	0xf4, 0x98, 0x17, 0x4e, 0xd7, 0xeb, 0xfb, 0x86, 0xea, 0x08, 0x14, 0xae, 0x0f, 0xc2, 0x84, 0x95,
 | 
			
		||||
	0x24, 0xec, 0x7c, 0x4b, 0x41, 0xff, 0x0f, 0x37, 0x69, 0x69, 0xc8, 0x35, 0x8e, 0xc8, 0x25, 0x53,
 | 
			
		||||
	0xfa, 0x04, 0xe3, 0xe9, 0x90, 0x54, 0xc2, 0x35, 0x62, 0x8c, 0x31, 0xfb, 0x6e, 0x7e, 0xae, 0x1d,
 | 
			
		||||
	0x58, 0x9e, 0x06, 0xa5, 0x39, 0x7e, 0x4f, 0xe1, 0xb6, 0x21, 0x9a, 0xdf, 0xa4, 0x28, 0x42, 0x1f,
 | 
			
		||||
	0xec, 0x07, 0x6a, 0xf5, 0x16, 0x1c, 0x50, 0xfd, 0x69, 0x29, 0x6c, 0xcc, 0x63, 0x43, 0xaa, 0x33,
 | 
			
		||||
	0x21, 0x9b, 0x34, 0x79, 0x51, 0x7a, 0xb4, 0x8c, 0x53, 0x2f, 0xeb, 0xb0, 0x54, 0xa3, 0x9c, 0x82,
 | 
			
		||||
	0xff, 0x48, 0xc1, 0xaf, 0xc0, 0xe6, 0xbc, 0x95, 0x16, 0x25, 0x07, 0xc6, 0xa1, 0x66, 0x82, 0x1c,
 | 
			
		||||
	0x18, 0xb4, 0xa9, 0x68, 0x3b, 0xe6, 0x66, 0x88, 0xd6, 0xaa, 0x18, 0x59, 0x9f, 0x4e, 0xd6, 0x61,
 | 
			
		||||
	0x49, 0xb9, 0xc9, 0x52, 0xfb, 0xe6, 0x1d, 0x93, 0x94, 0x66, 0x1b, 0xa2, 0x09, 0xdd, 0x94, 0x76,
 | 
			
		||||
	0x5e, 0xe8, 0x6a, 0x30, 0x31, 0x09, 0xdf, 0x26, 0xac, 0xf8, 0x91, 0xe1, 0x89, 0x90, 0xde, 0xd8,
 | 
			
		||||
	0x6a, 0x87, 0x48, 0xa1, 0xae, 0xc1, 0x6e, 0x20, 0xa7, 0xb1, 0xde, 0x71, 0x1b, 0x06, 0x97, 0xa9,
 | 
			
		||||
	0x5c, 0x85, 0x56, 0x2a, 0x4d, 0x65, 0x49, 0xbd, 0x8d, 0x11, 0xf6, 0xc3, 0x43, 0x60, 0x34, 0xd7,
 | 
			
		||||
	0x46, 0x4b, 0x64, 0x29, 0x5d, 0xdf, 0x84, 0x95, 0xc2, 0x2a, 0x63, 0x95, 0x1f, 0x73, 0x8b, 0xc2,
 | 
			
		||||
	0x19, 0xcd, 0x06, 0x61, 0x3c, 0xbd, 0x5f, 0x9a, 0xb0, 0xf9, 0x9e, 0x98, 0x4e, 0x75, 0x3a, 0x82,
 | 
			
		||||
	0x85, 0x09, 0xfc, 0x48, 0x4b, 0x9b, 0xf7, 0x1a, 0x47, 0x01, 0xd9, 0xa6, 0xf4, 0xdc, 0x24, 0x9c,
 | 
			
		||||
	0x26, 0x3e, 0x08, 0xef, 0x47, 0x1f, 0x45, 0x00, 0xa8, 0x34, 0x3a, 0xae, 0x34, 0xba, 0x19, 0x1d,
 | 
			
		||||
	0xc0, 0x96, 0xd2, 0x7f, 0xe4, 0x72, 0xbe, 0xc6, 0xe0, 0x4c, 0x9b, 0x2a, 0x81, 0xdd, 0x81, 0xb5,
 | 
			
		||||
	0x9a, 0xdb, 0x73, 0xf2, 0x4f, 0xea, 0xba, 0x10, 0x76, 0x5f, 0xa3, 0x23, 0xc9, 0x44, 0xea, 0x48,
 | 
			
		||||
	0x5b, 0x4f, 0xc9, 0x77, 0x25, 0xaa, 0xeb, 0xb0, 0x54, 0xe9, 0x46, 0x6c, 0x72, 0xa1, 0x34, 0x09,
 | 
			
		||||
	0x69, 0x8b, 0x90, 0x33, 0x0f, 0x63, 0x92, 0xd0, 0x20, 0x62, 0xed, 0x9a, 0x61, 0xf8, 0xce, 0xa3,
 | 
			
		||||
	0x0e, 0x88, 0x03, 0x2a, 0xef, 0x06, 0xec, 0x8f, 0xb0, 0x2f, 0x0a, 0x45, 0xd2, 0x14, 0x48, 0x11,
 | 
			
		||||
	0xb8, 0x5e, 0xd1, 0xb4, 0x9a, 0xec, 0xa5, 0x9a, 0xc3, 0x93, 0xfc, 0x9c, 0xc4, 0xd8, 0x0f, 0x2c,
 | 
			
		||||
	0xba, 0x81, 0xc9, 0x62, 0xb6, 0x44, 0xe5, 0xb4, 0x61, 0xb1, 0x74, 0xc8, 0x0b, 0x25, 0x1d, 0x5b,
 | 
			
		||||
	0xa6, 0x25, 0x45, 0x00, 0x43, 0xa1, 0xc3, 0x26, 0x4a, 0x9b, 0xb1, 0xcb, 0x35, 0xc8, 0xce, 0x94,
 | 
			
		||||
	0x60, 0x15, 0x93, 0x6c, 0x5f, 0x0c, 0x0b, 0x54, 0x05, 0xaf, 0x71, 0x46, 0xc0, 0xe8, 0xd4, 0x2a,
 | 
			
		||||
	0x56, 0x08, 0x8b, 0xda, 0x8b, 0xa0, 0xfd, 0xde, 0x2b, 0x9d, 0x3a, 0x52, 0xed, 0xa5, 0xa8, 0x07,
 | 
			
		||||
	0xdb, 0xef, 0x1f, 0x71, 0xa7, 0x52, 0x2d, 0x7c, 0x69, 0x91, 0x6d, 0x92, 0xcf, 0x0d, 0xd8, 0xaf,
 | 
			
		||||
	0x66, 0x4a, 0x7a, 0x97, 0x08, 0x95, 0x95, 0x16, 0x1d, 0xf7, 0x86, 0xe7, 0x2a, 0x0d, 0x40, 0x63,
 | 
			
		||||
	0x8c, 0xc6, 0x71, 0x0d, 0x76, 0x2b, 0xbf, 0x58, 0x39, 0x69, 0xb4, 0x46, 0xe9, 0x4f, 0x79, 0x6d,
 | 
			
		||||
	0x91, 0xd7, 0x55, 0xd8, 0x31, 0xa9, 0xe3, 0xb1, 0xf0, 0x82, 0x5b, 0x0c, 0x68, 0xa5, 0x0d, 0xf2,
 | 
			
		||||
	0x91, 0xd2, 0xb1, 0x19, 0xb1, 0x6d, 0x72, 0x3a, 0x1b, 0xff, 0x3b, 0x84, 0xff, 0x03, 0xd8, 0x4a,
 | 
			
		||||
	0x8c, 0x95, 0x38, 0xf9, 0xd8, 0xf0, 0xb2, 0x88, 0xc3, 0xd4, 0xe5, 0x00, 0xe5, 0x09, 0xdb, 0x0d,
 | 
			
		||||
	0xe3, 0xeb, 0x3d, 0x84, 0x7f, 0xcd, 0x00, 0x3b, 0xf9, 0x99, 0xbc, 0xc1, 0xfe, 0xf1, 0xf3, 0xc7,
 | 
			
		||||
	0xc7, 0x73, 0x8b, 0x7a, 0xed, 0xd0, 0x3e, 0x0d, 0x6b, 0x8a, 0x36, 0x00, 0x48, 0xda, 0x2b, 0xfd,
 | 
			
		||||
	0xab, 0x80, 0x7c, 0xee, 0xdf, 0xff, 0xeb, 0xfd, 0xdc, 0x80, 0xbb, 0x7f, 0x27, 0xd0, 0x47, 0x69,
 | 
			
		||||
	0xf1, 0x57, 0xd1, 0x72, 0xba, 0x98, 0xf3, 0xd3, 0x62, 0x22, 0x68, 0x9f, 0x62, 0xe1, 0xb3, 0x24,
 | 
			
		||||
	0xe9, 0xdd, 0x9a, 0xff, 0xa8, 0x3d, 0x31, 0x69, 0x8a, 0xf1, 0xb3, 0x24, 0x39, 0x2b, 0x7d, 0xef,
 | 
			
		||||
	0x53, 0xe8, 0xcc, 0x5c, 0x9f, 0xe2, 0xe8, 0x49, 0x58, 0xe6, 0xe7, 0x38, 0x0e, 0x24, 0x2b, 0xb5,
 | 
			
		||||
	0x7a, 0x5b, 0xd2, 0x88, 0x1b, 0xf5, 0x07, 0x60, 0xf6, 0xb6, 0x05, 0xb6, 0xb6, 0x7a, 0x47, 0xb0,
 | 
			
		||||
	0x77, 0xe6, 0xf5, 0x63, 0x29, 0xb1, 0xf0, 0x18, 0x9f, 0x11, 0xa6, 0xf7, 0xdb, 0xb9, 0xf9, 0x9c,
 | 
			
		||||
	0xc7, 0x15, 0x33, 0x1f, 0xeb, 0xc4, 0x04, 0x02, 0x16, 0x68, 0x9d, 0xd1, 0xa2, 0x92, 0xd1, 0x06,
 | 
			
		||||
	0x75, 0x1e, 0x01, 0xcc, 0x00, 0x5c, 0xe5, 0x25, 0xee, 0x10, 0xa8, 0x68, 0x68, 0xf1, 0x54, 0x8f,
 | 
			
		||||
	0x1d, 0x51, 0xbe, 0xf9, 0x21, 0xe5, 0x2b, 0x86, 0xaf, 0xc1, 0xa5, 0x44, 0x48, 0xec, 0x1b, 0x73,
 | 
			
		||||
	0x12, 0xea, 0x59, 0x24, 0xe4, 0x74, 0x60, 0x79, 0x6a, 0xa4, 0xb4, 0xd5, 0x1f, 0xe9, 0x3a, 0xec,
 | 
			
		||||
	0xcd, 0xc9, 0xbf, 0x36, 0x5e, 0x25, 0xe3, 0xf0, 0xe8, 0x4c, 0x24, 0xdd, 0x11, 0xff, 0x16, 0xa3,
 | 
			
		||||
	0xdb, 0x70, 0x75, 0xce, 0xed, 0x03, 0xbd, 0xe7, 0x13, 0xc1, 0x5f, 0xa9, 0x29, 0xa7, 0x1c, 0x2f,
 | 
			
		||||
	0x06, 0xa6, 0xfa, 0x91, 0x85, 0xd7, 0x32, 0x66, 0x6d, 0x8a, 0xc3, 0xa0, 0x3d, 0xa7, 0xdf, 0xce,
 | 
			
		||||
	0x07, 0x6a, 0xac, 0x52, 0xd1, 0xbb, 0xb0, 0x3e, 0xbd, 0x34, 0x79, 0x64, 0xc7, 0x4a, 0xa7, 0x2c,
 | 
			
		||||
	0xa2, 0x7b, 0x41, 0x2f, 0xeb, 0xd3, 0xf0, 0xf0, 0x05, 0xaa, 0x5a, 0xa4, 0xe0, 0x63, 0xb6, 0x16,
 | 
			
		||||
	0x5c, 0xee, 0x37, 0x1f, 0x35, 0x7e, 0x6a, 0xfc, 0xe3, 0xf7, 0x00, 0x00, 0x00, 0xff, 0xff, 0xb8,
 | 
			
		||||
	0x55, 0x41, 0x55, 0x01, 0x0c, 0x00, 0x00,
 | 
			
		||||
	// 2325 bytes of a gzipped FileDescriptorProto
 | 
			
		||||
	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x58, 0x5b, 0x77, 0x1b, 0xb7,
 | 
			
		||||
	0xd5, 0xfd, 0x98, 0x58, 0x96, 0x08, 0x51, 0xb7, 0xd1, 0x0d, 0x92, 0x7c, 0x91, 0x98, 0xaf, 0x8e,
 | 
			
		||||
	0x12, 0x27, 0x5e, 0x8e, 0x9c, 0x95, 0x36, 0xa9, 0xd7, 0x4a, 0x65, 0xb9, 0x4e, 0xb8, 0xa2, 0x0b,
 | 
			
		||||
	0x33, 0x92, 0x9c, 0x5e, 0xd2, 0xa2, 0xe0, 0xcc, 0xe1, 0x10, 0xd5, 0x10, 0x18, 0x0f, 0x30, 0x62,
 | 
			
		||||
	0xf8, 0xd6, 0xc7, 0xbe, 0xf4, 0xa9, 0x7f, 0xa5, 0x6f, 0xfd, 0x11, 0xfd, 0x4b, 0x5d, 0x38, 0xc0,
 | 
			
		||||
	0x0c, 0x87, 0x8e, 0xec, 0x5e, 0x56, 0xdf, 0x34, 0xfb, 0x6c, 0x00, 0x07, 0x38, 0x1b, 0x07, 0x9b,
 | 
			
		||||
	0x22, 0x0f, 0xb4, 0x01, 0x3e, 0x1c, 0x82, 0xd6, 0x3c, 0x01, 0xcd, 0xa2, 0x54, 0x80, 0x34, 0x1a,
 | 
			
		||||
	0xf2, 0x6b, 0xc8, 0x59, 0xaa, 0x12, 0x21, 0x1f, 0x65, 0xb9, 0x32, 0x6a, 0x9b, 0x4e, 0xf3, 0x7a,
 | 
			
		||||
	0x5c, 0x83, 0x8b, 0xb4, 0xd7, 0xc9, 0xea, 0xd1, 0x89, 0x4e, 0x8e, 0x70, 0xe4, 0xd7, 0xc0, 0x73,
 | 
			
		||||
	0xf3, 0x0c, 0xb8, 0x69, 0x7f, 0x4f, 0x76, 0x27, 0xf0, 0x39, 0x4e, 0x78, 0x21, 0x86, 0xa0, 0x0d,
 | 
			
		||||
	0x1f, 0x66, 0x21, 0xbc, 0x2a, 0x40, 0x9b, 0xe0, 0x67, 0x84, 0xba, 0x05, 0x59, 0xee, 0x10, 0x66,
 | 
			
		||||
	0x4a, 0x0a, 0x6d, 0xec, 0x36, 0xf6, 0x6f, 0x85, 0x1b, 0x2e, 0xee, 0x07, 0x54, 0x13, 0xb4, 0xff,
 | 
			
		||||
	0xd2, 0x20, 0x7b, 0x6f, 0x99, 0x5e, 0x67, 0x4a, 0x6a, 0xf8, 0xef, 0xe7, 0x0f, 0x1e, 0x91, 0x55,
 | 
			
		||||
	0x7f, 0x08, 0xd5, 0x08, 0x36, 0xd4, 0xf4, 0x1d, 0x1c, 0xb4, 0xa2, 0xa7, 0xd7, 0x3b, 0xd1, 0xed,
 | 
			
		||||
	0x3f, 0x37, 0xc8, 0x72, 0x3d, 0x9f, 0x28, 0x07, 0x13, 0x50, 0x32, 0x7b, 0x0d, 0xb9, 0x16, 0x4a,
 | 
			
		||||
	0xe2, 0x6a, 0x0b, 0x61, 0xf9, 0x19, 0xac, 0x91, 0x19, 0x9e, 0x65, 0x22, 0xc6, 0x09, 0x17, 0x42,
 | 
			
		||||
	0xf7, 0x11, 0x6c, 0x93, 0xb9, 0x18, 0xae, 0x45, 0x04, 0x22, 0xa6, 0xef, 0x62, 0xa0, 0xfa, 0xb6,
 | 
			
		||||
	0x23, 0xa4, 0x92, 0x11, 0xd0, 0x5b, 0xbb, 0x8d, 0xfd, 0xdb, 0xa1, 0xfb, 0x08, 0x02, 0x72, 0x6b,
 | 
			
		||||
	0x30, 0xe4, 0x11, 0x9d, 0xd9, 0x6d, 0xec, 0xb7, 0x42, 0xfc, 0xbb, 0xfd, 0xd7, 0x55, 0xb2, 0x34,
 | 
			
		||||
	0x49, 0xe5, 0x58, 0x25, 0x4a, 0x06, 0x1f, 0x90, 0x65, 0x2c, 0x56, 0xa4, 0x52, 0x36, 0x9d, 0xd2,
 | 
			
		||||
	0x52, 0x89, 0xbf, 0xf4, 0xa9, 0x7d, 0x43, 0xda, 0x31, 0x64, 0x39, 0x44, 0xdc, 0x40, 0xcc, 0x54,
 | 
			
		||||
	0xaf, 0x5f, 0x68, 0x53, 0xb8, 0x8f, 0x2c, 0x17, 0xd7, 0xdc, 0x00, 0x13, 0x99, 0xcf, 0xfb, 0xfe,
 | 
			
		||||
	0x84, 0x79, 0x56, 0x23, 0x76, 0x1d, 0xaf, 0x93, 0x05, 0x9b, 0x64, 0x36, 0x82, 0x34, 0x65, 0xd5,
 | 
			
		||||
	0x86, 0x6e, 0xdb, 0xcf, 0x4e, 0x1c, 0x3c, 0x20, 0x4b, 0x29, 0xd7, 0x86, 0x69, 0xd0, 0x76, 0x55,
 | 
			
		||||
	0x4b, 0xb8, 0x85, 0x84, 0x05, 0x0b, 0x9f, 0x3b, 0xb4, 0x13, 0x07, 0x9f, 0x12, 0x5f, 0x21, 0x96,
 | 
			
		||||
	0xf1, 0xe8, 0x8a, 0x27, 0x50, 0xa5, 0x3f, 0x83, 0xf4, 0x35, 0x17, 0xed, 0xba, 0x60, 0xb9, 0x87,
 | 
			
		||||
	0xf7, 0xc9, 0x92, 0x1f, 0x95, 0x72, 0x99, 0x14, 0x3c, 0x01, 0x7a, 0x7b, 0xb7, 0xb1, 0xdf, 0x0c,
 | 
			
		||||
	0x17, 0x1d, 0x7c, 0xec, 0xd1, 0xe0, 0xff, 0x89, 0x47, 0x98, 0xd2, 0xcc, 0x8c, 0x33, 0xa0, 0xb3,
 | 
			
		||||
	0x38, 0x6d, 0xcb, 0xa1, 0x67, 0xfa, 0x62, 0x9c, 0x41, 0xf0, 0x25, 0xa1, 0x7a, 0xa0, 0x8a, 0x34,
 | 
			
		||||
	0x66, 0x39, 0x0c, 0x61, 0xd8, 0x83, 0x9c, 0x65, 0x5c, 0xeb, 0x91, 0xca, 0x63, 0x3a, 0xb7, 0xdb,
 | 
			
		||||
	0xd8, 0x9f, 0xfb, 0x62, 0xa6, 0xcf, 0x53, 0x0d, 0xe1, 0x86, 0xa3, 0x85, 0x9e, 0xd5, 0xf5, 0xa4,
 | 
			
		||||
	0x60, 0x8f, 0xb4, 0x46, 0x42, 0x4e, 0x72, 0x6f, 0x62, 0x32, 0xf3, 0x16, 0x2b, 0x53, 0x7e, 0x8f,
 | 
			
		||||
	0x2c, 0xd4, 0x8e, 0xfd, 0x93, 0xc7, 0x94, 0xb8, 0x44, 0x26, 0xe0, 0x27, 0x8f, 0x83, 0x67, 0x64,
 | 
			
		||||
	0x1d, 0x0b, 0xf2, 0xa3, 0x72, 0xcc, 0xef, 0x36, 0xf6, 0xe7, 0x0f, 0x16, 0x1f, 0xd9, 0xba, 0x77,
 | 
			
		||||
	0xba, 0x87, 0x71, 0x9c, 0x83, 0xd6, 0xe1, 0xea, 0x84, 0x3c, 0x29, 0xc9, 0x63, 0xb2, 0x56, 0x5b,
 | 
			
		||||
	0x28, 0x2b, 0x7a, 0xa9, 0x88, 0xec, 0x14, 0x6b, 0xb8, 0x5e, 0x30, 0x89, 0x75, 0x31, 0xd4, 0xc9,
 | 
			
		||||
	0x82, 0x1d, 0xd2, 0x7c, 0xa5, 0x34, 0x4b, 0xe1, 0x1a, 0x52, 0xba, 0xee, 0x74, 0xf9, 0x4a, 0xe9,
 | 
			
		||||
	0x63, 0xfb, 0x1d, 0xfc, 0xb4, 0xba, 0x62, 0xba, 0xc8, 0xb2, 0x54, 0x40, 0xcc, 0xb0, 0x53, 0xd8,
 | 
			
		||||
	0x8a, 0x6e, 0xa0, 0x54, 0xd7, 0x5d, 0xfc, 0xdc, 0x87, 0xcf, 0x6d, 0xb4, 0x13, 0x07, 0x0f, 0x49,
 | 
			
		||||
	0x73, 0xb2, 0xf8, 0xe6, 0x8d, 0xf9, 0xcf, 0x65, 0x65, 0x0a, 0x77, 0x09, 0x19, 0xf2, 0x68, 0x60,
 | 
			
		||||
	0xcf, 0x50, 0xc4, 0xf4, 0x1e, 0xaa, 0xbd, 0xe9, 0x11, 0x54, 0xd3, 0x42, 0xca, 0x0b, 0x19, 0x0d,
 | 
			
		||||
	0xec, 0x7d, 0xb5, 0x55, 0xbc, 0x6f, 0xb3, 0xfc, 0xa2, 0xf1, 0x38, 0x6c, 0x95, 0x38, 0x16, 0x72,
 | 
			
		||||
	0x9b, 0xcc, 0x16, 0x82, 0x0d, 0x55, 0x0c, 0x74, 0xb7, 0x64, 0xdc, 0x2e, 0xc4, 0x89, 0x8a, 0x21,
 | 
			
		||||
	0xb8, 0x47, 0x9a, 0xd1, 0x80, 0x1b, 0x17, 0xdd, 0x2b, 0xa3, 0x73, 0x16, 0xc3, 0xf8, 0x47, 0x24,
 | 
			
		||||
	0xc0, 0x8d, 0x1d, 0x30, 0x5e, 0x98, 0x01, 0x33, 0x22, 0xba, 0x02, 0x43, 0x3f, 0xc0, 0x54, 0x96,
 | 
			
		||||
	0x5d, 0xe4, 0xb0, 0x30, 0x83, 0x0b, 0xc4, 0x6d, 0x39, 0x61, 0xc8, 0x45, 0xca, 0xb8, 0xdb, 0x0b,
 | 
			
		||||
	0xfd, 0x10, 0x4b, 0xde, 0x42, 0xd0, 0xef, 0xcf, 0xb6, 0xa7, 0xdc, 0xb6, 0x97, 0x27, 0x07, 0x8c,
 | 
			
		||||
	0x47, 0x91, 0x2a, 0xa4, 0x61, 0x51, 0x0e, 0xdc, 0x58, 0x89, 0x3c, 0xdc, 0x6d, 0xec, 0xcf, 0x86,
 | 
			
		||||
	0x1b, 0x3e, 0x7e, 0xe8, 0xc2, 0x47, 0x3e, 0x6a, 0x05, 0x55, 0x8e, 0x90, 0x7c, 0x08, 0xf4, 0xc0,
 | 
			
		||||
	0x09, 0xca, 0x63, 0xa7, 0x7c, 0x68, 0xf7, 0x3a, 0x57, 0x89, 0xf4, 0x09, 0x86, 0xab, 0xef, 0xe0,
 | 
			
		||||
	0x43, 0xb2, 0x92, 0xf0, 0x21, 0xb0, 0xb2, 0xc5, 0xa9, 0x2b, 0x90, 0xf4, 0x53, 0x24, 0x2d, 0xd9,
 | 
			
		||||
	0x80, 0xef, 0xa7, 0x16, 0xb6, 0xd5, 0xc7, 0x77, 0x80, 0x5d, 0xc1, 0x98, 0x3e, 0x75, 0x13, 0x21,
 | 
			
		||||
	0xf0, 0x0d, 0x8c, 0x83, 0x17, 0xe4, 0xce, 0x88, 0x6b, 0x16, 0x29, 0x79, 0x0d, 0xb9, 0xd5, 0x53,
 | 
			
		||||
	0x4d, 0x5a, 0x43, 0x9d, 0xd0, 0x17, 0xf5, 0xdb, 0xb1, 0x35, 0xe2, 0xfa, 0xa8, 0x64, 0x3e, 0xaf,
 | 
			
		||||
	0x88, 0x27, 0x3a, 0x09, 0x7e, 0x41, 0xee, 0x72, 0xa9, 0x24, 0x2b, 0xb4, 0x4d, 0x87, 0xe7, 0x09,
 | 
			
		||||
	0x18, 0x36, 0xb5, 0xc1, 0x2e, 0x2e, 0xbc, 0x65, 0x49, 0x97, 0x1a, 0xf2, 0x0b, 0xa4, 0x1c, 0xd6,
 | 
			
		||||
	0xb6, 0xfb, 0x84, 0x6c, 0xe4, 0xa0, 0x55, 0x7a, 0x0d, 0xb1, 0x9b, 0xa5, 0x52, 0xe1, 0xb7, 0xa8,
 | 
			
		||||
	0xc2, 0xd5, 0x32, 0x6a, 0x87, 0x97, 0x1a, 0xfc, 0x98, 0x04, 0x90, 0x83, 0x2e, 0x52, 0xdb, 0x88,
 | 
			
		||||
	0xa4, 0xc9, 0xc7, 0x7d, 0x91, 0x02, 0x0d, 0x77, 0x1b, 0xfb, 0x33, 0xe1, 0x8a, 0x8f, 0x9c, 0x57,
 | 
			
		||||
	0x81, 0xe0, 0x27, 0x64, 0x51, 0x0f, 0x78, 0x9d, 0x7a, 0x8e, 0xe5, 0x5f, 0xd0, 0x03, 0x5e, 0xa3,
 | 
			
		||||
	0xed, 0x90, 0x26, 0x4a, 0x24, 0xb2, 0x4a, 0xba, 0x70, 0x27, 0x66, 0x81, 0x23, 0x2b, 0xa3, 0x2d,
 | 
			
		||||
	0x32, 0xa7, 0x4c, 0xe6, 0x54, 0x7a, 0x89, 0x0b, 0xcd, 0x2a, 0x93, 0xa1, 0x3a, 0x77, 0x48, 0xd3,
 | 
			
		||||
	0x86, 0xae, 0x79, 0x5a, 0x00, 0x7d, 0xe9, 0xee, 0x99, 0x32, 0xd9, 0x4b, 0xfb, 0x6d, 0xd7, 0xb6,
 | 
			
		||||
	0x41, 0x11, 0x83, 0x34, 0xa2, 0x2f, 0x20, 0xa7, 0xdf, 0xe1, 0xcc, 0x0b, 0xca, 0x64, 0x9d, 0x0a,
 | 
			
		||||
	0x0c, 0x0e, 0xc8, 0xba, 0x57, 0xa9, 0x13, 0x68, 0xf9, 0xf0, 0xd1, 0x5f, 0xd9, 0x4a, 0x84, 0xab,
 | 
			
		||||
	0x2e, 0xe8, 0x44, 0x5a, 0xbe, 0xc2, 0x0f, 0xc8, 0x92, 0x56, 0x72, 0xcc, 0x32, 0x2d, 0x4b, 0x59,
 | 
			
		||||
	0xff, 0xc6, 0xef, 0x4b, 0xc9, 0x71, 0x57, 0x4b, 0xaf, 0xe9, 0x8f, 0xc9, 0x6a, 0xc5, 0xb3, 0xca,
 | 
			
		||||
	0x11, 0x11, 0xde, 0xc6, 0xdf, 0x62, 0x1e, 0xcb, 0x9e, 0x7b, 0xee, 0x02, 0x9d, 0x38, 0xf8, 0x35,
 | 
			
		||||
	0x79, 0x1f, 0xd5, 0x0c, 0x4c, 0xc2, 0x08, 0x07, 0xa5, 0x42, 0x5e, 0x41, 0x5c, 0x15, 0x56, 0xf4,
 | 
			
		||||
	0x99, 0x04, 0x88, 0x21, 0xa6, 0xdf, 0xd7, 0x65, 0xb2, 0xe7, 0x46, 0x9d, 0xc2, 0xa8, 0xab, 0xe5,
 | 
			
		||||
	0x31, 0x0e, 0xf1, 0x85, 0xee, 0xf4, 0x4f, 0x91, 0x1f, 0xb4, 0xc9, 0x42, 0x95, 0x09, 0xca, 0xe3,
 | 
			
		||||
	0x77, 0x4e, 0xff, 0x3e, 0x07, 0x14, 0xc4, 0x43, 0x12, 0xd4, 0x35, 0xce, 0x33, 0x7b, 0x78, 0xf4,
 | 
			
		||||
	0xf7, 0x78, 0xe4, 0x35, 0x91, 0x1f, 0x66, 0x59, 0x27, 0x0e, 0x3a, 0x64, 0x0f, 0x4f, 0x26, 0x29,
 | 
			
		||||
	0x78, 0x1e, 0xb3, 0x58, 0xa1, 0x63, 0xf0, 0xad, 0x3e, 0x52, 0xc3, 0xac, 0x30, 0x90, 0x53, 0x86,
 | 
			
		||||
	0x47, 0x78, 0x6f, 0x42, 0x7c, 0xae, 0xac, 0x73, 0x70, 0xb4, 0x23, 0xcf, 0xb2, 0x57, 0xb3, 0x6c,
 | 
			
		||||
	0x55, 0x98, 0xda, 0x1f, 0x5c, 0x6a, 0x1e, 0xc3, 0xd4, 0x3e, 0x23, 0x9b, 0x75, 0x0a, 0xea, 0x35,
 | 
			
		||||
	0x1a, 0x28, 0x0d, 0x92, 0x72, 0x64, 0xaf, 0xd7, 0xd8, 0x97, 0x55, 0xd0, 0xbe, 0xe2, 0x78, 0x0e,
 | 
			
		||||
	0xf9, 0x98, 0xa9, 0x6b, 0xc8, 0x73, 0x11, 0x03, 0xed, 0xb9, 0x5b, 0xeb, 0xf1, 0x33, 0x0f, 0x07,
 | 
			
		||||
	0xbb, 0xa4, 0x25, 0xb4, 0xbf, 0x03, 0x3d, 0xf5, 0x03, 0x8d, 0x30, 0x77, 0x22, 0x34, 0x4a, 0xff,
 | 
			
		||||
	0x99, 0xfa, 0xc1, 0xf6, 0x33, 0xdf, 0xb8, 0x85, 0xd4, 0x86, 0x4b, 0x57, 0xcc, 0x18, 0x0d, 0xce,
 | 
			
		||||
	0xb2, 0x8b, 0x74, 0x7c, 0xc0, 0xbd, 0xd7, 0x66, 0xa4, 0x58, 0x9f, 0x47, 0x46, 0xe5, 0x4e, 0xd9,
 | 
			
		||||
	0xe0, 0xf4, 0x67, 0x46, 0xea, 0x05, 0xa2, 0x28, 0xef, 0x2f, 0xc9, 0x1d, 0xfb, 0x0e, 0xa8, 0xdc,
 | 
			
		||||
	0x68, 0x96, 0xdb, 0xda, 0xa7, 0x62, 0x28, 0xec, 0x61, 0x3a, 0x47, 0x46, 0xfb, 0x98, 0xc7, 0x56,
 | 
			
		||||
	0xc9, 0x09, 0xb9, 0x81, 0x63, 0xcb, 0xa8, 0x2c, 0xdb, 0x03, 0xb2, 0x34, 0x82, 0x9e, 0xb5, 0x9e,
 | 
			
		||||
	0x4a, 0x32, 0xe7, 0x78, 0x12, 0xb7, 0xd0, 0x08, 0x7a, 0x68, 0x66, 0x4e, 0xd1, 0xf9, 0xbc, 0x4f,
 | 
			
		||||
	0x96, 0xb2, 0x5c, 0xa8, 0x5c, 0x98, 0x31, 0xcb, 0x81, 0x6b, 0x25, 0xe9, 0x00, 0x6b, 0xbb, 0x58,
 | 
			
		||||
	0xc2, 0x21, 0xa2, 0xc1, 0x57, 0x64, 0xc3, 0x16, 0x28, 0x8e, 0x21, 0x66, 0xe5, 0x4b, 0x85, 0xf6,
 | 
			
		||||
	0x8c, 0x0a, 0x7c, 0x74, 0x56, 0x1e, 0xbd, 0xee, 0xdb, 0xc2, 0xb5, 0x72, 0xc0, 0x94, 0x9b, 0x7b,
 | 
			
		||||
	0x4a, 0xb6, 0x63, 0xa1, 0x79, 0x2f, 0x05, 0x96, 0xf1, 0xdc, 0x48, 0x2b, 0xaa, 0xc2, 0xa8, 0x24,
 | 
			
		||||
	0xe7, 0xd2, 0x68, 0xfa, 0x47, 0xdc, 0x18, 0xf5, 0x8c, 0xae, 0x23, 0x1c, 0x56, 0xf1, 0xf6, 0xdf,
 | 
			
		||||
	0x9a, 0x64, 0xf3, 0x35, 0x57, 0x56, 0xed, 0x79, 0x87, 0xcc, 0xfa, 0x66, 0x83, 0xa6, 0x6c, 0xe6,
 | 
			
		||||
	0x8b, 0xc6, 0x41, 0x58, 0x22, 0xb6, 0x35, 0xaa, 0xc2, 0x30, 0xd5, 0x67, 0x28, 0xe7, 0x81, 0x35,
 | 
			
		||||
	0xd8, 0x3d, 0xe0, 0xb8, 0x0b, 0x25, 0x63, 0xe7, 0x49, 0x67, 0xc2, 0x2d, 0x55, 0x98, 0xb3, 0xfe,
 | 
			
		||||
	0x57, 0x7c, 0x08, 0x5f, 0x97, 0x8c, 0x73, 0x47, 0x08, 0x3e, 0x27, 0x5b, 0x42, 0xbe, 0x69, 0xf4,
 | 
			
		||||
	0xbb, 0x38, 0x7a, 0x43, 0xc8, 0x1b, 0x87, 0xbe, 0xc9, 0x2c, 0xdc, 0x7a, 0xa3, 0x59, 0x78, 0x44,
 | 
			
		||||
	0x56, 0xcb, 0x37, 0xad, 0x66, 0xa0, 0xd1, 0xad, 0xcd, 0x86, 0x2b, 0x3e, 0x34, 0xf1, 0xeb, 0xf6,
 | 
			
		||||
	0xa1, 0x2c, 0xfb, 0x41, 0x3f, 0xe5, 0x89, 0x46, 0xa3, 0xb6, 0x10, 0x96, 0xcf, 0xdb, 0x0b, 0x8b,
 | 
			
		||||
	0xd5, 0x6d, 0xe4, 0xec, 0x94, 0x8d, 0xdc, 0x23, 0xee, 0x45, 0x65, 0xb1, 0x1a, 0x72, 0x21, 0xd1,
 | 
			
		||||
	0x8d, 0x35, 0xc3, 0x79, 0xc4, 0x9e, 0x23, 0x64, 0x17, 0x98, 0xea, 0x88, 0x68, 0xbe, 0x5a, 0x61,
 | 
			
		||||
	0xab, 0xde, 0x09, 0xed, 0xcd, 0x2a, 0x1f, 0x02, 0xf8, 0xc1, 0x80, 0xb4, 0x4d, 0x89, 0xb8, 0x56,
 | 
			
		||||
	0xe1, 0xf1, 0x5f, 0x7a, 0x38, 0x38, 0x22, 0xf7, 0x46, 0xd0, 0xe3, 0x99, 0x40, 0x1f, 0x60, 0x1b,
 | 
			
		||||
	0xaf, 0x3d, 0x00, 0xf7, 0xe6, 0x38, 0xbd, 0xce, 0x63, 0x12, 0x3b, 0x8e, 0x75, 0x58, 0x23, 0xd9,
 | 
			
		||||
	0xab, 0xec, 0xd4, 0xfb, 0x84, 0x6c, 0xf8, 0x0d, 0xb1, 0x4c, 0xc8, 0x84, 0x99, 0x41, 0x0e, 0x7a,
 | 
			
		||||
	0xa0, 0xd2, 0x98, 0xb6, 0x70, 0x7f, 0xab, 0x6e, 0x7f, 0x5d, 0x21, 0x93, 0x8b, 0x32, 0x64, 0x8f,
 | 
			
		||||
	0xb6, 0x56, 0x8c, 0x42, 0x03, 0xcb, 0x44, 0xa4, 0xe9, 0x02, 0x2a, 0x6f, 0x65, 0x12, 0xba, 0xd4,
 | 
			
		||||
	0xd0, 0x15, 0x91, 0xb6, 0xa6, 0xe9, 0x9a, 0x4b, 0x7b, 0x41, 0x8a, 0x3c, 0xa5, 0x8b, 0x98, 0x55,
 | 
			
		||||
	0xd3, 0x21, 0x97, 0x79, 0x3a, 0x6d, 0xc0, 0x96, 0xfe, 0x85, 0x01, 0xfb, 0x8c, 0x6c, 0xde, 0x68,
 | 
			
		||||
	0xf3, 0x44, 0x8c, 0xc6, 0xf1, 0x66, 0x97, 0x27, 0xb0, 0x6f, 0x88, 0x8c, 0x95, 0x5d, 0x0b, 0xfb,
 | 
			
		||||
	0xc6, 0xba, 0xbb, 0xce, 0x22, 0x3b, 0x72, 0x28, 0xf6, 0x8d, 0x87, 0x64, 0x25, 0xe3, 0x39, 0x48,
 | 
			
		||||
	0xc3, 0x53, 0xa6, 0xc1, 0x18, 0x21, 0x13, 0x8d, 0xfe, 0xb1, 0x15, 0x2e, 0x97, 0x81, 0x73, 0x8f,
 | 
			
		||||
	0xdb, 0x9b, 0xf8, 0x3a, 0x99, 0x69, 0x91, 0x48, 0x6e, 0x8a, 0x1c, 0xd0, 0x4b, 0xb6, 0x42, 0xfa,
 | 
			
		||||
	0xda, 0xa8, 0xf3, 0x32, 0x6e, 0x0b, 0xe8, 0xf4, 0x86, 0x2e, 0xa6, 0xcf, 0x45, 0x5a, 0xe4, 0xa0,
 | 
			
		||||
	0x99, 0x51, 0x6c, 0x28, 0x12, 0xdb, 0xb3, 0x28, 0xc5, 0xca, 0xef, 0x20, 0xeb, 0xb8, 0x4e, 0xba,
 | 
			
		||||
	0x50, 0x27, 0x8e, 0x62, 0xfb, 0x9c, 0x9b, 0x24, 0x16, 0x3a, 0x52, 0x52, 0x42, 0x64, 0xa6, 0xa6,
 | 
			
		||||
	0xd8, 0x72, 0x97, 0x12, 0x39, 0xcf, 0x27, 0x94, 0xc9, 0x04, 0x4f, 0xc9, 0x8e, 0x4a, 0x34, 0x8b,
 | 
			
		||||
	0xb9, 0xe1, 0x2c, 0x07, 0xdb, 0x0c, 0xf1, 0xa2, 0xb0, 0x91, 0x90, 0xb1, 0x1a, 0xd1, 0x6d, 0x1c,
 | 
			
		||||
	0xbf, 0xa9, 0x12, 0xfd, 0x9c, 0x1b, 0x1e, 0x22, 0xc1, 0xde, 0x97, 0xef, 0x30, 0xfc, 0x86, 0xe6,
 | 
			
		||||
	0xbd, 0xf3, 0x86, 0xe6, 0xfd, 0x39, 0xd9, 0xea, 0xab, 0x3c, 0x82, 0xb2, 0xff, 0x15, 0x59, 0x6c,
 | 
			
		||||
	0x25, 0x1b, 0x0d, 0x20, 0xba, 0xa2, 0x77, 0x50, 0x3e, 0x1b, 0x48, 0x70, 0xcd, 0xe9, 0x12, 0xc3,
 | 
			
		||||
	0x47, 0x36, 0xda, 0xfe, 0x96, 0x7c, 0x34, 0xe9, 0x5a, 0xde, 0x30, 0x7c, 0x07, 0xbd, 0xc3, 0x6e,
 | 
			
		||||
	0xe7, 0x66, 0x61, 0xef, 0x11, 0x82, 0x6e, 0xd2, 0x19, 0x1c, 0xd7, 0xcd, 0xde, 0xf9, 0xf8, 0x93,
 | 
			
		||||
	0xb0, 0x89, 0xa8, 0xb5, 0x39, 0xed, 0xbf, 0x37, 0xc8, 0xa7, 0xff, 0xc9, 0x9c, 0xff, 0x5e, 0x9b,
 | 
			
		||||
	0xfc, 0x9f, 0x5c, 0xcb, 0xe9, 0xec, 0xdf, 0xbd, 0x29, 0xfb, 0xa0, 0xfe, 0x3b, 0xff, 0x58, 0x25,
 | 
			
		||||
	0x67, 0xfd, 0x7e, 0xfb, 0xa0, 0xfe, 0x1f, 0x90, 0x63, 0x95, 0x24, 0x10, 0x9f, 0xf5, 0xfb, 0x6f,
 | 
			
		||||
	0xcd, 0xb7, 0xfd, 0x2d, 0x59, 0x9f, 0x8c, 0x39, 0x85, 0xd1, 0x71, 0x69, 0xa9, 0x77, 0x48, 0xb3,
 | 
			
		||||
	0x90, 0xe2, 0x55, 0x81, 0x15, 0x75, 0xbf, 0xd1, 0xe7, 0x1c, 0xd0, 0x89, 0xa7, 0xcd, 0xf8, 0x3b,
 | 
			
		||||
	0xd3, 0x66, 0xbc, 0xfd, 0x94, 0xdc, 0xbd, 0x71, 0xca, 0xc3, 0x28, 0x82, 0xcc, 0x40, 0xfc, 0xd6,
 | 
			
		||||
	0xa9, 0xdb, 0xff, 0xb8, 0x55, 0xcf, 0xa8, 0x74, 0x5c, 0xb2, 0xaf, 0x6c, 0x93, 0xcd, 0x20, 0xd7,
 | 
			
		||||
	0x4a, 0x72, 0xe7, 0x68, 0x1a, 0xae, 0xc9, 0x7a, 0x0c, 0x1d, 0xcd, 0x5d, 0x42, 0x26, 0xd7, 0xdc,
 | 
			
		||||
	0x27, 0xd6, 0xac, 0x6e, 0x38, 0xfe, 0x8a, 0xc7, 0xdb, 0x82, 0xb5, 0x89, 0x2b, 0x4b, 0xa5, 0xf1,
 | 
			
		||||
	0x5d, 0x98, 0x09, 0xd7, 0x30, 0x8a, 0x35, 0x89, 0x4b, 0x23, 0xa5, 0x7f, 0xfc, 0x34, 0xcc, 0xde,
 | 
			
		||||
	0xf0, 0x34, 0xdc, 0x27, 0xf3, 0x7d, 0x1e, 0x41, 0x4f, 0xa9, 0x2b, 0xbb, 0xab, 0x39, 0xbc, 0x02,
 | 
			
		||||
	0xa4, 0x84, 0x3a, 0xb1, 0x9d, 0xa5, 0x22, 0x60, 0xfa, 0xee, 0xc7, 0x77, 0xab, 0x04, 0x31, 0xff,
 | 
			
		||||
	0x67, 0xe4, 0x6e, 0xcd, 0xff, 0x49, 0x65, 0x44, 0x7f, 0x6c, 0x6d, 0xab, 0xf7, 0x61, 0x1a, 0xbb,
 | 
			
		||||
	0xe7, 0x5c, 0xb8, 0x33, 0x21, 0x9d, 0x22, 0xe7, 0x74, 0x42, 0x09, 0x8e, 0xc9, 0x7b, 0xb5, 0x39,
 | 
			
		||||
	0x7e, 0x64, 0xf0, 0x98, 0x77, 0x78, 0x4b, 0xb8, 0xfc, 0xfd, 0x09, 0xf5, 0x64, 0xda, 0xeb, 0x1d,
 | 
			
		||||
	0x39, 0xaf, 0xf7, 0x21, 0x59, 0x11, 0x9a, 0x65, 0x03, 0xe5, 0xfe, 0x6d, 0x60, 0xdd, 0x7d, 0x4c,
 | 
			
		||||
	0x97, 0x31, 0x8b, 0x25, 0xa1, 0xbb, 0x16, 0x7f, 0xe9, 0xe1, 0x60, 0x9f, 0x2c, 0xd7, 0xcc, 0x99,
 | 
			
		||||
	0x36, 0xb6, 0x01, 0xad, 0xe0, 0x59, 0x2d, 0x56, 0xee, 0xec, 0xdc, 0xa2, 0xf6, 0x3d, 0xaf, 0x66,
 | 
			
		||||
	0xf5, 0x3f, 0x25, 0xc6, 0x42, 0x26, 0x34, 0xc0, 0x89, 0x03, 0x3f, 0x71, 0x67, 0x12, 0x41, 0xf3,
 | 
			
		||||
	0x50, 0x8e, 0xb0, 0x6e, 0xdd, 0xf6, 0xda, 0x1c, 0x30, 0xa3, 0x31, 0x5d, 0x75, 0xbd, 0xc3, 0x0f,
 | 
			
		||||
	0x3b, 0x75, 0xe1, 0xd0, 0x47, 0xdb, 0x9f, 0x91, 0xed, 0x89, 0xa0, 0x8e, 0x06, 0x3c, 0x4d, 0x41,
 | 
			
		||||
	0x26, 0x50, 0xfe, 0xea, 0xa0, 0x64, 0xb6, 0x7c, 0x41, 0x1a, 0xf8, 0x82, 0x94, 0x9f, 0xed, 0x9f,
 | 
			
		||||
	0x93, 0x9d, 0x1b, 0xc7, 0xf9, 0x36, 0x70, 0x07, 0x7f, 0xa8, 0x3b, 0xd0, 0x0f, 0x9d, 0x00, 0xcf,
 | 
			
		||||
	0x66, 0xbe, 0x6e, 0xfc, 0xa9, 0xf1, 0x7f, 0xff, 0x0c, 0x00, 0x00, 0xff, 0xff, 0xa0, 0x4a, 0xca,
 | 
			
		||||
	0x5a, 0xd7, 0x14, 0x00, 0x00,
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										64
									
								
								vendor/github.com/Philipp15b/go-steam/protocol/protobuf/client_site_license.pb.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										64
									
								
								vendor/github.com/Philipp15b/go-steam/protocol/protobuf/client_site_license.pb.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -21,9 +21,9 @@ var _ = math.Inf
 | 
			
		||||
const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
 | 
			
		||||
 | 
			
		||||
type CMsgClientSiteInfo struct {
 | 
			
		||||
	SiteId                 *uint64  `protobuf:"varint,1,opt,name=site_id" json:"site_id,omitempty"`
 | 
			
		||||
	SiteName               *string  `protobuf:"bytes,2,opt,name=site_name" json:"site_name,omitempty"`
 | 
			
		||||
	AllowCachedCredentials *bool    `protobuf:"varint,3,opt,name=allow_cached_credentials" json:"allow_cached_credentials,omitempty"`
 | 
			
		||||
	SiteId                 *uint64  `protobuf:"varint,1,opt,name=site_id,json=siteId" json:"site_id,omitempty"`
 | 
			
		||||
	SiteName               *string  `protobuf:"bytes,2,opt,name=site_name,json=siteName" json:"site_name,omitempty"`
 | 
			
		||||
	AllowCachedCredentials *bool    `protobuf:"varint,3,opt,name=allow_cached_credentials,json=allowCachedCredentials" json:"allow_cached_credentials,omitempty"`
 | 
			
		||||
	XXX_NoUnkeyedLiteral   struct{} `json:"-"`
 | 
			
		||||
	XXX_unrecognized       []byte   `json:"-"`
 | 
			
		||||
	XXX_sizecache          int32    `json:"-"`
 | 
			
		||||
@@ -283,11 +283,11 @@ func (m *CMsgClientSiteLicenseGetContentCacheInfo) XXX_DiscardUnknown() {
 | 
			
		||||
var xxx_messageInfo_CMsgClientSiteLicenseGetContentCacheInfo proto.InternalMessageInfo
 | 
			
		||||
 | 
			
		||||
type CMsgClientSiteLicenseGetContentCacheInfoResponse struct {
 | 
			
		||||
	UseCache             *bool    `protobuf:"varint,1,opt,name=use_cache" json:"use_cache,omitempty"`
 | 
			
		||||
	Ipv4Address          *uint32  `protobuf:"varint,2,opt,name=ipv4_address" json:"ipv4_address,omitempty"`
 | 
			
		||||
	PortNumber           *uint32  `protobuf:"varint,3,opt,name=port_number" json:"port_number,omitempty"`
 | 
			
		||||
	P2PGroup             *uint32  `protobuf:"varint,4,opt,name=p2p_group" json:"p2p_group,omitempty"`
 | 
			
		||||
	IpAddress            *string  `protobuf:"bytes,5,opt,name=ip_address" json:"ip_address,omitempty"`
 | 
			
		||||
	UseCache             *bool    `protobuf:"varint,1,opt,name=use_cache,json=useCache" json:"use_cache,omitempty"`
 | 
			
		||||
	Ipv4Address          *uint32  `protobuf:"varint,2,opt,name=ipv4_address,json=ipv4Address" json:"ipv4_address,omitempty"`
 | 
			
		||||
	PortNumber           *uint32  `protobuf:"varint,3,opt,name=port_number,json=portNumber" json:"port_number,omitempty"`
 | 
			
		||||
	P2PGroup             *uint32  `protobuf:"varint,4,opt,name=p2p_group,json=p2pGroup" json:"p2p_group,omitempty"`
 | 
			
		||||
	IpAddress            *string  `protobuf:"bytes,5,opt,name=ip_address,json=ipAddress" json:"ip_address,omitempty"`
 | 
			
		||||
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
 | 
			
		||||
	XXX_unrecognized     []byte   `json:"-"`
 | 
			
		||||
	XXX_sizecache        int32    `json:"-"`
 | 
			
		||||
@@ -372,26 +372,30 @@ func init() {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var fileDescriptor_0a32817a56a37a6e = []byte{
 | 
			
		||||
	// 335 bytes of a gzipped FileDescriptorProto
 | 
			
		||||
	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x91, 0x41, 0x4b, 0xfb, 0x40,
 | 
			
		||||
	0x14, 0xc4, 0xff, 0xfb, 0xb7, 0xa1, 0xed, 0xd3, 0x20, 0x5d, 0x3d, 0x04, 0x41, 0x08, 0x81, 0x4a,
 | 
			
		||||
	0xf0, 0x50, 0xa4, 0x08, 0x82, 0x9e, 0x34, 0x07, 0x15, 0xf4, 0x62, 0x6f, 0x5e, 0xc2, 0x36, 0x79,
 | 
			
		||||
	0xb6, 0x8b, 0x9b, 0xdd, 0x25, 0x6f, 0x53, 0xaf, 0x7e, 0x0b, 0xbf, 0xae, 0x64, 0x5b, 0x0a, 0x15,
 | 
			
		||||
	0x2d, 0xbd, 0xee, 0xce, 0x6f, 0x66, 0x98, 0x07, 0x43, 0x72, 0x28, 0xaa, 0x0a, 0x89, 0xc4, 0x0c,
 | 
			
		||||
	0x29, 0x27, 0xe9, 0x50, 0xc9, 0x02, 0x35, 0x61, 0xa1, 0x24, 0x6a, 0x37, 0xb2, 0xb5, 0x71, 0xe6,
 | 
			
		||||
	0x24, 0xda, 0x94, 0x4d, 0x05, 0xe1, 0xf2, 0x27, 0x79, 0x05, 0x9e, 0x3d, 0xd3, 0x2c, 0xf3, 0xea,
 | 
			
		||||
	0x89, 0x74, 0xf8, 0xa8, 0xdf, 0x0c, 0x3f, 0x84, 0x6e, 0x6b, 0x95, 0xcb, 0x32, 0x62, 0x31, 0x4b,
 | 
			
		||||
	0x3b, 0x7c, 0x00, 0x7d, 0xff, 0xa0, 0x45, 0x85, 0xd1, 0xff, 0x98, 0xa5, 0x7d, 0x1e, 0x43, 0x24,
 | 
			
		||||
	0x94, 0x32, 0x1f, 0x79, 0x21, 0x8a, 0x39, 0x96, 0x79, 0x51, 0x63, 0x89, 0xda, 0x49, 0xa1, 0x28,
 | 
			
		||||
	0xda, 0x8b, 0x59, 0xda, 0x4b, 0x46, 0x70, 0xba, 0xe9, 0xfd, 0xb4, 0xac, 0x96, 0xcd, 0xb1, 0x78,
 | 
			
		||||
	0x37, 0x8d, 0xe3, 0x21, 0x04, 0xc2, 0xda, 0x55, 0x48, 0x98, 0xdc, 0xc0, 0x70, 0xab, 0xfe, 0x05,
 | 
			
		||||
	0xc9, 0x1a, 0x4d, 0xc8, 0x39, 0x74, 0xb1, 0x46, 0x6a, 0x94, 0xf3, 0x64, 0x70, 0xcd, 0xc6, 0xc9,
 | 
			
		||||
	0x15, 0x9c, 0xfd, 0x0a, 0xdf, 0xa3, 0xbb, 0x5d, 0x08, 0xa9, 0xc4, 0x54, 0xe1, 0x04, 0x85, 0xa3,
 | 
			
		||||
	0x9f, 0xa9, 0x13, 0x18, 0xed, 0x06, 0x6e, 0x8b, 0x6f, 0x4d, 0xa9, 0x15, 0xf9, 0x71, 0xc2, 0xe4,
 | 
			
		||||
	0x1c, 0xd2, 0xbf, 0x4c, 0x33, 0xa3, 0x1d, 0x6a, 0x97, 0xb5, 0xab, 0xb5, 0x63, 0x27, 0x5f, 0x0c,
 | 
			
		||||
	0x2e, 0x76, 0x15, 0xaf, 0x3b, 0x0c, 0xa0, 0xdf, 0x10, 0x2e, 0xb7, 0xf7, 0x2d, 0x7a, 0xfc, 0x18,
 | 
			
		||||
	0x0e, 0xa4, 0x5d, 0x5c, 0xe6, 0xa2, 0x2c, 0x6b, 0xa4, 0x55, 0x13, 0x7e, 0x04, 0xfb, 0xd6, 0xd4,
 | 
			
		||||
	0x2e, 0xd7, 0x4d, 0x35, 0xc5, 0xda, 0x5f, 0x26, 0x6c, 0x69, 0x3b, 0xb6, 0xf9, 0xac, 0x36, 0x8d,
 | 
			
		||||
	0x8d, 0x3a, 0xfe, 0x89, 0x03, 0x48, 0xbb, 0x66, 0x83, 0xf6, 0xc4, 0x77, 0xc1, 0x03, 0xfb, 0x64,
 | 
			
		||||
	0xff, 0xbe, 0x03, 0x00, 0x00, 0xff, 0xff, 0x09, 0x2f, 0x9f, 0xe9, 0x65, 0x02, 0x00, 0x00,
 | 
			
		||||
	// 393 bytes of a gzipped FileDescriptorProto
 | 
			
		||||
	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x52, 0x4f, 0x8b, 0xd3, 0x40,
 | 
			
		||||
	0x14, 0x77, 0x74, 0xe3, 0x26, 0x6f, 0xed, 0x65, 0x10, 0x0d, 0x2e, 0x8b, 0x35, 0xb0, 0x12, 0x3c,
 | 
			
		||||
	0x2c, 0x52, 0x14, 0xc4, 0x83, 0xb0, 0x46, 0x58, 0x17, 0xb4, 0x87, 0xe9, 0x07, 0x08, 0xd3, 0xe4,
 | 
			
		||||
	0xd9, 0x0e, 0x4e, 0x66, 0x86, 0xbc, 0x49, 0xbd, 0x7a, 0xf0, 0xfb, 0xf9, 0x95, 0x64, 0x26, 0xad,
 | 
			
		||||
	0x5a, 0xb0, 0xd2, 0xe3, 0xef, 0xcf, 0xfc, 0xde, 0x2f, 0xef, 0x05, 0x2e, 0xc9, 0xa3, 0xec, 0x3a,
 | 
			
		||||
	0x24, 0x92, 0x2b, 0xa4, 0x9a, 0x94, 0x47, 0xad, 0x1a, 0x34, 0x84, 0x8d, 0x56, 0x68, 0xfc, 0x95,
 | 
			
		||||
	0xeb, 0xad, 0xb7, 0x4f, 0xf2, 0x7d, 0xdb, 0x52, 0x12, 0x8e, 0x4a, 0xf1, 0x83, 0x01, 0xaf, 0x3e,
 | 
			
		||||
	0xd3, 0xaa, 0x8a, 0xf6, 0x85, 0xf2, 0x78, 0x6b, 0xbe, 0x58, 0xfe, 0x18, 0x4e, 0x43, 0x56, 0xad,
 | 
			
		||||
	0xda, 0x9c, 0x4d, 0x59, 0x79, 0x22, 0xee, 0x07, 0x78, 0xdb, 0xf2, 0x73, 0xc8, 0xa2, 0x60, 0x64,
 | 
			
		||||
	0x87, 0xf9, 0xdd, 0x29, 0x2b, 0x33, 0x91, 0x06, 0x62, 0x2e, 0x3b, 0xe4, 0x6f, 0x20, 0x97, 0x5a,
 | 
			
		||||
	0xdb, 0x6f, 0x75, 0x23, 0x9b, 0x35, 0xb6, 0x75, 0xd3, 0x63, 0x8b, 0xc6, 0x2b, 0xa9, 0x29, 0xbf,
 | 
			
		||||
	0x37, 0x65, 0x65, 0x2a, 0x1e, 0x45, 0xbd, 0x8a, 0x72, 0xf5, 0x47, 0x2d, 0x5e, 0xc3, 0xc5, 0x7e,
 | 
			
		||||
	0x8b, 0x4f, 0xe3, 0x57, 0x54, 0x6b, 0x6c, 0xbe, 0xda, 0xc1, 0xf3, 0x87, 0x90, 0x48, 0xe7, 0xb6,
 | 
			
		||||
	0x75, 0x26, 0x62, 0x04, 0xc5, 0x07, 0xb8, 0xfc, 0xef, 0x33, 0x81, 0xe4, 0xac, 0x21, 0xe4, 0xe7,
 | 
			
		||||
	0x70, 0x8a, 0x3d, 0xd2, 0xa0, 0x7d, 0x0c, 0x48, 0xde, 0xb2, 0x99, 0xd8, 0x31, 0xc5, 0x3b, 0x78,
 | 
			
		||||
	0xfe, 0xcf, 0x94, 0x1b, 0xf4, 0xd7, 0x1b, 0xa9, 0xb4, 0x5c, 0x6a, 0x5c, 0xa0, 0xf4, 0x74, 0xa0,
 | 
			
		||||
	0x45, 0x03, 0x57, 0xc7, 0xbd, 0x3f, 0xaa, 0x4e, 0x18, 0x42, 0xc1, 0x1d, 0xd7, 0x3b, 0x11, 0x23,
 | 
			
		||||
	0x28, 0x5e, 0x40, 0x79, 0x68, 0x48, 0x65, 0x8d, 0x47, 0xe3, 0xe3, 0x56, 0xc3, 0xf5, 0x8a, 0x9f,
 | 
			
		||||
	0x0c, 0x5e, 0x1e, 0x6b, 0xfe, 0xab, 0x53, 0x36, 0x10, 0x8e, 0xa7, 0x8b, 0xad, 0x52, 0x91, 0x0e,
 | 
			
		||||
	0x84, 0xd1, 0xc8, 0x9f, 0xc1, 0x03, 0xe5, 0x36, 0xaf, 0x6a, 0xd9, 0xb6, 0x3d, 0xd2, 0xae, 0xda,
 | 
			
		||||
	0x59, 0xe0, 0xae, 0x47, 0x8a, 0x3f, 0x85, 0x33, 0x67, 0x7b, 0x5f, 0x9b, 0xa1, 0x5b, 0x62, 0x1f,
 | 
			
		||||
	0xef, 0x3d, 0x11, 0x10, 0xa8, 0x79, 0x64, 0xc2, 0x00, 0x37, 0x73, 0xf5, 0xaa, 0xb7, 0x83, 0xcb,
 | 
			
		||||
	0x4f, 0xa2, 0x9c, 0xba, 0x99, 0xbb, 0x09, 0x98, 0x5f, 0x00, 0x28, 0xf7, 0x3b, 0x3e, 0x89, 0x3f,
 | 
			
		||||
	0x56, 0xa6, 0xdc, 0x36, 0xfc, 0x7d, 0xf2, 0x91, 0x7d, 0x67, 0x77, 0x7e, 0x05, 0x00, 0x00, 0xff,
 | 
			
		||||
	0xff, 0x35, 0x87, 0xfb, 0x5f, 0xef, 0x02, 0x00, 0x00,
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										180
									
								
								vendor/github.com/Philipp15b/go-steam/protocol/protobuf/content_manifest.pb.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										180
									
								
								vendor/github.com/Philipp15b/go-steam/protocol/protobuf/content_manifest.pb.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -20,6 +20,46 @@ var _ = math.Inf
 | 
			
		||||
// proto package protobuf to be updated.
 | 
			
		||||
const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
 | 
			
		||||
 | 
			
		||||
type EContentDeltaChunkDataLocation int32
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	EContentDeltaChunkDataLocation_k_EContentDeltaChunkDataLocationInProtobuf    EContentDeltaChunkDataLocation = 0
 | 
			
		||||
	EContentDeltaChunkDataLocation_k_EContentDeltaChunkDataLocationAfterProtobuf EContentDeltaChunkDataLocation = 1
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var EContentDeltaChunkDataLocation_name = map[int32]string{
 | 
			
		||||
	0: "k_EContentDeltaChunkDataLocationInProtobuf",
 | 
			
		||||
	1: "k_EContentDeltaChunkDataLocationAfterProtobuf",
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var EContentDeltaChunkDataLocation_value = map[string]int32{
 | 
			
		||||
	"k_EContentDeltaChunkDataLocationInProtobuf":    0,
 | 
			
		||||
	"k_EContentDeltaChunkDataLocationAfterProtobuf": 1,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (x EContentDeltaChunkDataLocation) Enum() *EContentDeltaChunkDataLocation {
 | 
			
		||||
	p := new(EContentDeltaChunkDataLocation)
 | 
			
		||||
	*p = x
 | 
			
		||||
	return p
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (x EContentDeltaChunkDataLocation) String() string {
 | 
			
		||||
	return proto.EnumName(EContentDeltaChunkDataLocation_name, int32(x))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (x *EContentDeltaChunkDataLocation) UnmarshalJSON(data []byte) error {
 | 
			
		||||
	value, err := proto.UnmarshalJSONEnum(EContentDeltaChunkDataLocation_value, data, "EContentDeltaChunkDataLocation")
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	*x = EContentDeltaChunkDataLocation(value)
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (EContentDeltaChunkDataLocation) EnumDescriptor() ([]byte, []int) {
 | 
			
		||||
	return fileDescriptor_e3cda137a29253ba, []int{0}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type ContentManifestPayload struct {
 | 
			
		||||
	Mappings             []*ContentManifestPayload_FileMapping `protobuf:"bytes,1,rep,name=mappings" json:"mappings,omitempty"`
 | 
			
		||||
	XXX_NoUnkeyedLiteral struct{}                              `json:"-"`
 | 
			
		||||
@@ -63,8 +103,8 @@ type ContentManifestPayload_FileMapping struct {
 | 
			
		||||
	Filename             *string                                         `protobuf:"bytes,1,opt,name=filename" json:"filename,omitempty"`
 | 
			
		||||
	Size                 *uint64                                         `protobuf:"varint,2,opt,name=size" json:"size,omitempty"`
 | 
			
		||||
	Flags                *uint32                                         `protobuf:"varint,3,opt,name=flags" json:"flags,omitempty"`
 | 
			
		||||
	ShaFilename          []byte                                          `protobuf:"bytes,4,opt,name=sha_filename" json:"sha_filename,omitempty"`
 | 
			
		||||
	ShaContent           []byte                                          `protobuf:"bytes,5,opt,name=sha_content" json:"sha_content,omitempty"`
 | 
			
		||||
	ShaFilename          []byte                                          `protobuf:"bytes,4,opt,name=sha_filename,json=shaFilename" json:"sha_filename,omitempty"`
 | 
			
		||||
	ShaContent           []byte                                          `protobuf:"bytes,5,opt,name=sha_content,json=shaContent" json:"sha_content,omitempty"`
 | 
			
		||||
	Chunks               []*ContentManifestPayload_FileMapping_ChunkData `protobuf:"bytes,6,rep,name=chunks" json:"chunks,omitempty"`
 | 
			
		||||
	Linktarget           *string                                         `protobuf:"bytes,7,opt,name=linktarget" json:"linktarget,omitempty"`
 | 
			
		||||
	XXX_NoUnkeyedLiteral struct{}                                        `json:"-"`
 | 
			
		||||
@@ -150,8 +190,8 @@ type ContentManifestPayload_FileMapping_ChunkData struct {
 | 
			
		||||
	Sha                  []byte   `protobuf:"bytes,1,opt,name=sha" json:"sha,omitempty"`
 | 
			
		||||
	Crc                  *uint32  `protobuf:"fixed32,2,opt,name=crc" json:"crc,omitempty"`
 | 
			
		||||
	Offset               *uint64  `protobuf:"varint,3,opt,name=offset" json:"offset,omitempty"`
 | 
			
		||||
	CbOriginal           *uint32  `protobuf:"varint,4,opt,name=cb_original" json:"cb_original,omitempty"`
 | 
			
		||||
	CbCompressed         *uint32  `protobuf:"varint,5,opt,name=cb_compressed" json:"cb_compressed,omitempty"`
 | 
			
		||||
	CbOriginal           *uint32  `protobuf:"varint,4,opt,name=cb_original,json=cbOriginal" json:"cb_original,omitempty"`
 | 
			
		||||
	CbCompressed         *uint32  `protobuf:"varint,5,opt,name=cb_compressed,json=cbCompressed" json:"cb_compressed,omitempty"`
 | 
			
		||||
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
 | 
			
		||||
	XXX_unrecognized     []byte   `json:"-"`
 | 
			
		||||
	XXX_sizecache        int32    `json:"-"`
 | 
			
		||||
@@ -222,15 +262,15 @@ func (m *ContentManifestPayload_FileMapping_ChunkData) GetCbCompressed() uint32
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type ContentManifestMetadata struct {
 | 
			
		||||
	DepotId              *uint32  `protobuf:"varint,1,opt,name=depot_id" json:"depot_id,omitempty"`
 | 
			
		||||
	GidManifest          *uint64  `protobuf:"varint,2,opt,name=gid_manifest" json:"gid_manifest,omitempty"`
 | 
			
		||||
	CreationTime         *uint32  `protobuf:"varint,3,opt,name=creation_time" json:"creation_time,omitempty"`
 | 
			
		||||
	FilenamesEncrypted   *bool    `protobuf:"varint,4,opt,name=filenames_encrypted" json:"filenames_encrypted,omitempty"`
 | 
			
		||||
	CbDiskOriginal       *uint64  `protobuf:"varint,5,opt,name=cb_disk_original" json:"cb_disk_original,omitempty"`
 | 
			
		||||
	CbDiskCompressed     *uint64  `protobuf:"varint,6,opt,name=cb_disk_compressed" json:"cb_disk_compressed,omitempty"`
 | 
			
		||||
	UniqueChunks         *uint32  `protobuf:"varint,7,opt,name=unique_chunks" json:"unique_chunks,omitempty"`
 | 
			
		||||
	CrcEncrypted         *uint32  `protobuf:"varint,8,opt,name=crc_encrypted" json:"crc_encrypted,omitempty"`
 | 
			
		||||
	CrcClear             *uint32  `protobuf:"varint,9,opt,name=crc_clear" json:"crc_clear,omitempty"`
 | 
			
		||||
	DepotId              *uint32  `protobuf:"varint,1,opt,name=depot_id,json=depotId" json:"depot_id,omitempty"`
 | 
			
		||||
	GidManifest          *uint64  `protobuf:"varint,2,opt,name=gid_manifest,json=gidManifest" json:"gid_manifest,omitempty"`
 | 
			
		||||
	CreationTime         *uint32  `protobuf:"varint,3,opt,name=creation_time,json=creationTime" json:"creation_time,omitempty"`
 | 
			
		||||
	FilenamesEncrypted   *bool    `protobuf:"varint,4,opt,name=filenames_encrypted,json=filenamesEncrypted" json:"filenames_encrypted,omitempty"`
 | 
			
		||||
	CbDiskOriginal       *uint64  `protobuf:"varint,5,opt,name=cb_disk_original,json=cbDiskOriginal" json:"cb_disk_original,omitempty"`
 | 
			
		||||
	CbDiskCompressed     *uint64  `protobuf:"varint,6,opt,name=cb_disk_compressed,json=cbDiskCompressed" json:"cb_disk_compressed,omitempty"`
 | 
			
		||||
	UniqueChunks         *uint32  `protobuf:"varint,7,opt,name=unique_chunks,json=uniqueChunks" json:"unique_chunks,omitempty"`
 | 
			
		||||
	CrcEncrypted         *uint32  `protobuf:"varint,8,opt,name=crc_encrypted,json=crcEncrypted" json:"crc_encrypted,omitempty"`
 | 
			
		||||
	CrcClear             *uint32  `protobuf:"varint,9,opt,name=crc_clear,json=crcClear" json:"crc_clear,omitempty"`
 | 
			
		||||
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
 | 
			
		||||
	XXX_unrecognized     []byte   `json:"-"`
 | 
			
		||||
	XXX_sizecache        int32    `json:"-"`
 | 
			
		||||
@@ -364,10 +404,11 @@ func (m *ContentManifestSignature) GetSignature() []byte {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type ContentDeltaChunks struct {
 | 
			
		||||
	DepotId              *uint32                          `protobuf:"varint,1,opt,name=depot_id" json:"depot_id,omitempty"`
 | 
			
		||||
	ManifestIdSource     *uint64                          `protobuf:"varint,2,opt,name=manifest_id_source" json:"manifest_id_source,omitempty"`
 | 
			
		||||
	ManifestIdTarget     *uint64                          `protobuf:"varint,3,opt,name=manifest_id_target" json:"manifest_id_target,omitempty"`
 | 
			
		||||
	DepotId              *uint32                          `protobuf:"varint,1,opt,name=depot_id,json=depotId" json:"depot_id,omitempty"`
 | 
			
		||||
	ManifestIdSource     *uint64                          `protobuf:"varint,2,opt,name=manifest_id_source,json=manifestIdSource" json:"manifest_id_source,omitempty"`
 | 
			
		||||
	ManifestIdTarget     *uint64                          `protobuf:"varint,3,opt,name=manifest_id_target,json=manifestIdTarget" json:"manifest_id_target,omitempty"`
 | 
			
		||||
	DeltaChunks          []*ContentDeltaChunks_DeltaChunk `protobuf:"bytes,4,rep,name=deltaChunks" json:"deltaChunks,omitempty"`
 | 
			
		||||
	ChunkDataLocation    *EContentDeltaChunkDataLocation  `protobuf:"varint,5,opt,name=chunk_data_location,json=chunkDataLocation,enum=EContentDeltaChunkDataLocation,def=0" json:"chunk_data_location,omitempty"`
 | 
			
		||||
	XXX_NoUnkeyedLiteral struct{}                         `json:"-"`
 | 
			
		||||
	XXX_unrecognized     []byte                           `json:"-"`
 | 
			
		||||
	XXX_sizecache        int32                            `json:"-"`
 | 
			
		||||
@@ -398,6 +439,8 @@ func (m *ContentDeltaChunks) XXX_DiscardUnknown() {
 | 
			
		||||
 | 
			
		||||
var xxx_messageInfo_ContentDeltaChunks proto.InternalMessageInfo
 | 
			
		||||
 | 
			
		||||
const Default_ContentDeltaChunks_ChunkDataLocation EContentDeltaChunkDataLocation = EContentDeltaChunkDataLocation_k_EContentDeltaChunkDataLocationInProtobuf
 | 
			
		||||
 | 
			
		||||
func (m *ContentDeltaChunks) GetDepotId() uint32 {
 | 
			
		||||
	if m != nil && m.DepotId != nil {
 | 
			
		||||
		return *m.DepotId
 | 
			
		||||
@@ -426,12 +469,20 @@ func (m *ContentDeltaChunks) GetDeltaChunks() []*ContentDeltaChunks_DeltaChunk {
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *ContentDeltaChunks) GetChunkDataLocation() EContentDeltaChunkDataLocation {
 | 
			
		||||
	if m != nil && m.ChunkDataLocation != nil {
 | 
			
		||||
		return *m.ChunkDataLocation
 | 
			
		||||
	}
 | 
			
		||||
	return Default_ContentDeltaChunks_ChunkDataLocation
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type ContentDeltaChunks_DeltaChunk struct {
 | 
			
		||||
	ShaSource            []byte   `protobuf:"bytes,1,opt,name=sha_source" json:"sha_source,omitempty"`
 | 
			
		||||
	ShaTarget            []byte   `protobuf:"bytes,2,opt,name=sha_target" json:"sha_target,omitempty"`
 | 
			
		||||
	SizeOriginal         *uint32  `protobuf:"varint,3,opt,name=size_original" json:"size_original,omitempty"`
 | 
			
		||||
	PatchMethod          *uint32  `protobuf:"varint,4,opt,name=patch_method" json:"patch_method,omitempty"`
 | 
			
		||||
	ShaSource            []byte   `protobuf:"bytes,1,opt,name=sha_source,json=shaSource" json:"sha_source,omitempty"`
 | 
			
		||||
	ShaTarget            []byte   `protobuf:"bytes,2,opt,name=sha_target,json=shaTarget" json:"sha_target,omitempty"`
 | 
			
		||||
	SizeOriginal         *uint32  `protobuf:"varint,3,opt,name=size_original,json=sizeOriginal" json:"size_original,omitempty"`
 | 
			
		||||
	PatchMethod          *uint32  `protobuf:"varint,4,opt,name=patch_method,json=patchMethod" json:"patch_method,omitempty"`
 | 
			
		||||
	Chunk                []byte   `protobuf:"bytes,5,opt,name=chunk" json:"chunk,omitempty"`
 | 
			
		||||
	SizeDelta            *uint32  `protobuf:"varint,6,opt,name=size_delta,json=sizeDelta" json:"size_delta,omitempty"`
 | 
			
		||||
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
 | 
			
		||||
	XXX_unrecognized     []byte   `json:"-"`
 | 
			
		||||
	XXX_sizecache        int32    `json:"-"`
 | 
			
		||||
@@ -497,7 +548,15 @@ func (m *ContentDeltaChunks_DeltaChunk) GetChunk() []byte {
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *ContentDeltaChunks_DeltaChunk) GetSizeDelta() uint32 {
 | 
			
		||||
	if m != nil && m.SizeDelta != nil {
 | 
			
		||||
		return *m.SizeDelta
 | 
			
		||||
	}
 | 
			
		||||
	return 0
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func init() {
 | 
			
		||||
	proto.RegisterEnum("EContentDeltaChunkDataLocation", EContentDeltaChunkDataLocation_name, EContentDeltaChunkDataLocation_value)
 | 
			
		||||
	proto.RegisterType((*ContentManifestPayload)(nil), "ContentManifestPayload")
 | 
			
		||||
	proto.RegisterType((*ContentManifestPayload_FileMapping)(nil), "ContentManifestPayload.FileMapping")
 | 
			
		||||
	proto.RegisterType((*ContentManifestPayload_FileMapping_ChunkData)(nil), "ContentManifestPayload.FileMapping.ChunkData")
 | 
			
		||||
@@ -510,37 +569,52 @@ func init() {
 | 
			
		||||
func init() { proto.RegisterFile("content_manifest.proto", fileDescriptor_e3cda137a29253ba) }
 | 
			
		||||
 | 
			
		||||
var fileDescriptor_e3cda137a29253ba = []byte{
 | 
			
		||||
	// 508 bytes of a gzipped FileDescriptorProto
 | 
			
		||||
	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x92, 0xcd, 0x8e, 0xd3, 0x30,
 | 
			
		||||
	0x10, 0xc7, 0x49, 0xbf, 0x3b, 0x6d, 0x50, 0xf1, 0xb2, 0x8b, 0x55, 0x24, 0x54, 0x95, 0x4b, 0x2f,
 | 
			
		||||
	0x9b, 0x03, 0x88, 0x23, 0x17, 0x76, 0x85, 0xb8, 0x54, 0x42, 0xe2, 0x01, 0x2c, 0xd7, 0x76, 0x53,
 | 
			
		||||
	0xab, 0x89, 0x1d, 0x6c, 0xe7, 0xb0, 0x9c, 0xb8, 0xf0, 0x18, 0xbc, 0x21, 0x12, 0xaf, 0x80, 0xec,
 | 
			
		||||
	0x38, 0x4d, 0x55, 0xf6, 0xb0, 0xb7, 0xcc, 0x47, 0x3c, 0xbf, 0xf9, 0xcf, 0x1f, 0x6e, 0x98, 0x56,
 | 
			
		||||
	0x4e, 0x28, 0x47, 0x4a, 0xaa, 0xe4, 0x5e, 0x58, 0x97, 0x55, 0x46, 0x3b, 0xbd, 0xfe, 0xdb, 0x83,
 | 
			
		||||
	0x9b, 0xbb, 0xa6, 0xb4, 0x8d, 0x95, 0xaf, 0xf4, 0xa1, 0xd0, 0x94, 0xa3, 0x0f, 0x30, 0x29, 0x69,
 | 
			
		||||
	0x55, 0x49, 0x95, 0x5b, 0x9c, 0xac, 0xfa, 0x9b, 0xd9, 0xbb, 0xb7, 0xd9, 0xe3, 0xad, 0xd9, 0x67,
 | 
			
		||||
	0x59, 0x88, 0x6d, 0xd3, 0xbb, 0xfc, 0xdd, 0x83, 0xd9, 0x59, 0x8c, 0x16, 0x30, 0xd9, 0xcb, 0x42,
 | 
			
		||||
	0x28, 0x5a, 0x0a, 0x9c, 0xac, 0x92, 0xcd, 0x14, 0xcd, 0x61, 0x60, 0xe5, 0x0f, 0x81, 0x7b, 0xab,
 | 
			
		||||
	0x64, 0x33, 0x40, 0x29, 0x0c, 0xf7, 0x05, 0xcd, 0x2d, 0xee, 0xaf, 0x92, 0x4d, 0x8a, 0x5e, 0xc2,
 | 
			
		||||
	0xdc, 0x1e, 0x28, 0x39, 0xfd, 0x32, 0x58, 0x25, 0x9b, 0x39, 0xba, 0x82, 0x99, 0xcf, 0xc6, 0x25,
 | 
			
		||||
	0xf0, 0x30, 0x24, 0x3f, 0xc2, 0x88, 0x1d, 0x6a, 0x75, 0xb4, 0x78, 0x14, 0xf0, 0x6e, 0x9f, 0x80,
 | 
			
		||||
	0x97, 0xdd, 0xf9, 0x3f, 0xee, 0xa9, 0xa3, 0x08, 0x01, 0x14, 0x52, 0x1d, 0x1d, 0x35, 0xb9, 0x70,
 | 
			
		||||
	0x78, 0xec, 0xd1, 0x96, 0x14, 0xa6, 0x5d, 0xc3, 0x0c, 0xfa, 0xf6, 0x40, 0x03, 0xf4, 0xdc, 0x07,
 | 
			
		||||
	0xcc, 0xb0, 0xc0, 0x3c, 0x46, 0xcf, 0x61, 0xa4, 0xf7, 0x7b, 0x2b, 0x5c, 0x80, 0x1e, 0x78, 0x3c,
 | 
			
		||||
	0xb6, 0x23, 0xda, 0xc8, 0x5c, 0x2a, 0x5a, 0x04, 0xe6, 0x14, 0x5d, 0x43, 0xca, 0x76, 0x84, 0xe9,
 | 
			
		||||
	0xb2, 0x32, 0xc2, 0x5a, 0xc1, 0x03, 0x75, 0xba, 0xfe, 0x93, 0xc0, 0xab, 0x0b, 0xce, 0xad, 0x70,
 | 
			
		||||
	0x94, 0xfb, 0x89, 0x0b, 0x98, 0x70, 0x51, 0x69, 0x47, 0x24, 0x0f, 0x63, 0x83, 0x1c, 0xb9, 0xe4,
 | 
			
		||||
	0xa7, 0xab, 0x45, 0xcd, 0xfc, 0xd3, 0x46, 0x50, 0x27, 0xb5, 0x22, 0x4e, 0x96, 0x22, 0x6a, 0xf7,
 | 
			
		||||
	0x1a, 0xae, 0x5a, 0xdd, 0x2c, 0x11, 0x8a, 0x99, 0x87, 0xca, 0x09, 0x1e, 0x70, 0x26, 0x08, 0xc3,
 | 
			
		||||
	0x82, 0xed, 0x08, 0x97, 0xf6, 0xd8, 0x81, 0x0e, 0xc3, 0x6b, 0x4b, 0x40, 0x6d, 0xe5, 0x8c, 0x76,
 | 
			
		||||
	0xd4, 0x4e, 0xaa, 0x95, 0xfc, 0x5e, 0x0b, 0x12, 0xa5, 0x1e, 0x9f, 0x76, 0x33, 0xec, 0x6c, 0xc6,
 | 
			
		||||
	0x24, 0xa4, 0x5f, 0xc0, 0xd4, 0xa7, 0x59, 0x21, 0xa8, 0xc1, 0xd3, 0xb0, 0xee, 0x2d, 0xe0, 0x8b,
 | 
			
		||||
	0x6d, 0xbf, 0xc9, 0x5c, 0x51, 0x57, 0x1b, 0xe1, 0xdb, 0x6d, 0x1b, 0x34, 0x32, 0xaf, 0x7f, 0xf5,
 | 
			
		||||
	0x00, 0xc5, 0xfe, 0x7b, 0x51, 0x38, 0x1a, 0xae, 0x61, 0x1f, 0x11, 0x66, 0x09, 0xa8, 0x15, 0x85,
 | 
			
		||||
	0x48, 0x4e, 0xac, 0xae, 0x0d, 0x6b, 0x2d, 0x75, 0x51, 0x8b, 0x17, 0x6e, 0x4e, 0xf5, 0x1e, 0x66,
 | 
			
		||||
	0xbc, 0x7b, 0x18, 0x0f, 0x82, 0x73, 0xde, 0x64, 0xff, 0xcf, 0xcc, 0xba, 0xef, 0x65, 0x05, 0xd0,
 | 
			
		||||
	0x45, 0xde, 0x38, 0xde, 0x8c, 0x71, 0x64, 0x63, 0x8f, 0x98, 0x8b, 0xa3, 0x7a, 0x21, 0x77, 0x0d,
 | 
			
		||||
	0xa9, 0xf7, 0x79, 0x27, 0xf7, 0xc9, 0xe1, 0x15, 0x75, 0xec, 0x40, 0x4a, 0xe1, 0x0e, 0x9a, 0x47,
 | 
			
		||||
	0xb7, 0xa4, 0x30, 0x0c, 0x0a, 0x37, 0xde, 0xfe, 0x34, 0xfc, 0x92, 0xfc, 0x4c, 0x9e, 0xfd, 0x0b,
 | 
			
		||||
	0x00, 0x00, 0xff, 0xff, 0x00, 0x92, 0x22, 0xd7, 0xb7, 0x03, 0x00, 0x00,
 | 
			
		||||
	// 742 bytes of a gzipped FileDescriptorProto
 | 
			
		||||
	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x54, 0x4f, 0x6f, 0xd3, 0x4e,
 | 
			
		||||
	0x10, 0xad, 0x9b, 0xff, 0x93, 0xa4, 0xca, 0x6f, 0xfb, 0x53, 0x31, 0x01, 0xda, 0x34, 0xbd, 0x44,
 | 
			
		||||
	0x55, 0x6b, 0x44, 0x4f, 0x88, 0x0b, 0x7f, 0xd2, 0x56, 0x54, 0x22, 0xa2, 0xda, 0xf6, 0xbe, 0xda,
 | 
			
		||||
	0xac, 0x37, 0xf1, 0x2a, 0x8e, 0x1d, 0xbc, 0x9b, 0x43, 0xcb, 0x05, 0x89, 0x33, 0x9c, 0xf8, 0x4e,
 | 
			
		||||
	0x7c, 0x17, 0xc4, 0x87, 0x40, 0xbb, 0x5e, 0xdb, 0x51, 0x8a, 0x0a, 0xdc, 0x3c, 0x33, 0x6f, 0xd6,
 | 
			
		||||
	0xef, 0xbd, 0x99, 0x5d, 0xd8, 0x61, 0x71, 0xa4, 0x78, 0xa4, 0xc8, 0x9c, 0x46, 0x62, 0xc2, 0xa5,
 | 
			
		||||
	0xf2, 0x16, 0x49, 0xac, 0xe2, 0xfe, 0x8f, 0x12, 0xec, 0x0c, 0xd3, 0xd2, 0xc8, 0x56, 0x2e, 0xe9,
 | 
			
		||||
	0x4d, 0x18, 0x53, 0x1f, 0xbd, 0x84, 0xfa, 0x9c, 0x2e, 0x16, 0x22, 0x9a, 0x4a, 0xd7, 0xe9, 0x95,
 | 
			
		||||
	0x06, 0xcd, 0x93, 0x03, 0xef, 0xf7, 0x50, 0xef, 0x5c, 0x84, 0x7c, 0x94, 0x62, 0x71, 0xde, 0xd4,
 | 
			
		||||
	0xfd, 0x5a, 0x82, 0xe6, 0x4a, 0x05, 0x75, 0xa1, 0x3e, 0x11, 0x21, 0x8f, 0xe8, 0x9c, 0xbb, 0x4e,
 | 
			
		||||
	0xcf, 0x19, 0x34, 0x70, 0x1e, 0x23, 0x04, 0x65, 0x29, 0x6e, 0xb9, 0xbb, 0xd9, 0x73, 0x06, 0x65,
 | 
			
		||||
	0x6c, 0xbe, 0xd1, 0xff, 0x50, 0x99, 0x84, 0x74, 0x2a, 0xdd, 0x52, 0xcf, 0x19, 0xb4, 0x71, 0x1a,
 | 
			
		||||
	0xa0, 0x7d, 0x68, 0xc9, 0x80, 0x92, 0xfc, 0xa4, 0x72, 0xcf, 0x19, 0xb4, 0x70, 0x53, 0x06, 0xf4,
 | 
			
		||||
	0x3c, 0x3b, 0x6c, 0x0f, 0x74, 0x48, 0xac, 0x64, 0xb7, 0x62, 0x10, 0x20, 0x03, 0x6a, 0xe9, 0xa3,
 | 
			
		||||
	0x33, 0xa8, 0xb2, 0x60, 0x19, 0xcd, 0xa4, 0x5b, 0x35, 0xc2, 0x8e, 0xff, 0x42, 0x98, 0x37, 0xd4,
 | 
			
		||||
	0x1d, 0xa7, 0x54, 0x51, 0x6c, 0x9b, 0xd1, 0x2e, 0x40, 0x28, 0xa2, 0x99, 0xa2, 0xc9, 0x94, 0x2b,
 | 
			
		||||
	0xb7, 0x66, 0x24, 0xad, 0x64, 0xba, 0x5f, 0x1c, 0x68, 0xe4, 0x5d, 0xa8, 0x03, 0x25, 0x19, 0x50,
 | 
			
		||||
	0xa3, 0xbc, 0x85, 0xf5, 0xa7, 0xce, 0xb0, 0x84, 0x19, 0xcd, 0x35, 0xac, 0x3f, 0xd1, 0x0e, 0x54,
 | 
			
		||||
	0xe3, 0xc9, 0x44, 0x72, 0x65, 0x34, 0x97, 0xb1, 0x8d, 0xb4, 0x22, 0x36, 0x26, 0x71, 0x22, 0xa6,
 | 
			
		||||
	0x22, 0xa2, 0xa1, 0xd1, 0xdc, 0xc6, 0xc0, 0xc6, 0xef, 0x6d, 0x06, 0x1d, 0x40, 0x9b, 0x8d, 0x09,
 | 
			
		||||
	0x8b, 0xe7, 0x8b, 0x84, 0x4b, 0xc9, 0x7d, 0x23, 0xba, 0x8d, 0x5b, 0x6c, 0x3c, 0xcc, 0x73, 0xfd,
 | 
			
		||||
	0x9f, 0x9b, 0xf0, 0x60, 0x4d, 0xe8, 0x88, 0x2b, 0xea, 0x6b, 0x76, 0x0f, 0xa1, 0xee, 0xf3, 0x45,
 | 
			
		||||
	0xac, 0x88, 0xf0, 0x0d, 0xc5, 0x36, 0xae, 0x99, 0xf8, 0xc2, 0xd7, 0x8e, 0x4f, 0x85, 0x9f, 0x6f,
 | 
			
		||||
	0x8e, 0x9d, 0x51, 0x73, 0x2a, 0xfc, 0xec, 0x14, 0xf3, 0xfb, 0x84, 0x53, 0x25, 0xe2, 0x88, 0x28,
 | 
			
		||||
	0x31, 0xe7, 0x76, 0x64, 0xad, 0x2c, 0x79, 0x2d, 0xe6, 0x1c, 0x3d, 0x85, 0xed, 0x6c, 0x6a, 0x92,
 | 
			
		||||
	0xf0, 0x88, 0x25, 0x37, 0x0b, 0xc5, 0x7d, 0x23, 0xa6, 0x8e, 0x51, 0x5e, 0x3a, 0xcb, 0x2a, 0x68,
 | 
			
		||||
	0x00, 0x1d, 0x36, 0x26, 0xbe, 0x90, 0xb3, 0x42, 0x7a, 0xc5, 0xfc, 0x7c, 0x8b, 0x8d, 0x4f, 0x85,
 | 
			
		||||
	0x9c, 0xe5, 0xf2, 0x8f, 0x00, 0x65, 0xc8, 0x15, 0x0f, 0xaa, 0x06, 0xdb, 0x49, 0xb1, 0x85, 0x0f,
 | 
			
		||||
	0x9a, 0xed, 0x32, 0x12, 0x1f, 0x96, 0x9c, 0xd8, 0x2d, 0xa8, 0xa5, 0x6c, 0xd3, 0xe4, 0x30, 0x1d,
 | 
			
		||||
	0xae, 0x91, 0xc4, 0x56, 0x78, 0xd6, 0x33, 0x49, 0xac, 0x60, 0xf8, 0x08, 0x1a, 0x1a, 0xc4, 0x42,
 | 
			
		||||
	0x4e, 0x13, 0xb7, 0x61, 0x00, 0x75, 0x96, 0xb0, 0xa1, 0x8e, 0xfb, 0xcf, 0xc1, 0x5d, 0x73, 0xfb,
 | 
			
		||||
	0x4a, 0x4c, 0x23, 0xaa, 0x96, 0x09, 0x47, 0x8f, 0xa1, 0x21, 0xb3, 0xc0, 0xae, 0x44, 0x91, 0xe8,
 | 
			
		||||
	0x7f, 0x2b, 0x03, 0xb2, 0xad, 0xa7, 0x3c, 0x54, 0xd4, 0x52, 0xba, 0x67, 0x46, 0x47, 0x80, 0xb2,
 | 
			
		||||
	0xf9, 0x10, 0xe1, 0x13, 0x19, 0x2f, 0x13, 0x96, 0xdd, 0xa6, 0x4e, 0x56, 0xb9, 0xf0, 0xaf, 0x4c,
 | 
			
		||||
	0x7e, 0x1d, 0x6d, 0x17, 0xb8, 0xb4, 0x8e, 0xbe, 0x36, 0x79, 0xf4, 0x0a, 0x9a, 0x7e, 0xc1, 0xc2,
 | 
			
		||||
	0x2d, 0x9b, 0x2b, 0xb3, 0xeb, 0xdd, 0x25, 0xe8, 0x15, 0xdf, 0x78, 0xb5, 0x05, 0x7d, 0x84, 0x6d,
 | 
			
		||||
	0xe3, 0x34, 0xd1, 0xab, 0x46, 0xc2, 0x98, 0x99, 0xa5, 0x30, 0xb3, 0xdc, 0x3a, 0xd9, 0xf3, 0xce,
 | 
			
		||||
	0xee, 0x1c, 0xa5, 0x2f, 0xcc, 0x3b, 0x0b, 0x7b, 0x71, 0x38, 0x23, 0xf7, 0x23, 0x2e, 0xa2, 0x4b,
 | 
			
		||||
	0xfd, 0x98, 0x8d, 0x97, 0x13, 0xfc, 0x1f, 0x5b, 0x2f, 0x76, 0xbf, 0x3b, 0x00, 0x45, 0x1f, 0x7a,
 | 
			
		||||
	0x02, 0xfa, 0x25, 0xc8, 0x1c, 0xca, 0xac, 0x0f, 0xa8, 0xb5, 0xc6, 0x96, 0xad, 0x25, 0x9b, 0x79,
 | 
			
		||||
	0xd9, 0x7a, 0x71, 0x00, 0x6d, 0xfd, 0x36, 0x15, 0xfb, 0x68, 0x17, 0x5d, 0x27, 0xf3, 0x6d, 0xdc,
 | 
			
		||||
	0x87, 0xd6, 0x82, 0x2a, 0x16, 0x90, 0x39, 0x57, 0x41, 0xec, 0xdb, 0xeb, 0xda, 0x34, 0xb9, 0x91,
 | 
			
		||||
	0x49, 0xe9, 0xb7, 0xcd, 0x30, 0xb5, 0x8f, 0x53, 0x1a, 0x98, 0x9f, 0xeb, 0xd3, 0x8d, 0x77, 0x66,
 | 
			
		||||
	0x7d, 0xdb, 0x7a, 0x2d, 0x6e, 0xb9, 0xe1, 0x7f, 0xf8, 0xd9, 0x81, 0xdd, 0xfb, 0x9d, 0x40, 0x1e,
 | 
			
		||||
	0xfc, 0x83, 0x5b, 0x9d, 0x0d, 0xf4, 0x0c, 0x8e, 0xff, 0x84, 0x7f, 0x3d, 0x51, 0x3c, 0xc9, 0x5b,
 | 
			
		||||
	0x9c, 0x37, 0x95, 0xb7, 0xce, 0x27, 0x67, 0xe3, 0x57, 0x00, 0x00, 0x00, 0xff, 0xff, 0xa3, 0x9c,
 | 
			
		||||
	0xf1, 0x49, 0x52, 0x06, 0x00, 0x00,
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										669
									
								
								vendor/github.com/Philipp15b/go-steam/protocol/steamlang/enums.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										669
									
								
								vendor/github.com/Philipp15b/go-steam/protocol/steamlang/enums.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -400,6 +400,7 @@ const (
 | 
			
		||||
	EMsg_FBSBootstrapperGetPackageChunkResponse                   EMsg = 1131
 | 
			
		||||
	EMsg_FBSBootstrapperPackageTransferProgress                   EMsg = 1132
 | 
			
		||||
	EMsg_FBSRestartBootstrapper                                   EMsg = 1133
 | 
			
		||||
	EMsg_FBSPauseFrozenDumps                                      EMsg = 1134
 | 
			
		||||
	EMsg_BaseFileXfer                                             EMsg = 1200
 | 
			
		||||
	EMsg_FileXferRequest                                          EMsg = 1200
 | 
			
		||||
	EMsg_FileXferResponse                                         EMsg = 1201
 | 
			
		||||
@@ -416,6 +417,8 @@ const (
 | 
			
		||||
	EMsg_BaseBS                                                   EMsg = 1400
 | 
			
		||||
	EMsg_BSPurchaseStart                                          EMsg = 1401
 | 
			
		||||
	EMsg_BSPurchaseResponse                                       EMsg = 1402
 | 
			
		||||
	EMsg_BSAuthenticateCCTrans                                    EMsg = 1403
 | 
			
		||||
	EMsg_BSAuthenticateCCTransResponse                            EMsg = 1404
 | 
			
		||||
	EMsg_BSSettleComplete                                         EMsg = 1406
 | 
			
		||||
	EMsg_BSInitPayPalTxn                                          EMsg = 1408
 | 
			
		||||
	EMsg_BSInitPayPalTxnResponse                                  EMsg = 1409
 | 
			
		||||
@@ -979,6 +982,8 @@ const (
 | 
			
		||||
	EMsg_AMFundedPayment                                          EMsg = 4418
 | 
			
		||||
	EMsg_AMFundedPaymentResponse                                  EMsg = 4419
 | 
			
		||||
	EMsg_AMRequestPersonaUpdateForChatServer                      EMsg = 4420
 | 
			
		||||
	EMsg_AMPerfectWorldPayment                                    EMsg = 4421
 | 
			
		||||
	EMsg_AMPerfectWorldPaymentResponse                            EMsg = 4422
 | 
			
		||||
	EMsg_BasePSRange                                              EMsg = 5000
 | 
			
		||||
	EMsg_PSCreateShoppingCart                                     EMsg = 5001
 | 
			
		||||
	EMsg_PSCreateShoppingCartResponse                             EMsg = 5002
 | 
			
		||||
@@ -1238,6 +1243,9 @@ const (
 | 
			
		||||
	EMsg_ClientNetworkingCertRequestResponse                      EMsg = 5622
 | 
			
		||||
	EMsg_ClientChallengeRequest                                   EMsg = 5623
 | 
			
		||||
	EMsg_ClientChallengeResponse                                  EMsg = 5624
 | 
			
		||||
	EMsg_BadgeCraftedNotification                                 EMsg = 5625
 | 
			
		||||
	EMsg_ClientNetworkingMobileCertRequest                        EMsg = 5626
 | 
			
		||||
	EMsg_ClientNetworkingMobileCertRequestResponse                EMsg = 5627
 | 
			
		||||
	EMsg_BaseMDS                                                  EMsg = 5800
 | 
			
		||||
	EMsg_AMToMDSGetDepotDecryptionKey                             EMsg = 5812
 | 
			
		||||
	EMsg_MDSToAMGetDepotDecryptionKeyResponse                     EMsg = 5813
 | 
			
		||||
@@ -1303,6 +1311,8 @@ const (
 | 
			
		||||
	EMsg_ClientMMSSetRatelimitPolicyOnClient                      EMsg = 6625
 | 
			
		||||
	EMsg_ClientMMSGetLobbyStatus                                  EMsg = 6626
 | 
			
		||||
	EMsg_ClientMMSGetLobbyStatusResponse                          EMsg = 6627
 | 
			
		||||
	EMsg_MMSGetLobbyList                                          EMsg = 6628
 | 
			
		||||
	EMsg_MMSGetLobbyListResponse                                  EMsg = 6629
 | 
			
		||||
	EMsg_NonStdMsgBase                                            EMsg = 6800
 | 
			
		||||
	EMsg_NonStdMsgMemcached                                       EMsg = 6801
 | 
			
		||||
	EMsg_NonStdMsgHTTPServer                                      EMsg = 6802
 | 
			
		||||
@@ -1318,6 +1328,7 @@ const (
 | 
			
		||||
	EMsg_NonStdMsgSteam2Emulator                                  EMsg = 6812
 | 
			
		||||
	EMsg_NonStdMsgRTMPServer                                      EMsg = 6813
 | 
			
		||||
	EMsg_NonStdMsgWebSocket                                       EMsg = 6814
 | 
			
		||||
	EMsg_NonStdMsgRedis                                           EMsg = 6815
 | 
			
		||||
	EMsg_UDSBase                                                  EMsg = 7000
 | 
			
		||||
	EMsg_ClientUDSP2PSessionStarted                               EMsg = 7001
 | 
			
		||||
	EMsg_ClientUDSP2PSessionEnded                                 EMsg = 7002
 | 
			
		||||
@@ -2072,6 +2083,7 @@ var EMsg_name = map[EMsg]string{
 | 
			
		||||
	1131:  "EMsg_FBSBootstrapperGetPackageChunkResponse",
 | 
			
		||||
	1132:  "EMsg_FBSBootstrapperPackageTransferProgress",
 | 
			
		||||
	1133:  "EMsg_FBSRestartBootstrapper",
 | 
			
		||||
	1134:  "EMsg_FBSPauseFrozenDumps",
 | 
			
		||||
	1200:  "EMsg_BaseFileXfer",
 | 
			
		||||
	1201:  "EMsg_FileXferResponse",
 | 
			
		||||
	1202:  "EMsg_FileXferData",
 | 
			
		||||
@@ -2086,7 +2098,8 @@ var EMsg_name = map[EMsg]string{
 | 
			
		||||
	1400:  "EMsg_BaseBS",
 | 
			
		||||
	1401:  "EMsg_BSPurchaseStart",
 | 
			
		||||
	1402:  "EMsg_BSPurchaseResponse",
 | 
			
		||||
	1404:  "EMsg_BSSettleNOVA",
 | 
			
		||||
	1403:  "EMsg_BSAuthenticateCCTrans",
 | 
			
		||||
	1404:  "EMsg_BSAuthenticateCCTransResponse",
 | 
			
		||||
	1406:  "EMsg_BSSettleComplete",
 | 
			
		||||
	1407:  "EMsg_BSBannedRequest",
 | 
			
		||||
	1408:  "EMsg_BSInitPayPalTxn",
 | 
			
		||||
@@ -2772,6 +2785,8 @@ var EMsg_name = map[EMsg]string{
 | 
			
		||||
	4418:  "EMsg_AMFundedPayment",
 | 
			
		||||
	4419:  "EMsg_AMFundedPaymentResponse",
 | 
			
		||||
	4420:  "EMsg_AMRequestPersonaUpdateForChatServer",
 | 
			
		||||
	4421:  "EMsg_AMPerfectWorldPayment",
 | 
			
		||||
	4422:  "EMsg_AMPerfectWorldPaymentResponse",
 | 
			
		||||
	5000:  "EMsg_BasePSRange",
 | 
			
		||||
	5001:  "EMsg_PSCreateShoppingCart",
 | 
			
		||||
	5002:  "EMsg_PSCreateShoppingCartResponse",
 | 
			
		||||
@@ -3041,6 +3056,9 @@ var EMsg_name = map[EMsg]string{
 | 
			
		||||
	5622:  "EMsg_ClientNetworkingCertRequestResponse",
 | 
			
		||||
	5623:  "EMsg_ClientChallengeRequest",
 | 
			
		||||
	5624:  "EMsg_ClientChallengeResponse",
 | 
			
		||||
	5625:  "EMsg_BadgeCraftedNotification",
 | 
			
		||||
	5626:  "EMsg_ClientNetworkingMobileCertRequest",
 | 
			
		||||
	5627:  "EMsg_ClientNetworkingMobileCertRequestResponse",
 | 
			
		||||
	5800:  "EMsg_BaseMDS",
 | 
			
		||||
	5801:  "EMsg_ClientMDSLoginRequest",
 | 
			
		||||
	5802:  "EMsg_ClientMDSLoginResponse",
 | 
			
		||||
@@ -3136,6 +3154,8 @@ var EMsg_name = map[EMsg]string{
 | 
			
		||||
	6625:  "EMsg_ClientMMSSetRatelimitPolicyOnClient",
 | 
			
		||||
	6626:  "EMsg_ClientMMSGetLobbyStatus",
 | 
			
		||||
	6627:  "EMsg_ClientMMSGetLobbyStatusResponse",
 | 
			
		||||
	6628:  "EMsg_MMSGetLobbyList",
 | 
			
		||||
	6629:  "EMsg_MMSGetLobbyListResponse",
 | 
			
		||||
	6800:  "EMsg_NonStdMsgBase",
 | 
			
		||||
	6801:  "EMsg_NonStdMsgMemcached",
 | 
			
		||||
	6802:  "EMsg_NonStdMsgHTTPServer",
 | 
			
		||||
@@ -3151,6 +3171,7 @@ var EMsg_name = map[EMsg]string{
 | 
			
		||||
	6812:  "EMsg_NonStdMsgSteam2Emulator",
 | 
			
		||||
	6813:  "EMsg_NonStdMsgRTMPServer",
 | 
			
		||||
	6814:  "EMsg_NonStdMsgWebSocket",
 | 
			
		||||
	6815:  "EMsg_NonStdMsgRedis",
 | 
			
		||||
	7000:  "EMsg_UDSBase",
 | 
			
		||||
	7001:  "EMsg_ClientUDSP2PSessionStarted",
 | 
			
		||||
	7002:  "EMsg_ClientUDSP2PSessionEnded",
 | 
			
		||||
@@ -3487,119 +3508,122 @@ func (e EMsg) String() string {
 | 
			
		||||
type EResult int32
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	EResult_Invalid                                 EResult = 0
 | 
			
		||||
	EResult_OK                                      EResult = 1
 | 
			
		||||
	EResult_Fail                                    EResult = 2
 | 
			
		||||
	EResult_NoConnection                            EResult = 3
 | 
			
		||||
	EResult_InvalidPassword                         EResult = 5
 | 
			
		||||
	EResult_LoggedInElsewhere                       EResult = 6
 | 
			
		||||
	EResult_InvalidProtocolVer                      EResult = 7
 | 
			
		||||
	EResult_InvalidParam                            EResult = 8
 | 
			
		||||
	EResult_FileNotFound                            EResult = 9
 | 
			
		||||
	EResult_Busy                                    EResult = 10
 | 
			
		||||
	EResult_InvalidState                            EResult = 11
 | 
			
		||||
	EResult_InvalidName                             EResult = 12
 | 
			
		||||
	EResult_InvalidEmail                            EResult = 13
 | 
			
		||||
	EResult_DuplicateName                           EResult = 14
 | 
			
		||||
	EResult_AccessDenied                            EResult = 15
 | 
			
		||||
	EResult_Timeout                                 EResult = 16
 | 
			
		||||
	EResult_Banned                                  EResult = 17
 | 
			
		||||
	EResult_AccountNotFound                         EResult = 18
 | 
			
		||||
	EResult_InvalidSteamID                          EResult = 19
 | 
			
		||||
	EResult_ServiceUnavailable                      EResult = 20
 | 
			
		||||
	EResult_NotLoggedOn                             EResult = 21
 | 
			
		||||
	EResult_Pending                                 EResult = 22
 | 
			
		||||
	EResult_EncryptionFailure                       EResult = 23
 | 
			
		||||
	EResult_InsufficientPrivilege                   EResult = 24
 | 
			
		||||
	EResult_LimitExceeded                           EResult = 25
 | 
			
		||||
	EResult_Revoked                                 EResult = 26
 | 
			
		||||
	EResult_Expired                                 EResult = 27
 | 
			
		||||
	EResult_AlreadyRedeemed                         EResult = 28
 | 
			
		||||
	EResult_DuplicateRequest                        EResult = 29
 | 
			
		||||
	EResult_AlreadyOwned                            EResult = 30
 | 
			
		||||
	EResult_IPNotFound                              EResult = 31
 | 
			
		||||
	EResult_PersistFailed                           EResult = 32
 | 
			
		||||
	EResult_LockingFailed                           EResult = 33
 | 
			
		||||
	EResult_LogonSessionReplaced                    EResult = 34
 | 
			
		||||
	EResult_ConnectFailed                           EResult = 35
 | 
			
		||||
	EResult_HandshakeFailed                         EResult = 36
 | 
			
		||||
	EResult_IOFailure                               EResult = 37
 | 
			
		||||
	EResult_RemoteDisconnect                        EResult = 38
 | 
			
		||||
	EResult_ShoppingCartNotFound                    EResult = 39
 | 
			
		||||
	EResult_Blocked                                 EResult = 40
 | 
			
		||||
	EResult_Ignored                                 EResult = 41
 | 
			
		||||
	EResult_NoMatch                                 EResult = 42
 | 
			
		||||
	EResult_AccountDisabled                         EResult = 43
 | 
			
		||||
	EResult_ServiceReadOnly                         EResult = 44
 | 
			
		||||
	EResult_AccountNotFeatured                      EResult = 45
 | 
			
		||||
	EResult_AdministratorOK                         EResult = 46
 | 
			
		||||
	EResult_ContentVersion                          EResult = 47
 | 
			
		||||
	EResult_TryAnotherCM                            EResult = 48
 | 
			
		||||
	EResult_PasswordRequiredToKickSession           EResult = 49
 | 
			
		||||
	EResult_AlreadyLoggedInElsewhere                EResult = 50
 | 
			
		||||
	EResult_Suspended                               EResult = 51
 | 
			
		||||
	EResult_Cancelled                               EResult = 52
 | 
			
		||||
	EResult_DataCorruption                          EResult = 53
 | 
			
		||||
	EResult_DiskFull                                EResult = 54
 | 
			
		||||
	EResult_RemoteCallFailed                        EResult = 55
 | 
			
		||||
	EResult_PasswordUnset                           EResult = 56
 | 
			
		||||
	EResult_ExternalAccountUnlinked                 EResult = 57
 | 
			
		||||
	EResult_PSNTicketInvalid                        EResult = 58
 | 
			
		||||
	EResult_ExternalAccountAlreadyLinked            EResult = 59
 | 
			
		||||
	EResult_RemoteFileConflict                      EResult = 60
 | 
			
		||||
	EResult_IllegalPassword                         EResult = 61
 | 
			
		||||
	EResult_SameAsPreviousValue                     EResult = 62
 | 
			
		||||
	EResult_AccountLogonDenied                      EResult = 63
 | 
			
		||||
	EResult_CannotUseOldPassword                    EResult = 64
 | 
			
		||||
	EResult_InvalidLoginAuthCode                    EResult = 65
 | 
			
		||||
	EResult_AccountLogonDeniedNoMail                EResult = 66
 | 
			
		||||
	EResult_HardwareNotCapableOfIPT                 EResult = 67
 | 
			
		||||
	EResult_IPTInitError                            EResult = 68
 | 
			
		||||
	EResult_ParentalControlRestricted               EResult = 69
 | 
			
		||||
	EResult_FacebookQueryError                      EResult = 70
 | 
			
		||||
	EResult_ExpiredLoginAuthCode                    EResult = 71
 | 
			
		||||
	EResult_IPLoginRestrictionFailed                EResult = 72
 | 
			
		||||
	EResult_AccountLockedDown                       EResult = 73
 | 
			
		||||
	EResult_AccountLogonDeniedVerifiedEmailRequired EResult = 74
 | 
			
		||||
	EResult_NoMatchingURL                           EResult = 75
 | 
			
		||||
	EResult_BadResponse                             EResult = 76
 | 
			
		||||
	EResult_RequirePasswordReEntry                  EResult = 77
 | 
			
		||||
	EResult_ValueOutOfRange                         EResult = 78
 | 
			
		||||
	EResult_UnexpectedError                         EResult = 79
 | 
			
		||||
	EResult_Disabled                                EResult = 80
 | 
			
		||||
	EResult_InvalidCEGSubmission                    EResult = 81
 | 
			
		||||
	EResult_RestrictedDevice                        EResult = 82
 | 
			
		||||
	EResult_RegionLocked                            EResult = 83
 | 
			
		||||
	EResult_RateLimitExceeded                       EResult = 84
 | 
			
		||||
	EResult_AccountLoginDeniedNeedTwoFactor         EResult = 85
 | 
			
		||||
	EResult_ItemDeleted                             EResult = 86
 | 
			
		||||
	EResult_AccountLoginDeniedThrottle              EResult = 87
 | 
			
		||||
	EResult_TwoFactorCodeMismatch                   EResult = 88
 | 
			
		||||
	EResult_TwoFactorActivationCodeMismatch         EResult = 89
 | 
			
		||||
	EResult_AccountAssociatedToMultiplePartners     EResult = 90
 | 
			
		||||
	EResult_NotModified                             EResult = 91
 | 
			
		||||
	EResult_NoMobileDevice                          EResult = 92
 | 
			
		||||
	EResult_TimeNotSynced                           EResult = 93
 | 
			
		||||
	EResult_SMSCodeFailed                           EResult = 94
 | 
			
		||||
	EResult_AccountLimitExceeded                    EResult = 95
 | 
			
		||||
	EResult_AccountActivityLimitExceeded            EResult = 96
 | 
			
		||||
	EResult_PhoneActivityLimitExceeded              EResult = 97
 | 
			
		||||
	EResult_RefundToWallet                          EResult = 98
 | 
			
		||||
	EResult_EmailSendFailure                        EResult = 99
 | 
			
		||||
	EResult_NotSettled                              EResult = 100
 | 
			
		||||
	EResult_NeedCaptcha                             EResult = 101
 | 
			
		||||
	EResult_GSLTDenied                              EResult = 102
 | 
			
		||||
	EResult_GSOwnerDenied                           EResult = 103
 | 
			
		||||
	EResult_InvalidItemType                         EResult = 104
 | 
			
		||||
	EResult_IPBanned                                EResult = 105
 | 
			
		||||
	EResult_GSLTExpired                             EResult = 106
 | 
			
		||||
	EResult_InsufficientFunds                       EResult = 107
 | 
			
		||||
	EResult_TooManyPending                          EResult = 108
 | 
			
		||||
	EResult_NoSiteLicensesFound                     EResult = 109
 | 
			
		||||
	EResult_WGNetworkSendExceeded                   EResult = 110
 | 
			
		||||
	EResult_AccountNotFriends                       EResult = 111
 | 
			
		||||
	EResult_LimitedUserAccount                      EResult = 112
 | 
			
		||||
	EResult_CantRemoveItem                          EResult = 113
 | 
			
		||||
	EResult_Invalid                                  EResult = 0
 | 
			
		||||
	EResult_OK                                       EResult = 1
 | 
			
		||||
	EResult_Fail                                     EResult = 2
 | 
			
		||||
	EResult_NoConnection                             EResult = 3
 | 
			
		||||
	EResult_InvalidPassword                          EResult = 5
 | 
			
		||||
	EResult_LoggedInElsewhere                        EResult = 6
 | 
			
		||||
	EResult_InvalidProtocolVer                       EResult = 7
 | 
			
		||||
	EResult_InvalidParam                             EResult = 8
 | 
			
		||||
	EResult_FileNotFound                             EResult = 9
 | 
			
		||||
	EResult_Busy                                     EResult = 10
 | 
			
		||||
	EResult_InvalidState                             EResult = 11
 | 
			
		||||
	EResult_InvalidName                              EResult = 12
 | 
			
		||||
	EResult_InvalidEmail                             EResult = 13
 | 
			
		||||
	EResult_DuplicateName                            EResult = 14
 | 
			
		||||
	EResult_AccessDenied                             EResult = 15
 | 
			
		||||
	EResult_Timeout                                  EResult = 16
 | 
			
		||||
	EResult_Banned                                   EResult = 17
 | 
			
		||||
	EResult_AccountNotFound                          EResult = 18
 | 
			
		||||
	EResult_InvalidSteamID                           EResult = 19
 | 
			
		||||
	EResult_ServiceUnavailable                       EResult = 20
 | 
			
		||||
	EResult_NotLoggedOn                              EResult = 21
 | 
			
		||||
	EResult_Pending                                  EResult = 22
 | 
			
		||||
	EResult_EncryptionFailure                        EResult = 23
 | 
			
		||||
	EResult_InsufficientPrivilege                    EResult = 24
 | 
			
		||||
	EResult_LimitExceeded                            EResult = 25
 | 
			
		||||
	EResult_Revoked                                  EResult = 26
 | 
			
		||||
	EResult_Expired                                  EResult = 27
 | 
			
		||||
	EResult_AlreadyRedeemed                          EResult = 28
 | 
			
		||||
	EResult_DuplicateRequest                         EResult = 29
 | 
			
		||||
	EResult_AlreadyOwned                             EResult = 30
 | 
			
		||||
	EResult_IPNotFound                               EResult = 31
 | 
			
		||||
	EResult_PersistFailed                            EResult = 32
 | 
			
		||||
	EResult_LockingFailed                            EResult = 33
 | 
			
		||||
	EResult_LogonSessionReplaced                     EResult = 34
 | 
			
		||||
	EResult_ConnectFailed                            EResult = 35
 | 
			
		||||
	EResult_HandshakeFailed                          EResult = 36
 | 
			
		||||
	EResult_IOFailure                                EResult = 37
 | 
			
		||||
	EResult_RemoteDisconnect                         EResult = 38
 | 
			
		||||
	EResult_ShoppingCartNotFound                     EResult = 39
 | 
			
		||||
	EResult_Blocked                                  EResult = 40
 | 
			
		||||
	EResult_Ignored                                  EResult = 41
 | 
			
		||||
	EResult_NoMatch                                  EResult = 42
 | 
			
		||||
	EResult_AccountDisabled                          EResult = 43
 | 
			
		||||
	EResult_ServiceReadOnly                          EResult = 44
 | 
			
		||||
	EResult_AccountNotFeatured                       EResult = 45
 | 
			
		||||
	EResult_AdministratorOK                          EResult = 46
 | 
			
		||||
	EResult_ContentVersion                           EResult = 47
 | 
			
		||||
	EResult_TryAnotherCM                             EResult = 48
 | 
			
		||||
	EResult_PasswordRequiredToKickSession            EResult = 49
 | 
			
		||||
	EResult_AlreadyLoggedInElsewhere                 EResult = 50
 | 
			
		||||
	EResult_Suspended                                EResult = 51
 | 
			
		||||
	EResult_Cancelled                                EResult = 52
 | 
			
		||||
	EResult_DataCorruption                           EResult = 53
 | 
			
		||||
	EResult_DiskFull                                 EResult = 54
 | 
			
		||||
	EResult_RemoteCallFailed                         EResult = 55
 | 
			
		||||
	EResult_PasswordUnset                            EResult = 56
 | 
			
		||||
	EResult_ExternalAccountUnlinked                  EResult = 57
 | 
			
		||||
	EResult_PSNTicketInvalid                         EResult = 58
 | 
			
		||||
	EResult_ExternalAccountAlreadyLinked             EResult = 59
 | 
			
		||||
	EResult_RemoteFileConflict                       EResult = 60
 | 
			
		||||
	EResult_IllegalPassword                          EResult = 61
 | 
			
		||||
	EResult_SameAsPreviousValue                      EResult = 62
 | 
			
		||||
	EResult_AccountLogonDenied                       EResult = 63
 | 
			
		||||
	EResult_CannotUseOldPassword                     EResult = 64
 | 
			
		||||
	EResult_InvalidLoginAuthCode                     EResult = 65
 | 
			
		||||
	EResult_AccountLogonDeniedNoMail                 EResult = 66
 | 
			
		||||
	EResult_HardwareNotCapableOfIPT                  EResult = 67
 | 
			
		||||
	EResult_IPTInitError                             EResult = 68
 | 
			
		||||
	EResult_ParentalControlRestricted                EResult = 69
 | 
			
		||||
	EResult_FacebookQueryError                       EResult = 70
 | 
			
		||||
	EResult_ExpiredLoginAuthCode                     EResult = 71
 | 
			
		||||
	EResult_IPLoginRestrictionFailed                 EResult = 72
 | 
			
		||||
	EResult_AccountLockedDown                        EResult = 73
 | 
			
		||||
	EResult_AccountLogonDeniedVerifiedEmailRequired  EResult = 74
 | 
			
		||||
	EResult_NoMatchingURL                            EResult = 75
 | 
			
		||||
	EResult_BadResponse                              EResult = 76
 | 
			
		||||
	EResult_RequirePasswordReEntry                   EResult = 77
 | 
			
		||||
	EResult_ValueOutOfRange                          EResult = 78
 | 
			
		||||
	EResult_UnexpectedError                          EResult = 79
 | 
			
		||||
	EResult_Disabled                                 EResult = 80
 | 
			
		||||
	EResult_InvalidCEGSubmission                     EResult = 81
 | 
			
		||||
	EResult_RestrictedDevice                         EResult = 82
 | 
			
		||||
	EResult_RegionLocked                             EResult = 83
 | 
			
		||||
	EResult_RateLimitExceeded                        EResult = 84
 | 
			
		||||
	EResult_AccountLoginDeniedNeedTwoFactor          EResult = 85
 | 
			
		||||
	EResult_ItemDeleted                              EResult = 86
 | 
			
		||||
	EResult_AccountLoginDeniedThrottle               EResult = 87
 | 
			
		||||
	EResult_TwoFactorCodeMismatch                    EResult = 88
 | 
			
		||||
	EResult_TwoFactorActivationCodeMismatch          EResult = 89
 | 
			
		||||
	EResult_AccountAssociatedToMultiplePartners      EResult = 90
 | 
			
		||||
	EResult_NotModified                              EResult = 91
 | 
			
		||||
	EResult_NoMobileDevice                           EResult = 92
 | 
			
		||||
	EResult_TimeNotSynced                            EResult = 93
 | 
			
		||||
	EResult_SMSCodeFailed                            EResult = 94
 | 
			
		||||
	EResult_AccountLimitExceeded                     EResult = 95
 | 
			
		||||
	EResult_AccountActivityLimitExceeded             EResult = 96
 | 
			
		||||
	EResult_PhoneActivityLimitExceeded               EResult = 97
 | 
			
		||||
	EResult_RefundToWallet                           EResult = 98
 | 
			
		||||
	EResult_EmailSendFailure                         EResult = 99
 | 
			
		||||
	EResult_NotSettled                               EResult = 100
 | 
			
		||||
	EResult_NeedCaptcha                              EResult = 101
 | 
			
		||||
	EResult_GSLTDenied                               EResult = 102
 | 
			
		||||
	EResult_GSOwnerDenied                            EResult = 103
 | 
			
		||||
	EResult_InvalidItemType                          EResult = 104
 | 
			
		||||
	EResult_IPBanned                                 EResult = 105
 | 
			
		||||
	EResult_GSLTExpired                              EResult = 106
 | 
			
		||||
	EResult_InsufficientFunds                        EResult = 107
 | 
			
		||||
	EResult_TooManyPending                           EResult = 108
 | 
			
		||||
	EResult_NoSiteLicensesFound                      EResult = 109
 | 
			
		||||
	EResult_WGNetworkSendExceeded                    EResult = 110
 | 
			
		||||
	EResult_AccountNotFriends                        EResult = 111
 | 
			
		||||
	EResult_LimitedUserAccount                       EResult = 112
 | 
			
		||||
	EResult_CantRemoveItem                           EResult = 113
 | 
			
		||||
	EResult_AccountHasBeenDeleted                    EResult = 114
 | 
			
		||||
	EResult_AccountHasAnExistingUserCancelledLicense EResult = 115
 | 
			
		||||
	EResult_DeniedDueToCommunityCooldown             EResult = 116
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var EResult_name = map[EResult]string{
 | 
			
		||||
@@ -3716,6 +3740,9 @@ var EResult_name = map[EResult]string{
 | 
			
		||||
	111: "EResult_AccountNotFriends",
 | 
			
		||||
	112: "EResult_LimitedUserAccount",
 | 
			
		||||
	113: "EResult_CantRemoveItem",
 | 
			
		||||
	114: "EResult_AccountHasBeenDeleted",
 | 
			
		||||
	115: "EResult_AccountHasAnExistingUserCancelledLicense",
 | 
			
		||||
	116: "EResult_DeniedDueToCommunityCooldown",
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (e EResult) String() string {
 | 
			
		||||
@@ -3743,7 +3770,6 @@ const (
 | 
			
		||||
	EUniverse_Beta     EUniverse = 2
 | 
			
		||||
	EUniverse_Internal EUniverse = 3
 | 
			
		||||
	EUniverse_Dev      EUniverse = 4
 | 
			
		||||
	EUniverse_Max      EUniverse = 5
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var EUniverse_name = map[EUniverse]string{
 | 
			
		||||
@@ -3752,7 +3778,6 @@ var EUniverse_name = map[EUniverse]string{
 | 
			
		||||
	2: "EUniverse_Beta",
 | 
			
		||||
	3: "EUniverse_Internal",
 | 
			
		||||
	4: "EUniverse_Dev",
 | 
			
		||||
	5: "EUniverse_Max",
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (e EUniverse) String() string {
 | 
			
		||||
@@ -3836,7 +3861,6 @@ const (
 | 
			
		||||
	EPersonaState_LookingToTrade EPersonaState = 5
 | 
			
		||||
	EPersonaState_LookingToPlay  EPersonaState = 6
 | 
			
		||||
	EPersonaState_Invisible      EPersonaState = 7
 | 
			
		||||
	EPersonaState_Max            EPersonaState = 8
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var EPersonaState_name = map[EPersonaState]string{
 | 
			
		||||
@@ -3848,7 +3872,6 @@ var EPersonaState_name = map[EPersonaState]string{
 | 
			
		||||
	5: "EPersonaState_LookingToTrade",
 | 
			
		||||
	6: "EPersonaState_LookingToPlay",
 | 
			
		||||
	7: "EPersonaState_Invisible",
 | 
			
		||||
	8: "EPersonaState_Max",
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (e EPersonaState) String() string {
 | 
			
		||||
@@ -3882,7 +3905,6 @@ const (
 | 
			
		||||
	EAccountType_Chat           EAccountType = 8
 | 
			
		||||
	EAccountType_ConsoleUser    EAccountType = 9
 | 
			
		||||
	EAccountType_AnonUser       EAccountType = 10
 | 
			
		||||
	EAccountType_Max            EAccountType = 11
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var EAccountType_name = map[EAccountType]string{
 | 
			
		||||
@@ -3897,7 +3919,6 @@ var EAccountType_name = map[EAccountType]string{
 | 
			
		||||
	8:  "EAccountType_Chat",
 | 
			
		||||
	9:  "EAccountType_ConsoleUser",
 | 
			
		||||
	10: "EAccountType_AnonUser",
 | 
			
		||||
	11: "EAccountType_Max",
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (e EAccountType) String() string {
 | 
			
		||||
@@ -3927,7 +3948,6 @@ const (
 | 
			
		||||
	EFriendRelationship_RequestInitiator EFriendRelationship = 4
 | 
			
		||||
	EFriendRelationship_Ignored          EFriendRelationship = 5
 | 
			
		||||
	EFriendRelationship_IgnoredFriend    EFriendRelationship = 6
 | 
			
		||||
	EFriendRelationship_Max              EFriendRelationship = 8
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var EFriendRelationship_name = map[EFriendRelationship]string{
 | 
			
		||||
@@ -3939,7 +3959,6 @@ var EFriendRelationship_name = map[EFriendRelationship]string{
 | 
			
		||||
	5: "EFriendRelationship_Ignored",
 | 
			
		||||
	6: "EFriendRelationship_IgnoredFriend",
 | 
			
		||||
	7: "EFriendRelationship_SuggestedFriend",
 | 
			
		||||
	8: "EFriendRelationship_Max",
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (e EFriendRelationship) String() string {
 | 
			
		||||
@@ -4212,6 +4231,7 @@ const (
 | 
			
		||||
	EPersonaStateFlag_HasRichPresence      EPersonaStateFlag = 1
 | 
			
		||||
	EPersonaStateFlag_InJoinableGame       EPersonaStateFlag = 2
 | 
			
		||||
	EPersonaStateFlag_Golden               EPersonaStateFlag = 4
 | 
			
		||||
	EPersonaStateFlag_RemotePlayTogether   EPersonaStateFlag = 8
 | 
			
		||||
	EPersonaStateFlag_ClientTypeWeb        EPersonaStateFlag = 256
 | 
			
		||||
	EPersonaStateFlag_ClientTypeMobile     EPersonaStateFlag = 512
 | 
			
		||||
	EPersonaStateFlag_ClientTypeTenfoot    EPersonaStateFlag = 1024
 | 
			
		||||
@@ -4224,6 +4244,7 @@ var EPersonaStateFlag_name = map[EPersonaStateFlag]string{
 | 
			
		||||
	1:    "EPersonaStateFlag_HasRichPresence",
 | 
			
		||||
	2:    "EPersonaStateFlag_InJoinableGame",
 | 
			
		||||
	4:    "EPersonaStateFlag_Golden",
 | 
			
		||||
	8:    "EPersonaStateFlag_RemotePlayTogether",
 | 
			
		||||
	256:  "EPersonaStateFlag_OnlineUsingWeb",
 | 
			
		||||
	512:  "EPersonaStateFlag_OnlineUsingMobile",
 | 
			
		||||
	1024: "EPersonaStateFlag_OnlineUsingBigPicture",
 | 
			
		||||
@@ -4524,6 +4545,7 @@ const (
 | 
			
		||||
	EPaymentMethod_Valve                  EPaymentMethod = 129
 | 
			
		||||
	EPaymentMethod_MasterComp             EPaymentMethod = 130
 | 
			
		||||
	EPaymentMethod_Promotional            EPaymentMethod = 131
 | 
			
		||||
	EPaymentMethod_MasterSubscription     EPaymentMethod = 134
 | 
			
		||||
	EPaymentMethod_OEMTicket              EPaymentMethod = 256
 | 
			
		||||
	EPaymentMethod_Split                  EPaymentMethod = 512
 | 
			
		||||
	EPaymentMethod_Complimentary          EPaymentMethod = 1024
 | 
			
		||||
@@ -4613,6 +4635,7 @@ var EPaymentMethod_name = map[EPaymentMethod]string{
 | 
			
		||||
	129:  "EPaymentMethod_Valve",
 | 
			
		||||
	130:  "EPaymentMethod_SteamPressMaster",
 | 
			
		||||
	131:  "EPaymentMethod_StorePromotion",
 | 
			
		||||
	134:  "EPaymentMethod_MasterSubscription",
 | 
			
		||||
	256:  "EPaymentMethod_OEMTicket",
 | 
			
		||||
	512:  "EPaymentMethod_Split",
 | 
			
		||||
	1024: "EPaymentMethod_Complimentary",
 | 
			
		||||
@@ -4706,6 +4729,22 @@ const (
 | 
			
		||||
	EPurchaseResultDetail_PurchaseCannotBeReplayed                EPurchaseResultDetail = 65
 | 
			
		||||
	EPurchaseResultDetail_DelayedCompletion                       EPurchaseResultDetail = 66
 | 
			
		||||
	EPurchaseResultDetail_BundleTypeCannotBeGifted                EPurchaseResultDetail = 67
 | 
			
		||||
	EPurchaseResultDetail_BlockedByUSGov                          EPurchaseResultDetail = 68
 | 
			
		||||
	EPurchaseResultDetail_ItemsReservedForCommercialUse           EPurchaseResultDetail = 69
 | 
			
		||||
	EPurchaseResultDetail_GiftAlreadyOwned                        EPurchaseResultDetail = 70
 | 
			
		||||
	EPurchaseResultDetail_GiftInvalidForRecipientRegion           EPurchaseResultDetail = 71
 | 
			
		||||
	EPurchaseResultDetail_GiftPricingImbalance                    EPurchaseResultDetail = 72
 | 
			
		||||
	EPurchaseResultDetail_GiftRecipientNotSpecified               EPurchaseResultDetail = 73
 | 
			
		||||
	EPurchaseResultDetail_ItemsNotAllowedForCommercialUse         EPurchaseResultDetail = 74
 | 
			
		||||
	EPurchaseResultDetail_BusinessStoreCountryCodeMismatch        EPurchaseResultDetail = 75
 | 
			
		||||
	EPurchaseResultDetail_UserAssociatedWithManyCafes             EPurchaseResultDetail = 76
 | 
			
		||||
	EPurchaseResultDetail_UserNotAssociatedWithCafe               EPurchaseResultDetail = 77
 | 
			
		||||
	EPurchaseResultDetail_AddressInvalid                          EPurchaseResultDetail = 78
 | 
			
		||||
	EPurchaseResultDetail_CreditCardNumberInvalid                 EPurchaseResultDetail = 79
 | 
			
		||||
	EPurchaseResultDetail_CannotShipToMilitaryPostOffice          EPurchaseResultDetail = 80
 | 
			
		||||
	EPurchaseResultDetail_BillingNameInvalidResemblesCreditCard   EPurchaseResultDetail = 81
 | 
			
		||||
	EPurchaseResultDetail_PaymentMethodTemporarilyUnavailable     EPurchaseResultDetail = 82
 | 
			
		||||
	EPurchaseResultDetail_PaymentMethodNotSupportedForProduct     EPurchaseResultDetail = 83
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var EPurchaseResultDetail_name = map[EPurchaseResultDetail]string{
 | 
			
		||||
@@ -4777,6 +4816,22 @@ var EPurchaseResultDetail_name = map[EPurchaseResultDetail]string{
 | 
			
		||||
	65: "EPurchaseResultDetail_PurchaseCannotBeReplayed",
 | 
			
		||||
	66: "EPurchaseResultDetail_DelayedCompletion",
 | 
			
		||||
	67: "EPurchaseResultDetail_BundleTypeCannotBeGifted",
 | 
			
		||||
	68: "EPurchaseResultDetail_BlockedByUSGov",
 | 
			
		||||
	69: "EPurchaseResultDetail_ItemsReservedForCommercialUse",
 | 
			
		||||
	70: "EPurchaseResultDetail_GiftAlreadyOwned",
 | 
			
		||||
	71: "EPurchaseResultDetail_GiftInvalidForRecipientRegion",
 | 
			
		||||
	72: "EPurchaseResultDetail_GiftPricingImbalance",
 | 
			
		||||
	73: "EPurchaseResultDetail_GiftRecipientNotSpecified",
 | 
			
		||||
	74: "EPurchaseResultDetail_ItemsNotAllowedForCommercialUse",
 | 
			
		||||
	75: "EPurchaseResultDetail_BusinessStoreCountryCodeMismatch",
 | 
			
		||||
	76: "EPurchaseResultDetail_UserAssociatedWithManyCafes",
 | 
			
		||||
	77: "EPurchaseResultDetail_UserNotAssociatedWithCafe",
 | 
			
		||||
	78: "EPurchaseResultDetail_AddressInvalid",
 | 
			
		||||
	79: "EPurchaseResultDetail_CreditCardNumberInvalid",
 | 
			
		||||
	80: "EPurchaseResultDetail_CannotShipToMilitaryPostOffice",
 | 
			
		||||
	81: "EPurchaseResultDetail_BillingNameInvalidResemblesCreditCard",
 | 
			
		||||
	82: "EPurchaseResultDetail_PaymentMethodTemporarilyUnavailable",
 | 
			
		||||
	83: "EPurchaseResultDetail_PaymentMethodNotSupportedForProduct",
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (e EPurchaseResultDetail) String() string {
 | 
			
		||||
@@ -5275,7 +5330,8 @@ const (
 | 
			
		||||
	EAppInfoSection_Store             EAppInfoSection = 16
 | 
			
		||||
	EAppInfoSection_Localization      EAppInfoSection = 17
 | 
			
		||||
	EAppInfoSection_Broadcastgamedata EAppInfoSection = 18
 | 
			
		||||
	EAppInfoSection_Max               EAppInfoSection = 19
 | 
			
		||||
	EAppInfoSection_Computed          EAppInfoSection = 19
 | 
			
		||||
	EAppInfoSection_Albummetadata     EAppInfoSection = 20
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var EAppInfoSection_name = map[EAppInfoSection]string{
 | 
			
		||||
@@ -5298,7 +5354,8 @@ var EAppInfoSection_name = map[EAppInfoSection]string{
 | 
			
		||||
	16: "EAppInfoSection_Store",
 | 
			
		||||
	17: "EAppInfoSection_Localization",
 | 
			
		||||
	18: "EAppInfoSection_Broadcastgamedata",
 | 
			
		||||
	19: "EAppInfoSection_Max",
 | 
			
		||||
	19: "EAppInfoSection_Computed",
 | 
			
		||||
	20: "EAppInfoSection_Albummetadata",
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (e EAppInfoSection) String() string {
 | 
			
		||||
@@ -5330,7 +5387,7 @@ const (
 | 
			
		||||
	EContentDownloadSourceType_SLS        EContentDownloadSourceType = 6
 | 
			
		||||
	EContentDownloadSourceType_SteamCache EContentDownloadSourceType = 7
 | 
			
		||||
	EContentDownloadSourceType_OpenCache  EContentDownloadSourceType = 8
 | 
			
		||||
	EContentDownloadSourceType_Max        EContentDownloadSourceType = 9
 | 
			
		||||
	EContentDownloadSourceType_LANCache   EContentDownloadSourceType = 9
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var EContentDownloadSourceType_name = map[EContentDownloadSourceType]string{
 | 
			
		||||
@@ -5343,7 +5400,7 @@ var EContentDownloadSourceType_name = map[EContentDownloadSourceType]string{
 | 
			
		||||
	6: "EContentDownloadSourceType_SLS",
 | 
			
		||||
	7: "EContentDownloadSourceType_SteamCache",
 | 
			
		||||
	8: "EContentDownloadSourceType_OpenCache",
 | 
			
		||||
	9: "EContentDownloadSourceType_Max",
 | 
			
		||||
	9: "EContentDownloadSourceType_LANCache",
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (e EContentDownloadSourceType) String() string {
 | 
			
		||||
@@ -5373,7 +5430,6 @@ const (
 | 
			
		||||
	EPlatformType_OSX     EPlatformType = 4
 | 
			
		||||
	EPlatformType_PS3     EPlatformType = 5
 | 
			
		||||
	EPlatformType_Linux32 EPlatformType = 6
 | 
			
		||||
	EPlatformType_Max     EPlatformType = 7
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var EPlatformType_name = map[EPlatformType]string{
 | 
			
		||||
@@ -5384,7 +5440,6 @@ var EPlatformType_name = map[EPlatformType]string{
 | 
			
		||||
	4: "EPlatformType_OSX",
 | 
			
		||||
	5: "EPlatformType_PS3",
 | 
			
		||||
	6: "EPlatformType_Linux32",
 | 
			
		||||
	7: "EPlatformType_Max",
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (e EPlatformType) String() string {
 | 
			
		||||
@@ -5462,6 +5517,7 @@ const (
 | 
			
		||||
	EOSType_MacOS1012      EOSType = -85
 | 
			
		||||
	EOSType_Macos1013      EOSType = -84
 | 
			
		||||
	EOSType_Macos1014      EOSType = -83
 | 
			
		||||
	EOSType_Macos1015      EOSType = -82
 | 
			
		||||
	EOSType_MacOSMax       EOSType = -1
 | 
			
		||||
	EOSType_LinuxUnknown   EOSType = -203
 | 
			
		||||
	EOSType_Linux22        EOSType = -202
 | 
			
		||||
@@ -5501,7 +5557,6 @@ const (
 | 
			
		||||
	EOSType_Windows10      EOSType = 16
 | 
			
		||||
	EOSType_Win2016        EOSType = 17
 | 
			
		||||
	EOSType_WinMAX         EOSType = 18
 | 
			
		||||
	EOSType_Max            EOSType = 26
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var EOSType_name = map[EOSType]string{
 | 
			
		||||
@@ -5560,6 +5615,7 @@ var EOSType_name = map[EOSType]string{
 | 
			
		||||
	-85:  "EOSType_MacOS1012",
 | 
			
		||||
	-84:  "EOSType_Macos1013",
 | 
			
		||||
	-83:  "EOSType_Macos1014",
 | 
			
		||||
	-82:  "EOSType_Macos1015",
 | 
			
		||||
	-203: "EOSType_LinuxUnknown",
 | 
			
		||||
	-202: "EOSType_Linux22",
 | 
			
		||||
	-201: "EOSType_Linux24",
 | 
			
		||||
@@ -5597,7 +5653,6 @@ var EOSType_name = map[EOSType]string{
 | 
			
		||||
	16:   "EOSType_Win10",
 | 
			
		||||
	17:   "EOSType_Win2016",
 | 
			
		||||
	18:   "EOSType_WinMAX",
 | 
			
		||||
	26:   "EOSType_Max",
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (e EOSType) String() string {
 | 
			
		||||
@@ -5734,7 +5789,19 @@ const (
 | 
			
		||||
	EServerType_TimeMachine         EServerType = 111
 | 
			
		||||
	EServerType_VACDBMaster         EServerType = 112
 | 
			
		||||
	EServerType_ContentServerConfig EServerType = 113
 | 
			
		||||
	EServerType_Max                 EServerType = 114
 | 
			
		||||
	EServerType_Minigame            EServerType = 114
 | 
			
		||||
	EServerType_MLTrain             EServerType = 115
 | 
			
		||||
	EServerType_VACTest             EServerType = 116
 | 
			
		||||
	EServerType_TaxService          EServerType = 117
 | 
			
		||||
	EServerType_MLInference         EServerType = 118
 | 
			
		||||
	EServerType_UGSAggregate        EServerType = 119
 | 
			
		||||
	EServerType_TURN                EServerType = 120
 | 
			
		||||
	EServerType_RemoteClient        EServerType = 121
 | 
			
		||||
	EServerType_BroadcastOrigin     EServerType = 122
 | 
			
		||||
	EServerType_BroadcastChannel    EServerType = 123
 | 
			
		||||
	EServerType_SteamAR             EServerType = 124
 | 
			
		||||
	EServerType_China               EServerType = 125
 | 
			
		||||
	EServerType_CrashDump           EServerType = 126
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var EServerType_name = map[EServerType]string{
 | 
			
		||||
@@ -5856,7 +5923,19 @@ var EServerType_name = map[EServerType]string{
 | 
			
		||||
	111: "EServerType_TimeMachine",
 | 
			
		||||
	112: "EServerType_VACDBMaster",
 | 
			
		||||
	113: "EServerType_ContentServerConfig",
 | 
			
		||||
	114: "EServerType_Max",
 | 
			
		||||
	114: "EServerType_Minigame",
 | 
			
		||||
	115: "EServerType_MLTrain",
 | 
			
		||||
	116: "EServerType_VACTest",
 | 
			
		||||
	117: "EServerType_TaxService",
 | 
			
		||||
	118: "EServerType_MLInference",
 | 
			
		||||
	119: "EServerType_UGSAggregate",
 | 
			
		||||
	120: "EServerType_TURN",
 | 
			
		||||
	121: "EServerType_RemoteClient",
 | 
			
		||||
	122: "EServerType_BroadcastOrigin",
 | 
			
		||||
	123: "EServerType_BroadcastChannel",
 | 
			
		||||
	124: "EServerType_SteamAR",
 | 
			
		||||
	125: "EServerType_China",
 | 
			
		||||
	126: "EServerType_CrashDump",
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (e EServerType) String() string {
 | 
			
		||||
@@ -6102,7 +6181,6 @@ const (
 | 
			
		||||
	ECurrencyCode_QAR     ECurrencyCode = 39
 | 
			
		||||
	ECurrencyCode_CRC     ECurrencyCode = 40
 | 
			
		||||
	ECurrencyCode_UYU     ECurrencyCode = 41
 | 
			
		||||
	ECurrencyCode_Max     ECurrencyCode = 42
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var ECurrencyCode_name = map[ECurrencyCode]string{
 | 
			
		||||
@@ -6147,7 +6225,6 @@ var ECurrencyCode_name = map[ECurrencyCode]string{
 | 
			
		||||
	39: "ECurrencyCode_QAR",
 | 
			
		||||
	40: "ECurrencyCode_CRC",
 | 
			
		||||
	41: "ECurrencyCode_UYU",
 | 
			
		||||
	42: "ECurrencyCode_Max",
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (e ECurrencyCode) String() string {
 | 
			
		||||
@@ -6302,7 +6379,6 @@ const (
 | 
			
		||||
	EWorkshopFileType_SteamworksAccessInvite EWorkshopFileType = 13
 | 
			
		||||
	EWorkshopFileType_SteamVideo             EWorkshopFileType = 14
 | 
			
		||||
	EWorkshopFileType_GameManagedItem        EWorkshopFileType = 15
 | 
			
		||||
	EWorkshopFileType_Max                    EWorkshopFileType = 16
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var EWorkshopFileType_name = map[EWorkshopFileType]string{
 | 
			
		||||
@@ -6322,7 +6398,6 @@ var EWorkshopFileType_name = map[EWorkshopFileType]string{
 | 
			
		||||
	13: "EWorkshopFileType_SteamworksAccessInvite",
 | 
			
		||||
	14: "EWorkshopFileType_SteamVideo",
 | 
			
		||||
	15: "EWorkshopFileType_GameManagedItem",
 | 
			
		||||
	16: "EWorkshopFileType_Max",
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (e EWorkshopFileType) String() string {
 | 
			
		||||
@@ -6548,21 +6623,19 @@ const (
 | 
			
		||||
	ESystemIMType_GiftRevoked              ESystemIMType = 7
 | 
			
		||||
	ESystemIMType_SupportMessage           ESystemIMType = 8
 | 
			
		||||
	ESystemIMType_SupportMessageClearAlert ESystemIMType = 9
 | 
			
		||||
	ESystemIMType_Max                      ESystemIMType = 10
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var ESystemIMType_name = map[ESystemIMType]string{
 | 
			
		||||
	0:  "ESystemIMType_RawText",
 | 
			
		||||
	1:  "ESystemIMType_InvalidCard",
 | 
			
		||||
	2:  "ESystemIMType_RecurringPurchaseFailed",
 | 
			
		||||
	3:  "ESystemIMType_CardWillExpire",
 | 
			
		||||
	4:  "ESystemIMType_SubscriptionExpired",
 | 
			
		||||
	5:  "ESystemIMType_GuestPassReceived",
 | 
			
		||||
	6:  "ESystemIMType_GuestPassGranted",
 | 
			
		||||
	7:  "ESystemIMType_GiftRevoked",
 | 
			
		||||
	8:  "ESystemIMType_SupportMessage",
 | 
			
		||||
	9:  "ESystemIMType_SupportMessageClearAlert",
 | 
			
		||||
	10: "ESystemIMType_Max",
 | 
			
		||||
	0: "ESystemIMType_RawText",
 | 
			
		||||
	1: "ESystemIMType_InvalidCard",
 | 
			
		||||
	2: "ESystemIMType_RecurringPurchaseFailed",
 | 
			
		||||
	3: "ESystemIMType_CardWillExpire",
 | 
			
		||||
	4: "ESystemIMType_SubscriptionExpired",
 | 
			
		||||
	5: "ESystemIMType_GuestPassReceived",
 | 
			
		||||
	6: "ESystemIMType_GuestPassGranted",
 | 
			
		||||
	7: "ESystemIMType_GiftRevoked",
 | 
			
		||||
	8: "ESystemIMType_SupportMessage",
 | 
			
		||||
	9: "ESystemIMType_SupportMessageClearAlert",
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (e ESystemIMType) String() string {
 | 
			
		||||
@@ -6618,15 +6691,15 @@ func (e EChatFlags) String() string {
 | 
			
		||||
type ERemoteStoragePlatform int32
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	ERemoteStoragePlatform_None      ERemoteStoragePlatform = 0
 | 
			
		||||
	ERemoteStoragePlatform_Windows   ERemoteStoragePlatform = 1
 | 
			
		||||
	ERemoteStoragePlatform_OSX       ERemoteStoragePlatform = 2
 | 
			
		||||
	ERemoteStoragePlatform_PS3       ERemoteStoragePlatform = 4
 | 
			
		||||
	ERemoteStoragePlatform_Linux     ERemoteStoragePlatform = 8
 | 
			
		||||
	ERemoteStoragePlatform_Reserved2 ERemoteStoragePlatform = 16
 | 
			
		||||
	ERemoteStoragePlatform_Android   ERemoteStoragePlatform = 32
 | 
			
		||||
	ERemoteStoragePlatform_IPhoneOS  ERemoteStoragePlatform = 64
 | 
			
		||||
	ERemoteStoragePlatform_All       ERemoteStoragePlatform = -1
 | 
			
		||||
	ERemoteStoragePlatform_None     ERemoteStoragePlatform = 0
 | 
			
		||||
	ERemoteStoragePlatform_Windows  ERemoteStoragePlatform = 1
 | 
			
		||||
	ERemoteStoragePlatform_OSX      ERemoteStoragePlatform = 2
 | 
			
		||||
	ERemoteStoragePlatform_PS3      ERemoteStoragePlatform = 4
 | 
			
		||||
	ERemoteStoragePlatform_Linux    ERemoteStoragePlatform = 8
 | 
			
		||||
	ERemoteStoragePlatform_Switch   ERemoteStoragePlatform = 16
 | 
			
		||||
	ERemoteStoragePlatform_Android  ERemoteStoragePlatform = 32
 | 
			
		||||
	ERemoteStoragePlatform_IPhoneOS ERemoteStoragePlatform = 64
 | 
			
		||||
	ERemoteStoragePlatform_All      ERemoteStoragePlatform = -1
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var ERemoteStoragePlatform_name = map[ERemoteStoragePlatform]string{
 | 
			
		||||
@@ -6635,7 +6708,7 @@ var ERemoteStoragePlatform_name = map[ERemoteStoragePlatform]string{
 | 
			
		||||
	2:  "ERemoteStoragePlatform_OSX",
 | 
			
		||||
	4:  "ERemoteStoragePlatform_PS3",
 | 
			
		||||
	8:  "ERemoteStoragePlatform_Linux",
 | 
			
		||||
	16: "ERemoteStoragePlatform_Reserved2",
 | 
			
		||||
	16: "ERemoteStoragePlatform_Switch",
 | 
			
		||||
	32: "ERemoteStoragePlatform_Android",
 | 
			
		||||
	64: "ERemoteStoragePlatform_IPhoneOS",
 | 
			
		||||
	-1: "ERemoteStoragePlatform_All",
 | 
			
		||||
@@ -6780,7 +6853,6 @@ const (
 | 
			
		||||
	EClientStat_P2PGameConnections  EClientStat = 2
 | 
			
		||||
	EClientStat_P2PVoiceConnections EClientStat = 3
 | 
			
		||||
	EClientStat_BytesDownloaded     EClientStat = 4
 | 
			
		||||
	EClientStat_Max                 EClientStat = 5
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var EClientStat_name = map[EClientStat]string{
 | 
			
		||||
@@ -6789,7 +6861,6 @@ var EClientStat_name = map[EClientStat]string{
 | 
			
		||||
	2: "EClientStat_P2PGameConnections",
 | 
			
		||||
	3: "EClientStat_P2PVoiceConnections",
 | 
			
		||||
	4: "EClientStat_BytesDownloaded",
 | 
			
		||||
	5: "EClientStat_Max",
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (e EClientStat) String() string {
 | 
			
		||||
@@ -7106,6 +7177,7 @@ type EPublishedFileInappropriateResult int32
 | 
			
		||||
const (
 | 
			
		||||
	EPublishedFileInappropriateResult_NotScanned   EPublishedFileInappropriateResult = 0
 | 
			
		||||
	EPublishedFileInappropriateResult_VeryUnlikely EPublishedFileInappropriateResult = 1
 | 
			
		||||
	EPublishedFileInappropriateResult_Unlikely     EPublishedFileInappropriateResult = 30
 | 
			
		||||
	EPublishedFileInappropriateResult_Possible     EPublishedFileInappropriateResult = 50
 | 
			
		||||
	EPublishedFileInappropriateResult_Likely       EPublishedFileInappropriateResult = 75
 | 
			
		||||
	EPublishedFileInappropriateResult_VeryLikely   EPublishedFileInappropriateResult = 100
 | 
			
		||||
@@ -7114,6 +7186,7 @@ const (
 | 
			
		||||
var EPublishedFileInappropriateResult_name = map[EPublishedFileInappropriateResult]string{
 | 
			
		||||
	0:   "EPublishedFileInappropriateResult_NotScanned",
 | 
			
		||||
	1:   "EPublishedFileInappropriateResult_VeryUnlikely",
 | 
			
		||||
	30:  "EPublishedFileInappropriateResult_Unlikely",
 | 
			
		||||
	50:  "EPublishedFileInappropriateResult_Possible",
 | 
			
		||||
	75:  "EPublishedFileInappropriateResult_Likely",
 | 
			
		||||
	100: "EPublishedFileInappropriateResult_VeryLikely",
 | 
			
		||||
@@ -7723,6 +7796,282 @@ func (e ETradeOfferConfirmationMethod) String() string {
 | 
			
		||||
	return strings.Join(flags, " | ")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type ELobbyType int32
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	ELobbyType_Private       ELobbyType = 0
 | 
			
		||||
	ELobbyType_FriendsOnly   ELobbyType = 1
 | 
			
		||||
	ELobbyType_Public        ELobbyType = 2
 | 
			
		||||
	ELobbyType_Invisible     ELobbyType = 3
 | 
			
		||||
	ELobbyType_PrivateUnique ELobbyType = 4
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var ELobbyType_name = map[ELobbyType]string{
 | 
			
		||||
	0: "ELobbyType_Private",
 | 
			
		||||
	1: "ELobbyType_FriendsOnly",
 | 
			
		||||
	2: "ELobbyType_Public",
 | 
			
		||||
	3: "ELobbyType_Invisible",
 | 
			
		||||
	4: "ELobbyType_PrivateUnique",
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (e ELobbyType) String() string {
 | 
			
		||||
	if s, ok := ELobbyType_name[e]; ok {
 | 
			
		||||
		return s
 | 
			
		||||
	}
 | 
			
		||||
	var flags []string
 | 
			
		||||
	for k, v := range ELobbyType_name {
 | 
			
		||||
		if e&k != 0 {
 | 
			
		||||
			flags = append(flags, v)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if len(flags) == 0 {
 | 
			
		||||
		return fmt.Sprintf("%d", e)
 | 
			
		||||
	}
 | 
			
		||||
	sort.Strings(flags)
 | 
			
		||||
	return strings.Join(flags, " | ")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type ELobbyFilterType int32
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	ELobbyFilterType_String         ELobbyFilterType = 0
 | 
			
		||||
	ELobbyFilterType_Numerical      ELobbyFilterType = 1
 | 
			
		||||
	ELobbyFilterType_SlotsAvailable ELobbyFilterType = 2
 | 
			
		||||
	ELobbyFilterType_NearValue      ELobbyFilterType = 3
 | 
			
		||||
	ELobbyFilterType_Distance       ELobbyFilterType = 4
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var ELobbyFilterType_name = map[ELobbyFilterType]string{
 | 
			
		||||
	0: "ELobbyFilterType_String",
 | 
			
		||||
	1: "ELobbyFilterType_Numerical",
 | 
			
		||||
	2: "ELobbyFilterType_SlotsAvailable",
 | 
			
		||||
	3: "ELobbyFilterType_NearValue",
 | 
			
		||||
	4: "ELobbyFilterType_Distance",
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (e ELobbyFilterType) String() string {
 | 
			
		||||
	if s, ok := ELobbyFilterType_name[e]; ok {
 | 
			
		||||
		return s
 | 
			
		||||
	}
 | 
			
		||||
	var flags []string
 | 
			
		||||
	for k, v := range ELobbyFilterType_name {
 | 
			
		||||
		if e&k != 0 {
 | 
			
		||||
			flags = append(flags, v)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if len(flags) == 0 {
 | 
			
		||||
		return fmt.Sprintf("%d", e)
 | 
			
		||||
	}
 | 
			
		||||
	sort.Strings(flags)
 | 
			
		||||
	return strings.Join(flags, " | ")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type ELobbyComparison int32
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	ELobbyComparison_EqualToOrLessThan    ELobbyComparison = -2
 | 
			
		||||
	ELobbyComparison_LessThan             ELobbyComparison = -1
 | 
			
		||||
	ELobbyComparison_Equal                ELobbyComparison = 0
 | 
			
		||||
	ELobbyComparison_GreaterThan          ELobbyComparison = 1
 | 
			
		||||
	ELobbyComparison_EqualToOrGreaterThan ELobbyComparison = 2
 | 
			
		||||
	ELobbyComparison_NotEqual             ELobbyComparison = 3
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var ELobbyComparison_name = map[ELobbyComparison]string{
 | 
			
		||||
	-2: "ELobbyComparison_EqualToOrLessThan",
 | 
			
		||||
	-1: "ELobbyComparison_LessThan",
 | 
			
		||||
	0:  "ELobbyComparison_Equal",
 | 
			
		||||
	1:  "ELobbyComparison_GreaterThan",
 | 
			
		||||
	2:  "ELobbyComparison_EqualToOrGreaterThan",
 | 
			
		||||
	3:  "ELobbyComparison_NotEqual",
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (e ELobbyComparison) String() string {
 | 
			
		||||
	if s, ok := ELobbyComparison_name[e]; ok {
 | 
			
		||||
		return s
 | 
			
		||||
	}
 | 
			
		||||
	var flags []string
 | 
			
		||||
	for k, v := range ELobbyComparison_name {
 | 
			
		||||
		if e&k != 0 {
 | 
			
		||||
			flags = append(flags, v)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if len(flags) == 0 {
 | 
			
		||||
		return fmt.Sprintf("%d", e)
 | 
			
		||||
	}
 | 
			
		||||
	sort.Strings(flags)
 | 
			
		||||
	return strings.Join(flags, " | ")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type ELobbyDistanceFilter int32
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	ELobbyDistanceFilter_Close     ELobbyDistanceFilter = 0
 | 
			
		||||
	ELobbyDistanceFilter_Default   ELobbyDistanceFilter = 1
 | 
			
		||||
	ELobbyDistanceFilter_Far       ELobbyDistanceFilter = 2
 | 
			
		||||
	ELobbyDistanceFilter_Worldwide ELobbyDistanceFilter = 3
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var ELobbyDistanceFilter_name = map[ELobbyDistanceFilter]string{
 | 
			
		||||
	0: "ELobbyDistanceFilter_Close",
 | 
			
		||||
	1: "ELobbyDistanceFilter_Default",
 | 
			
		||||
	2: "ELobbyDistanceFilter_Far",
 | 
			
		||||
	3: "ELobbyDistanceFilter_Worldwide",
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (e ELobbyDistanceFilter) String() string {
 | 
			
		||||
	if s, ok := ELobbyDistanceFilter_name[e]; ok {
 | 
			
		||||
		return s
 | 
			
		||||
	}
 | 
			
		||||
	var flags []string
 | 
			
		||||
	for k, v := range ELobbyDistanceFilter_name {
 | 
			
		||||
		if e&k != 0 {
 | 
			
		||||
			flags = append(flags, v)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if len(flags) == 0 {
 | 
			
		||||
		return fmt.Sprintf("%d", e)
 | 
			
		||||
	}
 | 
			
		||||
	sort.Strings(flags)
 | 
			
		||||
	return strings.Join(flags, " | ")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type ESteamIPv6ConnectivityProtocol int32
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	ESteamIPv6ConnectivityProtocol_Invalid ESteamIPv6ConnectivityProtocol = 0
 | 
			
		||||
	ESteamIPv6ConnectivityProtocol_Http    ESteamIPv6ConnectivityProtocol = 1
 | 
			
		||||
	ESteamIPv6ConnectivityProtocol_Udp     ESteamIPv6ConnectivityProtocol = 2
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var ESteamIPv6ConnectivityProtocol_name = map[ESteamIPv6ConnectivityProtocol]string{
 | 
			
		||||
	0: "ESteamIPv6ConnectivityProtocol_Invalid",
 | 
			
		||||
	1: "ESteamIPv6ConnectivityProtocol_Http",
 | 
			
		||||
	2: "ESteamIPv6ConnectivityProtocol_Udp",
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (e ESteamIPv6ConnectivityProtocol) String() string {
 | 
			
		||||
	if s, ok := ESteamIPv6ConnectivityProtocol_name[e]; ok {
 | 
			
		||||
		return s
 | 
			
		||||
	}
 | 
			
		||||
	var flags []string
 | 
			
		||||
	for k, v := range ESteamIPv6ConnectivityProtocol_name {
 | 
			
		||||
		if e&k != 0 {
 | 
			
		||||
			flags = append(flags, v)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if len(flags) == 0 {
 | 
			
		||||
		return fmt.Sprintf("%d", e)
 | 
			
		||||
	}
 | 
			
		||||
	sort.Strings(flags)
 | 
			
		||||
	return strings.Join(flags, " | ")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type ESteamIPv6ConnectivityState int32
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	ESteamIPv6ConnectivityState_Unknown ESteamIPv6ConnectivityState = 0
 | 
			
		||||
	ESteamIPv6ConnectivityState_Good    ESteamIPv6ConnectivityState = 1
 | 
			
		||||
	ESteamIPv6ConnectivityState_Bad     ESteamIPv6ConnectivityState = 2
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var ESteamIPv6ConnectivityState_name = map[ESteamIPv6ConnectivityState]string{
 | 
			
		||||
	0: "ESteamIPv6ConnectivityState_Unknown",
 | 
			
		||||
	1: "ESteamIPv6ConnectivityState_Good",
 | 
			
		||||
	2: "ESteamIPv6ConnectivityState_Bad",
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (e ESteamIPv6ConnectivityState) String() string {
 | 
			
		||||
	if s, ok := ESteamIPv6ConnectivityState_name[e]; ok {
 | 
			
		||||
		return s
 | 
			
		||||
	}
 | 
			
		||||
	var flags []string
 | 
			
		||||
	for k, v := range ESteamIPv6ConnectivityState_name {
 | 
			
		||||
		if e&k != 0 {
 | 
			
		||||
			flags = append(flags, v)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if len(flags) == 0 {
 | 
			
		||||
		return fmt.Sprintf("%d", e)
 | 
			
		||||
	}
 | 
			
		||||
	sort.Strings(flags)
 | 
			
		||||
	return strings.Join(flags, " | ")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type ESteamRealm int32
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	ESteamRealm_Unknown     ESteamRealm = 0
 | 
			
		||||
	ESteamRealm_SteamGlobal ESteamRealm = 1
 | 
			
		||||
	ESteamRealm_SteamChina  ESteamRealm = 2
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var ESteamRealm_name = map[ESteamRealm]string{
 | 
			
		||||
	0: "ESteamRealm_Unknown",
 | 
			
		||||
	1: "ESteamRealm_SteamGlobal",
 | 
			
		||||
	2: "ESteamRealm_SteamChina",
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (e ESteamRealm) String() string {
 | 
			
		||||
	if s, ok := ESteamRealm_name[e]; ok {
 | 
			
		||||
		return s
 | 
			
		||||
	}
 | 
			
		||||
	var flags []string
 | 
			
		||||
	for k, v := range ESteamRealm_name {
 | 
			
		||||
		if e&k != 0 {
 | 
			
		||||
			flags = append(flags, v)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if len(flags) == 0 {
 | 
			
		||||
		return fmt.Sprintf("%d", e)
 | 
			
		||||
	}
 | 
			
		||||
	sort.Strings(flags)
 | 
			
		||||
	return strings.Join(flags, " | ")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type ELauncherType int32
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	ELauncherType_Default      ELauncherType = 0
 | 
			
		||||
	ELauncherType_PerfectWorld ELauncherType = 1
 | 
			
		||||
	ELauncherType_Nexon        ELauncherType = 2
 | 
			
		||||
	ELauncherType_CmdLine      ELauncherType = 3
 | 
			
		||||
	ELauncherType_CSGO         ELauncherType = 4
 | 
			
		||||
	ELauncherType_ClientUI     ELauncherType = 5
 | 
			
		||||
	ELauncherType_Headless     ELauncherType = 6
 | 
			
		||||
	ELauncherType_SteamChina   ELauncherType = 7
 | 
			
		||||
	ELauncherType_SingleApp    ELauncherType = 8
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var ELauncherType_name = map[ELauncherType]string{
 | 
			
		||||
	0: "ELauncherType_Default",
 | 
			
		||||
	1: "ELauncherType_PerfectWorld",
 | 
			
		||||
	2: "ELauncherType_Nexon",
 | 
			
		||||
	3: "ELauncherType_CmdLine",
 | 
			
		||||
	4: "ELauncherType_CSGO",
 | 
			
		||||
	5: "ELauncherType_ClientUI",
 | 
			
		||||
	6: "ELauncherType_Headless",
 | 
			
		||||
	7: "ELauncherType_SteamChina",
 | 
			
		||||
	8: "ELauncherType_SingleApp",
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (e ELauncherType) String() string {
 | 
			
		||||
	if s, ok := ELauncherType_name[e]; ok {
 | 
			
		||||
		return s
 | 
			
		||||
	}
 | 
			
		||||
	var flags []string
 | 
			
		||||
	for k, v := range ELauncherType_name {
 | 
			
		||||
		if e&k != 0 {
 | 
			
		||||
			flags = append(flags, v)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if len(flags) == 0 {
 | 
			
		||||
		return fmt.Sprintf("%d", e)
 | 
			
		||||
	}
 | 
			
		||||
	sort.Strings(flags)
 | 
			
		||||
	return strings.Join(flags, " | ")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type EUdpPacketType uint8
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										27
									
								
								vendor/github.com/Philipp15b/go-steam/social.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										27
									
								
								vendor/github.com/Philipp15b/go-steam/social.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -84,14 +84,14 @@ func (s *Social) SetPersonaState(state EPersonaState) {
 | 
			
		||||
 | 
			
		||||
// Sends a chat message to ether a room or friend
 | 
			
		||||
func (s *Social) SendMessage(to SteamId, entryType EChatEntryType, message string) {
 | 
			
		||||
	//Friend
 | 
			
		||||
	// Friend
 | 
			
		||||
	if to.GetAccountType() == int32(EAccountType_Individual) || to.GetAccountType() == int32(EAccountType_ConsoleUser) {
 | 
			
		||||
		s.client.Write(NewClientMsgProtobuf(EMsg_ClientFriendMsg, &CMsgClientFriendMsg{
 | 
			
		||||
			Steamid:       proto.Uint64(to.ToUint64()),
 | 
			
		||||
			ChatEntryType: proto.Int32(int32(entryType)),
 | 
			
		||||
			Message:       []byte(message),
 | 
			
		||||
		}))
 | 
			
		||||
		//Chat room
 | 
			
		||||
		// Chat room
 | 
			
		||||
	} else if to.GetAccountType() == int32(EAccountType_Clan) || to.GetAccountType() == int32(EAccountType_Chat) {
 | 
			
		||||
		chatId := to.ClanToChat()
 | 
			
		||||
		s.client.Write(NewClientMsg(&MsgClientChatMsg{
 | 
			
		||||
@@ -119,9 +119,9 @@ func (s *Social) RemoveFriend(id SteamId) {
 | 
			
		||||
 | 
			
		||||
// Ignores or unignores a friend on Steam
 | 
			
		||||
func (s *Social) IgnoreFriend(id SteamId, setIgnore bool) {
 | 
			
		||||
	ignore := uint8(1) //True
 | 
			
		||||
	ignore := uint8(1) // True
 | 
			
		||||
	if !setIgnore {
 | 
			
		||||
		ignore = uint8(0) //False
 | 
			
		||||
		ignore = uint8(0) // False
 | 
			
		||||
	}
 | 
			
		||||
	s.client.Write(NewClientMsg(&MsgClientSetIgnoreFriend{
 | 
			
		||||
		MySteamId:     s.client.SteamId(),
 | 
			
		||||
@@ -244,7 +244,7 @@ func (s *Social) HandlePacket(packet *Packet) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *Social) handleAccountInfo(packet *Packet) {
 | 
			
		||||
	//Just fire the personainfo, Auth handles the callback
 | 
			
		||||
	// Just fire the personainfo, Auth handles the callback
 | 
			
		||||
	flags := EClientPersonaStateFlag_PlayerName | EClientPersonaStateFlag_Presence | EClientPersonaStateFlag_SourceID
 | 
			
		||||
	s.RequestFriendInfo(s.client.SteamId(), EClientPersonaStateFlag(flags))
 | 
			
		||||
}
 | 
			
		||||
@@ -302,7 +302,7 @@ func (s *Social) handlePersonaState(packet *Packet) {
 | 
			
		||||
	flags := EClientPersonaStateFlag(list.GetStatusFlags())
 | 
			
		||||
	for _, friend := range list.GetFriends() {
 | 
			
		||||
		id := SteamId(friend.GetFriendid())
 | 
			
		||||
		if id == s.client.SteamId() { //this is our client id
 | 
			
		||||
		if id == s.client.SteamId() { // this is our client id
 | 
			
		||||
			s.mutex.Lock()
 | 
			
		||||
			if friend.GetPlayerName() != "" {
 | 
			
		||||
				s.name = friend.GetPlayerName()
 | 
			
		||||
@@ -364,7 +364,6 @@ func (s *Social) handlePersonaState(packet *Packet) {
 | 
			
		||||
			ClanRank:               friend.GetClanRank(),
 | 
			
		||||
			ClanTag:                friend.GetClanTag(),
 | 
			
		||||
			OnlineSessionInstances: friend.GetOnlineSessionInstances(),
 | 
			
		||||
			PublishedSessionId:     friend.GetPublishedInstanceId(),
 | 
			
		||||
			PersonaSetByUser:       friend.GetPersonaSetByUser(),
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
@@ -407,7 +406,7 @@ func (s *Social) handleClanState(packet *Packet) {
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	//Add stuff to group
 | 
			
		||||
	// Add stuff to group
 | 
			
		||||
	clanid := SteamId(body.GetSteamidClan())
 | 
			
		||||
	if body.NameInfo != nil {
 | 
			
		||||
		info := body.NameInfo
 | 
			
		||||
@@ -473,14 +472,14 @@ func (s *Social) handleChatEnter(packet *Packet) {
 | 
			
		||||
	payload := packet.ReadClientMsg(body).Payload
 | 
			
		||||
	reader := bytes.NewBuffer(payload)
 | 
			
		||||
	name, _ := ReadString(reader)
 | 
			
		||||
	ReadByte(reader) //0
 | 
			
		||||
	ReadByte(reader) // 0
 | 
			
		||||
	count := body.NumMembers
 | 
			
		||||
	chatId := SteamId(body.SteamIdChat)
 | 
			
		||||
	clanId := SteamId(body.SteamIdClan)
 | 
			
		||||
	s.Chats.Add(socialcache.Chat{SteamId: chatId, GroupId: clanId})
 | 
			
		||||
	for i := 0; i < int(count); i++ {
 | 
			
		||||
		id, chatPerm, clanPerm := readChatMember(reader)
 | 
			
		||||
		ReadBytes(reader, 6) //No idea what this is
 | 
			
		||||
		ReadBytes(reader, 6) // No idea what this is
 | 
			
		||||
		s.Chats.AddChatMember(chatId, socialcache.ChatMember{
 | 
			
		||||
			SteamId:         SteamId(id),
 | 
			
		||||
			ChatPermissions: chatPerm,
 | 
			
		||||
@@ -508,7 +507,7 @@ func (s *Social) handleChatMemberInfo(packet *Packet) {
 | 
			
		||||
		actedOn, _ := ReadUint64(reader)
 | 
			
		||||
		state, _ := ReadInt32(reader)
 | 
			
		||||
		actedBy, _ := ReadUint64(reader)
 | 
			
		||||
		ReadByte(reader) //0
 | 
			
		||||
		ReadByte(reader) // 0
 | 
			
		||||
		stateChange := EChatMemberStateChange(state)
 | 
			
		||||
		if stateChange == EChatMemberStateChange_Entered {
 | 
			
		||||
			_, chatPerm, clanPerm := readChatMember(reader)
 | 
			
		||||
@@ -537,13 +536,13 @@ func (s *Social) handleChatMemberInfo(packet *Packet) {
 | 
			
		||||
func readChatMember(r io.Reader) (SteamId, EChatPermission, EClanPermission) {
 | 
			
		||||
	ReadString(r) // MessageObject
 | 
			
		||||
	ReadByte(r)   // 7
 | 
			
		||||
	ReadString(r) //steamid
 | 
			
		||||
	ReadString(r) // steamid
 | 
			
		||||
	id, _ := ReadUint64(r)
 | 
			
		||||
	ReadByte(r)   // 2
 | 
			
		||||
	ReadString(r) //Permissions
 | 
			
		||||
	ReadString(r) // Permissions
 | 
			
		||||
	chat, _ := ReadInt32(r)
 | 
			
		||||
	ReadByte(r)   // 2
 | 
			
		||||
	ReadString(r) //Details
 | 
			
		||||
	ReadString(r) // Details
 | 
			
		||||
	clan, _ := ReadInt32(r)
 | 
			
		||||
	return SteamId(id), EChatPermission(chat), EClanPermission(clan)
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										1
									
								
								vendor/github.com/Philipp15b/go-steam/social_events.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								vendor/github.com/Philipp15b/go-steam/social_events.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -48,7 +48,6 @@ type PersonaStateEvent struct {
 | 
			
		||||
	ClanRank               uint32
 | 
			
		||||
	ClanTag                string
 | 
			
		||||
	OnlineSessionInstances uint32
 | 
			
		||||
	PublishedSessionId     uint32
 | 
			
		||||
	PersonaSetByUser       bool
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										8
									
								
								vendor/github.com/Rhymen/go-whatsapp/README.md
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										8
									
								
								vendor/github.com/Rhymen/go-whatsapp/README.md
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -70,6 +70,14 @@ func (myHandler) HandleContactMessage(message whatsapp.ContactMessage) {
 | 
			
		||||
	fmt.Println(message)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (myHandler) HandleBatteryMessage(msg whatsapp.BatteryMessage) {
 | 
			
		||||
	fmt.Println(message)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (myHandler) HandleNewContact(contact whatsapp.Contact) {
 | 
			
		||||
	fmt.Println(contact)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
wac.AddHandler(myHandler{})
 | 
			
		||||
```
 | 
			
		||||
The message handlers are all optional, you don't need to implement anything but the error handler to implement the interface. The ImageMessage, VideoMessage, AudioMessage and DocumentMessage provide a Download function to get the media data.
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										17
									
								
								vendor/github.com/Rhymen/go-whatsapp/conn.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										17
									
								
								vendor/github.com/Rhymen/go-whatsapp/conn.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -88,8 +88,11 @@ type Conn struct {
 | 
			
		||||
	Store          *Store
 | 
			
		||||
	ServerLastSeen time.Time
 | 
			
		||||
 | 
			
		||||
	timeTag string // last 3 digits obtained after a successful login takeover
 | 
			
		||||
 | 
			
		||||
	longClientName  string
 | 
			
		||||
	shortClientName string
 | 
			
		||||
	clientVersion   string
 | 
			
		||||
 | 
			
		||||
	loginSessionLock sync.RWMutex
 | 
			
		||||
	Proxy            func(*http.Request) (*url.URL, error)
 | 
			
		||||
@@ -121,6 +124,7 @@ func NewConn(timeout time.Duration) (*Conn, error) {
 | 
			
		||||
 | 
			
		||||
		longClientName:  "github.com/rhymen/go-whatsapp",
 | 
			
		||||
		shortClientName: "go-whatsapp",
 | 
			
		||||
		clientVersion:   "0.1.0",
 | 
			
		||||
	}
 | 
			
		||||
	return wac, wac.connect()
 | 
			
		||||
}
 | 
			
		||||
@@ -135,6 +139,7 @@ func NewConnWithProxy(timeout time.Duration, proxy func(*http.Request) (*url.URL
 | 
			
		||||
 | 
			
		||||
		longClientName:  "github.com/rhymen/go-whatsapp",
 | 
			
		||||
		shortClientName: "go-whatsapp",
 | 
			
		||||
		clientVersion:   "0.1.0",
 | 
			
		||||
		Proxy:           proxy,
 | 
			
		||||
	}
 | 
			
		||||
	return wac, wac.connect()
 | 
			
		||||
@@ -153,8 +158,8 @@ func (wac *Conn) connect() (err error) {
 | 
			
		||||
	}()
 | 
			
		||||
 | 
			
		||||
	dialer := &websocket.Dialer{
 | 
			
		||||
		ReadBufferSize:   25 * 1024 * 1024,
 | 
			
		||||
		WriteBufferSize:  10 * 1024 * 1024,
 | 
			
		||||
		ReadBufferSize:   0,
 | 
			
		||||
		WriteBufferSize:  0,
 | 
			
		||||
		HandshakeTimeout: wac.msgTimeout,
 | 
			
		||||
		Proxy:            wac.Proxy,
 | 
			
		||||
	}
 | 
			
		||||
@@ -243,3 +248,11 @@ func (wac *Conn) keepAlive(minIntervalMs int, maxIntervalMs int) {
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (wac *Conn) GetConnected() bool {
 | 
			
		||||
	return  wac.connected
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (wac *Conn) GetLoggedIn() bool {
 | 
			
		||||
	return  wac.loggedIn
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										2
									
								
								vendor/github.com/Rhymen/go-whatsapp/errors.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/Rhymen/go-whatsapp/errors.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -2,6 +2,7 @@ package whatsapp
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
 | 
			
		||||
	"github.com/pkg/errors"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
@@ -20,6 +21,7 @@ var (
 | 
			
		||||
	ErrServerRespondedWith404     = errors.New("server responded with status 404")
 | 
			
		||||
	ErrMediaDownloadFailedWith404 = errors.New("download failed with status code 404")
 | 
			
		||||
	ErrMediaDownloadFailedWith410 = errors.New("download failed with status code 410")
 | 
			
		||||
	ErrInvalidWebsocket           = errors.New("invalid websocket")
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type ErrConnectionFailed struct {
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										46
									
								
								vendor/github.com/Rhymen/go-whatsapp/handler.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										46
									
								
								vendor/github.com/Rhymen/go-whatsapp/handler.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -133,6 +133,22 @@ type ChatListHandler interface {
 | 
			
		||||
	HandleChatList(contacts []Chat)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
The BatteryMessageHandler interface needs to be implemented to receive percentage the device connected dispatched by the dispatcher.
 | 
			
		||||
*/
 | 
			
		||||
type BatteryMessageHandler interface {
 | 
			
		||||
	Handler
 | 
			
		||||
	HandleBatteryMessage(battery BatteryMessage)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
The NewContactHandler interface needs to be implemented to receive the contact's name for the first time.
 | 
			
		||||
*/
 | 
			
		||||
type NewContactHandler interface {
 | 
			
		||||
	Handler
 | 
			
		||||
	HandleNewContact(contact Contact)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
AddHandler adds an handler to the list of handler that receive dispatched messages.
 | 
			
		||||
The provided handler must at least implement the Handler interface. Additionally implemented
 | 
			
		||||
@@ -285,6 +301,28 @@ func (wac *Conn) handleWithCustomHandlers(message interface{}, handlers []Handle
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	
 | 
			
		||||
	case BatteryMessage:
 | 
			
		||||
		for _, h := range handlers {
 | 
			
		||||
			if x, ok := h.(BatteryMessageHandler); ok {
 | 
			
		||||
				if wac.shouldCallSynchronously(h) {
 | 
			
		||||
					x.HandleBatteryMessage(m)
 | 
			
		||||
				} else {
 | 
			
		||||
					go x.HandleBatteryMessage(m)
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	
 | 
			
		||||
	case Contact:
 | 
			
		||||
		for _, h := range handlers {
 | 
			
		||||
			if x, ok := h.(NewContactHandler); ok {
 | 
			
		||||
				if wac.shouldCallSynchronously(h) {
 | 
			
		||||
					x.HandleNewContact(m)
 | 
			
		||||
				} else {
 | 
			
		||||
					go x.HandleNewContact(m)
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	case *proto.WebMessageInfo:
 | 
			
		||||
		for _, h := range handlers {
 | 
			
		||||
@@ -378,6 +416,14 @@ func (wac *Conn) dispatch(msg interface{}) {
 | 
			
		||||
						wac.handle(v)
 | 
			
		||||
						wac.handle(ParseProtoMessage(v))
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					if v, ok := con[a].(binary.Node); ok {
 | 
			
		||||
						wac.handle(ParseNodeMessage(v))
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			} else if con, ok := message.Content.([]binary.Node); ok {
 | 
			
		||||
				for a := range con {
 | 
			
		||||
					wac.handle(ParseNodeMessage(con[a]))
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		} else if message.Description == "response" && message.Attributes["type"] == "contacts" {
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										39
									
								
								vendor/github.com/Rhymen/go-whatsapp/media.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										39
									
								
								vendor/github.com/Rhymen/go-whatsapp/media.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -93,18 +93,21 @@ func downloadMedia(url string) (file []byte, mac []byte, err error) {
 | 
			
		||||
	return data[:n-10], data[n-10 : n], nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type MediaConn struct {
 | 
			
		||||
	Status    int `json:"status"`
 | 
			
		||||
	MediaConn struct {
 | 
			
		||||
		Auth  string `json:"auth"`
 | 
			
		||||
		TTL   int    `json:"ttl"`
 | 
			
		||||
		Hosts []struct {
 | 
			
		||||
			Hostname string   `json:"hostname"`
 | 
			
		||||
			IPs      []string `json:"ips"`
 | 
			
		||||
		} `json:"hosts"`
 | 
			
		||||
	} `json:"media_conn"`
 | 
			
		||||
                                                                                
 | 
			
		||||
type MediaConn struct {                                                         
 | 
			
		||||
        Status int `json:"status"`                                              
 | 
			
		||||
        MediaConn struct {                                                      
 | 
			
		||||
                Auth string `json:"auth"`                                       
 | 
			
		||||
                TTL int `json:"ttl"`                                            
 | 
			
		||||
                Hosts []struct {                                                
 | 
			
		||||
                        Hostname string `json:"hostname"`                       
 | 
			
		||||
                        IPs []interface{}  `json:"ips"`                                              
 | 
			
		||||
                } `json:"hosts"`                                                
 | 
			
		||||
        } `json:"media_conn"`                                                   
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
func (wac *Conn) queryMediaConn() (hostname, auth string, ttl int, err error) {
 | 
			
		||||
	queryReq := []interface{}{"query", "mediaConn"}
 | 
			
		||||
	ch, err := wac.writeJson(queryReq)
 | 
			
		||||
@@ -126,7 +129,17 @@ func (wac *Conn) queryMediaConn() (hostname, auth string, ttl int, err error) {
 | 
			
		||||
		return "", "", 0, fmt.Errorf("query media conn responded with %d", resp.Status)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return resp.MediaConn.Hosts[0].Hostname, resp.MediaConn.Auth, resp.MediaConn.TTL, nil
 | 
			
		||||
	var host string
 | 
			
		||||
	for _, h := range resp.MediaConn.Hosts {
 | 
			
		||||
		if h.Hostname!="" {
 | 
			
		||||
			host = h.Hostname
 | 
			
		||||
			break
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if host == "" {
 | 
			
		||||
		return "", "", 0, fmt.Errorf("query media conn responded with no host")
 | 
			
		||||
	}
 | 
			
		||||
	return host, resp.MediaConn.Auth, resp.MediaConn.TTL, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var mediaTypeMap = map[MediaType]string{
 | 
			
		||||
@@ -170,6 +183,10 @@ func (wac *Conn) Upload(reader io.Reader, appInfo MediaType) (downloadURL string
 | 
			
		||||
	fileEncSha256 = sha.Sum(nil)
 | 
			
		||||
 | 
			
		||||
	hostname, auth, _, err := wac.queryMediaConn()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return "", nil, nil, nil, 0, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	token := base64.URLEncoding.EncodeToString(fileEncSha256)
 | 
			
		||||
	q := url.Values{
 | 
			
		||||
		"auth":  []string{auth},
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										146
									
								
								vendor/github.com/Rhymen/go-whatsapp/message.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										146
									
								
								vendor/github.com/Rhymen/go-whatsapp/message.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -81,7 +81,7 @@ func (wac *Conn) Send(msg interface{}) (string, error) {
 | 
			
		||||
			return "ERROR", fmt.Errorf("error decoding sending response: %v\n", err)
 | 
			
		||||
		}
 | 
			
		||||
		if int(resp["status"].(float64)) != 200 {
 | 
			
		||||
			return "ERROR", fmt.Errorf("message sending responded with %d", resp["status"])
 | 
			
		||||
			return "ERROR", fmt.Errorf("message sending responded with %v", resp["status"])
 | 
			
		||||
		}
 | 
			
		||||
		if int(resp["status"].(float64)) == 200 {
 | 
			
		||||
			return getMessageInfo(msgProto).Id, nil
 | 
			
		||||
@@ -105,6 +105,105 @@ func (wac *Conn) sendProto(p *proto.WebMessageInfo) (<-chan string, error) {
 | 
			
		||||
	return wac.writeBinary(n, message, ignore, p.Key.GetId())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// RevokeMessage revokes a message (marks as "message removed") for everyone
 | 
			
		||||
func (wac *Conn) RevokeMessage(remotejid, msgid string, fromme bool) (revokeid string, err error) {
 | 
			
		||||
	// create a revocation ID (required)
 | 
			
		||||
	rawrevocationID := make([]byte, 10)
 | 
			
		||||
	rand.Read(rawrevocationID)
 | 
			
		||||
	revocationID := strings.ToUpper(hex.EncodeToString(rawrevocationID))
 | 
			
		||||
	//
 | 
			
		||||
	ts := uint64(time.Now().Unix())
 | 
			
		||||
	status := proto.WebMessageInfo_PENDING
 | 
			
		||||
	mtype := proto.ProtocolMessage_REVOKE
 | 
			
		||||
 | 
			
		||||
	revoker := &proto.WebMessageInfo{
 | 
			
		||||
		Key: &proto.MessageKey{
 | 
			
		||||
			FromMe:    &fromme,
 | 
			
		||||
			Id:        &revocationID,
 | 
			
		||||
			RemoteJid: &remotejid,
 | 
			
		||||
		},
 | 
			
		||||
		MessageTimestamp: &ts,
 | 
			
		||||
		Message: &proto.Message{
 | 
			
		||||
			ProtocolMessage: &proto.ProtocolMessage{
 | 
			
		||||
				Type: &mtype,
 | 
			
		||||
				Key: &proto.MessageKey{
 | 
			
		||||
					FromMe:    &fromme,
 | 
			
		||||
					Id:        &msgid,
 | 
			
		||||
					RemoteJid: &remotejid,
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
		Status: &status,
 | 
			
		||||
	}
 | 
			
		||||
	if _, err := wac.Send(revoker); err != nil {
 | 
			
		||||
		return revocationID, err
 | 
			
		||||
	}
 | 
			
		||||
	return revocationID, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// DeleteMessage deletes a single message for the user (removes the msgbox). To
 | 
			
		||||
// delete the message for everyone, use RevokeMessage
 | 
			
		||||
func (wac *Conn) DeleteMessage(remotejid, msgid string, fromMe bool) error {
 | 
			
		||||
	ch, err := wac.deleteChatProto(remotejid, msgid, fromMe)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return fmt.Errorf("could not send proto: %v", err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	select {
 | 
			
		||||
	case response := <-ch:
 | 
			
		||||
		var resp map[string]interface{}
 | 
			
		||||
		if err = json.Unmarshal([]byte(response), &resp); err != nil {
 | 
			
		||||
			return fmt.Errorf("error decoding deletion response: %v", err)
 | 
			
		||||
		}
 | 
			
		||||
		if int(resp["status"].(float64)) != 200 {
 | 
			
		||||
			return fmt.Errorf("message deletion responded with %v", resp["status"])
 | 
			
		||||
		}
 | 
			
		||||
		if int(resp["status"].(float64)) == 200 {
 | 
			
		||||
			return nil
 | 
			
		||||
		}
 | 
			
		||||
	case <-time.After(wac.msgTimeout):
 | 
			
		||||
		return fmt.Errorf("deleting message timed out")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (wac *Conn) deleteChatProto(remotejid, msgid string, fromMe bool) (<-chan string, error) {
 | 
			
		||||
	tag := fmt.Sprintf("%s.--%d", wac.timeTag, wac.msgCount)
 | 
			
		||||
 | 
			
		||||
	owner := "true"
 | 
			
		||||
	if !fromMe {
 | 
			
		||||
		owner = "false"
 | 
			
		||||
	}
 | 
			
		||||
	n := binary.Node{
 | 
			
		||||
		Description: "action",
 | 
			
		||||
		Attributes: map[string]string{
 | 
			
		||||
			"epoch": strconv.Itoa(wac.msgCount),
 | 
			
		||||
			"type":  "set",
 | 
			
		||||
		},
 | 
			
		||||
		Content: []interface{}{
 | 
			
		||||
			binary.Node{
 | 
			
		||||
				Description: "chat",
 | 
			
		||||
				Attributes: map[string]string{
 | 
			
		||||
					"type":  "clear",
 | 
			
		||||
					"jid":   remotejid,
 | 
			
		||||
					"media": "true",
 | 
			
		||||
				},
 | 
			
		||||
				Content: []binary.Node{
 | 
			
		||||
					{
 | 
			
		||||
						Description: "item",
 | 
			
		||||
						Attributes: map[string]string{
 | 
			
		||||
							"owner": owner,
 | 
			
		||||
							"index": msgid,
 | 
			
		||||
						},
 | 
			
		||||
					},
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
	return wac.writeBinary(n, chat, expires|skipOffline, tag)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func init() {
 | 
			
		||||
	rand.Seed(time.Now().UTC().UnixNano())
 | 
			
		||||
}
 | 
			
		||||
@@ -744,3 +843,48 @@ func ParseProtoMessage(msg *proto.WebMessageInfo) interface{} {
 | 
			
		||||
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
BatteryMessage represents a battery level and charging state.
 | 
			
		||||
*/
 | 
			
		||||
type BatteryMessage struct {
 | 
			
		||||
	Plugged bool
 | 
			
		||||
	Powersave bool
 | 
			
		||||
	Percentage int
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func getBatteryMessage(msg map[string]string) BatteryMessage {
 | 
			
		||||
	plugged, _ := strconv.ParseBool(msg["live"])
 | 
			
		||||
	powersave, _ := strconv.ParseBool(msg["powersave"])
 | 
			
		||||
	percentage, _ := strconv.Atoi(msg["value"])
 | 
			
		||||
	batteryMessage := BatteryMessage{
 | 
			
		||||
		Plugged: plugged,
 | 
			
		||||
		Powersave: powersave,
 | 
			
		||||
		Percentage: percentage,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return batteryMessage
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func getNewContact(msg map[string]string) Contact {
 | 
			
		||||
	contact := Contact{
 | 
			
		||||
		Jid: msg["jid"],
 | 
			
		||||
		Notify: msg["notify"],
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return contact
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func ParseNodeMessage(msg binary.Node) interface{} {
 | 
			
		||||
	switch msg.Description {
 | 
			
		||||
	case "battery":
 | 
			
		||||
		return getBatteryMessage(msg.Attributes)
 | 
			
		||||
	case "user":
 | 
			
		||||
		return getNewContact(msg.Attributes)
 | 
			
		||||
	default:
 | 
			
		||||
		//cannot match message
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										11
									
								
								vendor/github.com/Rhymen/go-whatsapp/read.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										11
									
								
								vendor/github.com/Rhymen/go-whatsapp/read.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -5,13 +5,14 @@ import (
 | 
			
		||||
	"crypto/sha256"
 | 
			
		||||
	"encoding/json"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"io"
 | 
			
		||||
	"io/ioutil"
 | 
			
		||||
	"strings"
 | 
			
		||||
 | 
			
		||||
	"github.com/Rhymen/go-whatsapp/binary"
 | 
			
		||||
	"github.com/Rhymen/go-whatsapp/crypto/cbc"
 | 
			
		||||
	"github.com/gorilla/websocket"
 | 
			
		||||
	"github.com/pkg/errors"
 | 
			
		||||
	"io"
 | 
			
		||||
	"io/ioutil"
 | 
			
		||||
	"strings"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func (wac *Conn) readPump() {
 | 
			
		||||
@@ -27,7 +28,9 @@ func (wac *Conn) readPump() {
 | 
			
		||||
	for {
 | 
			
		||||
		readerFound := make(chan struct{})
 | 
			
		||||
		go func() {
 | 
			
		||||
			msgType, reader, readErr = wac.ws.conn.NextReader()
 | 
			
		||||
			if wac.ws != nil {
 | 
			
		||||
				msgType, reader, readErr = wac.ws.conn.NextReader()
 | 
			
		||||
			}
 | 
			
		||||
			close(readerFound)
 | 
			
		||||
		}()
 | 
			
		||||
		select {
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										30
									
								
								vendor/github.com/Rhymen/go-whatsapp/session.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										30
									
								
								vendor/github.com/Rhymen/go-whatsapp/session.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -18,7 +18,7 @@ import (
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
//represents the WhatsAppWeb client version
 | 
			
		||||
var waVersion = []int{0, 4, 2080}
 | 
			
		||||
var waVersion = []int{2, 2039, 9}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
Session contains session individual information. To be able to resume the connection without scanning the qr code
 | 
			
		||||
@@ -107,7 +107,7 @@ func CheckCurrentServerVersion() ([]int, error) {
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	b64ClientId := base64.StdEncoding.EncodeToString(clientId)
 | 
			
		||||
	login := []interface{}{"admin", "init", waVersion, []string{wac.longClientName, wac.shortClientName}, b64ClientId, true}
 | 
			
		||||
	login := []interface{}{"admin", "init", waVersion, []string{wac.longClientName, wac.shortClientName, wac.clientVersion}, b64ClientId, true}
 | 
			
		||||
	loginChan, err := wac.writeJson(login)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, fmt.Errorf("error writing login: %s", err.Error())
 | 
			
		||||
@@ -141,11 +141,11 @@ func CheckCurrentServerVersion() ([]int, error) {
 | 
			
		||||
SetClientName sets the long and short client names that are sent to WhatsApp when logging in and displayed in the
 | 
			
		||||
WhatsApp Web device list. As the values are only sent when logging in, changing them after logging in is not possible.
 | 
			
		||||
*/
 | 
			
		||||
func (wac *Conn) SetClientName(long, short string) error {
 | 
			
		||||
func (wac *Conn) SetClientName(long, short string, version string) error {
 | 
			
		||||
	if wac.session != nil && (wac.session.EncKey != nil || wac.session.MacKey != nil) {
 | 
			
		||||
		return fmt.Errorf("cannot change client name after logging in")
 | 
			
		||||
	}
 | 
			
		||||
	wac.longClientName, wac.shortClientName = long, short
 | 
			
		||||
	wac.longClientName, wac.shortClientName, wac.clientVersion = long, short, version
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -213,7 +213,7 @@ func (wac *Conn) Login(qrChan chan<- string) (Session, error) {
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	session.ClientId = base64.StdEncoding.EncodeToString(clientId)
 | 
			
		||||
	login := []interface{}{"admin", "init", waVersion, []string{wac.longClientName, wac.shortClientName}, session.ClientId, true}
 | 
			
		||||
	login := []interface{}{"admin", "init", waVersion, []string{wac.longClientName, wac.shortClientName, wac.clientVersion}, session.ClientId, true}
 | 
			
		||||
	loginChan, err := wac.writeJson(login)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return session, fmt.Errorf("error writing login: %v\n", err)
 | 
			
		||||
@@ -231,7 +231,12 @@ func (wac *Conn) Login(qrChan chan<- string) (Session, error) {
 | 
			
		||||
		return session, fmt.Errorf("error decoding login resp: %v\n", err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ref := resp["ref"].(string)
 | 
			
		||||
	var ref string
 | 
			
		||||
	if rref, ok := resp["ref"].(string); ok {
 | 
			
		||||
		ref = rref
 | 
			
		||||
	} else {
 | 
			
		||||
		return session, fmt.Errorf("error decoding login resp: invalid resp['ref']\n")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	priv, pub, err := curve25519.GenerateKey()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
@@ -369,7 +374,7 @@ func (wac *Conn) Restore() error {
 | 
			
		||||
	wac.listener.Unlock()
 | 
			
		||||
 | 
			
		||||
	//admin init
 | 
			
		||||
	init := []interface{}{"admin", "init", waVersion, []string{wac.longClientName, wac.shortClientName}, wac.session.ClientId, true}
 | 
			
		||||
	init := []interface{}{"admin", "init", waVersion, []string{wac.longClientName, wac.shortClientName, wac.clientVersion}, wac.session.ClientId, true}
 | 
			
		||||
	initChan, err := wac.writeJson(init)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return fmt.Errorf("error writing admin init: %v\n", err)
 | 
			
		||||
@@ -390,9 +395,11 @@ func (wac *Conn) Restore() error {
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if int(resp["status"].(float64)) != 200 {
 | 
			
		||||
			wac.timeTag = ""
 | 
			
		||||
			return fmt.Errorf("init responded with %d", resp["status"])
 | 
			
		||||
		}
 | 
			
		||||
	case <-time.After(wac.msgTimeout):
 | 
			
		||||
		wac.timeTag = ""
 | 
			
		||||
		return fmt.Errorf("restore session init timed out")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -401,10 +408,11 @@ func (wac *Conn) Restore() error {
 | 
			
		||||
	select {
 | 
			
		||||
	case r1 := <-s1:
 | 
			
		||||
		if err := json.Unmarshal([]byte(r1), &connResp); err != nil {
 | 
			
		||||
			wac.timeTag = ""
 | 
			
		||||
			return fmt.Errorf("error decoding s1 message: %v\n", err)
 | 
			
		||||
		}
 | 
			
		||||
	case <-time.After(wac.msgTimeout):
 | 
			
		||||
 | 
			
		||||
		wac.timeTag = ""
 | 
			
		||||
		//check for an error message
 | 
			
		||||
		select {
 | 
			
		||||
		case r := <-loginChan:
 | 
			
		||||
@@ -429,15 +437,18 @@ func (wac *Conn) Restore() error {
 | 
			
		||||
		wac.listener.Unlock()
 | 
			
		||||
 | 
			
		||||
		if err := wac.resolveChallenge(connResp[1].(map[string]interface{})["challenge"].(string)); err != nil {
 | 
			
		||||
			wac.timeTag = ""
 | 
			
		||||
			return fmt.Errorf("error resolving challenge: %v\n", err)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		select {
 | 
			
		||||
		case r := <-s2:
 | 
			
		||||
			if err := json.Unmarshal([]byte(r), &connResp); err != nil {
 | 
			
		||||
				wac.timeTag = ""
 | 
			
		||||
				return fmt.Errorf("error decoding s2 message: %v\n", err)
 | 
			
		||||
			}
 | 
			
		||||
		case <-time.After(wac.msgTimeout):
 | 
			
		||||
			wac.timeTag = ""
 | 
			
		||||
			return fmt.Errorf("restore session challenge timed out")
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
@@ -447,13 +458,16 @@ func (wac *Conn) Restore() error {
 | 
			
		||||
	case r := <-loginChan:
 | 
			
		||||
		var resp map[string]interface{}
 | 
			
		||||
		if err = json.Unmarshal([]byte(r), &resp); err != nil {
 | 
			
		||||
			wac.timeTag = ""
 | 
			
		||||
			return fmt.Errorf("error decoding login connResp: %v\n", err)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if int(resp["status"].(float64)) != 200 {
 | 
			
		||||
			wac.timeTag = ""
 | 
			
		||||
			return fmt.Errorf("admin login responded with %d", resp["status"])
 | 
			
		||||
		}
 | 
			
		||||
	case <-time.After(wac.msgTimeout):
 | 
			
		||||
		wac.timeTag = ""
 | 
			
		||||
		return fmt.Errorf("restore session login timed out")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										8
									
								
								vendor/github.com/Rhymen/go-whatsapp/write.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										8
									
								
								vendor/github.com/Rhymen/go-whatsapp/write.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -30,6 +30,11 @@ func (wac *Conn) writeJson(data []interface{}) (<-chan string, error) {
 | 
			
		||||
	messageTag := fmt.Sprintf("%d.--%d", ts, wac.msgCount)
 | 
			
		||||
	bytes := []byte(fmt.Sprintf("%s,%s", messageTag, d))
 | 
			
		||||
 | 
			
		||||
	if wac.timeTag == "" {
 | 
			
		||||
		tss := fmt.Sprintf("%d", ts)
 | 
			
		||||
		wac.timeTag = tss[len(tss)-3:]
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ch, err := wac.write(websocket.TextMessage, messageTag, bytes)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
@@ -127,6 +132,9 @@ func (wac *Conn) write(messageType int, answerMessageTag string, data []byte) (<
 | 
			
		||||
		wac.listener.Unlock()
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if wac == nil || wac.ws == nil {
 | 
			
		||||
		return nil, ErrInvalidWebsocket
 | 
			
		||||
	}
 | 
			
		||||
	wac.ws.Lock()
 | 
			
		||||
	err := wac.ws.conn.WriteMessage(messageType, data)
 | 
			
		||||
	wac.ws.Unlock()
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										21
									
								
								vendor/github.com/blang/semver/.travis.yml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								vendor/github.com/blang/semver/.travis.yml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,21 @@
 | 
			
		||||
language: go
 | 
			
		||||
matrix:
 | 
			
		||||
  include:
 | 
			
		||||
  - go: 1.4.3
 | 
			
		||||
  - go: 1.5.4
 | 
			
		||||
  - go: 1.6.3
 | 
			
		||||
  - go: 1.7
 | 
			
		||||
  - go: tip
 | 
			
		||||
  allow_failures:
 | 
			
		||||
  - go: tip
 | 
			
		||||
install:
 | 
			
		||||
- go get golang.org/x/tools/cmd/cover
 | 
			
		||||
- go get github.com/mattn/goveralls
 | 
			
		||||
script:
 | 
			
		||||
- echo "Test and track coverage" ; $HOME/gopath/bin/goveralls -package "." -service=travis-ci
 | 
			
		||||
  -repotoken $COVERALLS_TOKEN
 | 
			
		||||
- echo "Build examples" ; cd examples && go build
 | 
			
		||||
- echo "Check if gofmt'd" ; diff -u <(echo -n) <(gofmt -d -s .)
 | 
			
		||||
env:
 | 
			
		||||
  global:
 | 
			
		||||
    secure: HroGEAUQpVq9zX1b1VIkraLiywhGbzvNnTZq2TMxgK7JHP8xqNplAeF1izrR2i4QLL9nsY+9WtYss4QuPvEtZcVHUobw6XnL6radF7jS1LgfYZ9Y7oF+zogZ2I5QUMRLGA7rcxQ05s7mKq3XZQfeqaNts4bms/eZRefWuaFZbkw=
 | 
			
		||||
							
								
								
									
										22
									
								
								vendor/github.com/blang/semver/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								vendor/github.com/blang/semver/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,22 @@
 | 
			
		||||
The MIT License
 | 
			
		||||
 | 
			
		||||
Copyright (c) 2014 Benedikt Lang <github at benediktlang.de>
 | 
			
		||||
 | 
			
		||||
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.
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										194
									
								
								vendor/github.com/blang/semver/README.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										194
									
								
								vendor/github.com/blang/semver/README.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,194 @@
 | 
			
		||||
semver for golang [](https://travis-ci.org/blang/semver) [](https://godoc.org/github.com/blang/semver) [](https://coveralls.io/r/blang/semver?branch=master)
 | 
			
		||||
======
 | 
			
		||||
 | 
			
		||||
semver is a [Semantic Versioning](http://semver.org/) library written in golang. It fully covers spec version `2.0.0`.
 | 
			
		||||
 | 
			
		||||
Usage
 | 
			
		||||
-----
 | 
			
		||||
```bash
 | 
			
		||||
$ go get github.com/blang/semver
 | 
			
		||||
```
 | 
			
		||||
Note: Always vendor your dependencies or fix on a specific version tag.
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
import github.com/blang/semver
 | 
			
		||||
v1, err := semver.Make("1.0.0-beta")
 | 
			
		||||
v2, err := semver.Make("2.0.0-beta")
 | 
			
		||||
v1.Compare(v2)
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Also check the [GoDocs](http://godoc.org/github.com/blang/semver).
 | 
			
		||||
 | 
			
		||||
Why should I use this lib?
 | 
			
		||||
-----
 | 
			
		||||
 | 
			
		||||
- Fully spec compatible
 | 
			
		||||
- No reflection
 | 
			
		||||
- No regex
 | 
			
		||||
- Fully tested (Coverage >99%)
 | 
			
		||||
- Readable parsing/validation errors
 | 
			
		||||
- Fast (See [Benchmarks](#benchmarks))
 | 
			
		||||
- Only Stdlib
 | 
			
		||||
- Uses values instead of pointers
 | 
			
		||||
- Many features, see below
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Features
 | 
			
		||||
-----
 | 
			
		||||
 | 
			
		||||
- Parsing and validation at all levels
 | 
			
		||||
- Comparator-like comparisons
 | 
			
		||||
- Compare Helper Methods
 | 
			
		||||
- InPlace manipulation
 | 
			
		||||
- Ranges `>=1.0.0 <2.0.0 || >=3.0.0 !3.0.1-beta.1`
 | 
			
		||||
- Wildcards `>=1.x`, `<=2.5.x`
 | 
			
		||||
- Sortable (implements sort.Interface)
 | 
			
		||||
- database/sql compatible (sql.Scanner/Valuer)
 | 
			
		||||
- encoding/json compatible (json.Marshaler/Unmarshaler)
 | 
			
		||||
 | 
			
		||||
Ranges
 | 
			
		||||
------
 | 
			
		||||
 | 
			
		||||
A `Range` is a set of conditions which specify which versions satisfy the range.
 | 
			
		||||
 | 
			
		||||
A condition is composed of an operator and a version. The supported operators are:
 | 
			
		||||
 | 
			
		||||
- `<1.0.0` Less than `1.0.0`
 | 
			
		||||
- `<=1.0.0` Less than or equal to `1.0.0`
 | 
			
		||||
- `>1.0.0` Greater than `1.0.0`
 | 
			
		||||
- `>=1.0.0` Greater than or equal to `1.0.0`
 | 
			
		||||
- `1.0.0`, `=1.0.0`, `==1.0.0` Equal to `1.0.0`
 | 
			
		||||
- `!1.0.0`, `!=1.0.0` Not equal to `1.0.0`. Excludes version `1.0.0`.
 | 
			
		||||
 | 
			
		||||
Note that spaces between the operator and the version will be gracefully tolerated.
 | 
			
		||||
 | 
			
		||||
A `Range` can link multiple `Ranges` separated by space:
 | 
			
		||||
 | 
			
		||||
Ranges can be linked by logical AND:
 | 
			
		||||
 | 
			
		||||
  - `>1.0.0 <2.0.0` would match between both ranges, so `1.1.1` and `1.8.7` but not `1.0.0` or `2.0.0`
 | 
			
		||||
  - `>1.0.0 <3.0.0 !2.0.3-beta.2` would match every version between `1.0.0` and `3.0.0` except `2.0.3-beta.2`
 | 
			
		||||
 | 
			
		||||
Ranges can also be linked by logical OR:
 | 
			
		||||
 | 
			
		||||
  - `<2.0.0 || >=3.0.0` would match `1.x.x` and `3.x.x` but not `2.x.x`
 | 
			
		||||
 | 
			
		||||
AND has a higher precedence than OR. It's not possible to use brackets.
 | 
			
		||||
 | 
			
		||||
Ranges can be combined by both AND and OR
 | 
			
		||||
 | 
			
		||||
  - `>1.0.0 <2.0.0 || >3.0.0 !4.2.1` would match `1.2.3`, `1.9.9`, `3.1.1`, but not `4.2.1`, `2.1.1`
 | 
			
		||||
 | 
			
		||||
Range usage:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
v, err := semver.Parse("1.2.3")
 | 
			
		||||
range, err := semver.ParseRange(">1.0.0 <2.0.0 || >=3.0.0")
 | 
			
		||||
if range(v) {
 | 
			
		||||
    //valid
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Example
 | 
			
		||||
-----
 | 
			
		||||
 | 
			
		||||
Have a look at full examples in [examples/main.go](examples/main.go)
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
import github.com/blang/semver
 | 
			
		||||
 | 
			
		||||
v, err := semver.Make("0.0.1-alpha.preview+123.github")
 | 
			
		||||
fmt.Printf("Major: %d\n", v.Major)
 | 
			
		||||
fmt.Printf("Minor: %d\n", v.Minor)
 | 
			
		||||
fmt.Printf("Patch: %d\n", v.Patch)
 | 
			
		||||
fmt.Printf("Pre: %s\n", v.Pre)
 | 
			
		||||
fmt.Printf("Build: %s\n", v.Build)
 | 
			
		||||
 | 
			
		||||
// Prerelease versions array
 | 
			
		||||
if len(v.Pre) > 0 {
 | 
			
		||||
    fmt.Println("Prerelease versions:")
 | 
			
		||||
    for i, pre := range v.Pre {
 | 
			
		||||
        fmt.Printf("%d: %q\n", i, pre)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Build meta data array
 | 
			
		||||
if len(v.Build) > 0 {
 | 
			
		||||
    fmt.Println("Build meta data:")
 | 
			
		||||
    for i, build := range v.Build {
 | 
			
		||||
        fmt.Printf("%d: %q\n", i, build)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
v001, err := semver.Make("0.0.1")
 | 
			
		||||
// Compare using helpers: v.GT(v2), v.LT, v.GTE, v.LTE
 | 
			
		||||
v001.GT(v) == true
 | 
			
		||||
v.LT(v001) == true
 | 
			
		||||
v.GTE(v) == true
 | 
			
		||||
v.LTE(v) == true
 | 
			
		||||
 | 
			
		||||
// Or use v.Compare(v2) for comparisons (-1, 0, 1):
 | 
			
		||||
v001.Compare(v) == 1
 | 
			
		||||
v.Compare(v001) == -1
 | 
			
		||||
v.Compare(v) == 0
 | 
			
		||||
 | 
			
		||||
// Manipulate Version in place:
 | 
			
		||||
v.Pre[0], err = semver.NewPRVersion("beta")
 | 
			
		||||
if err != nil {
 | 
			
		||||
    fmt.Printf("Error parsing pre release version: %q", err)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fmt.Println("\nValidate versions:")
 | 
			
		||||
v.Build[0] = "?"
 | 
			
		||||
 | 
			
		||||
err = v.Validate()
 | 
			
		||||
if err != nil {
 | 
			
		||||
    fmt.Printf("Validation failed: %s\n", err)
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Benchmarks
 | 
			
		||||
-----
 | 
			
		||||
 | 
			
		||||
    BenchmarkParseSimple-4           5000000    390    ns/op    48 B/op   1 allocs/op
 | 
			
		||||
    BenchmarkParseComplex-4          1000000   1813    ns/op   256 B/op   7 allocs/op
 | 
			
		||||
    BenchmarkParseAverage-4          1000000   1171    ns/op   163 B/op   4 allocs/op
 | 
			
		||||
    BenchmarkStringSimple-4         20000000    119    ns/op    16 B/op   1 allocs/op
 | 
			
		||||
    BenchmarkStringLarger-4         10000000    206    ns/op    32 B/op   2 allocs/op
 | 
			
		||||
    BenchmarkStringComplex-4         5000000    324    ns/op    80 B/op   3 allocs/op
 | 
			
		||||
    BenchmarkStringAverage-4         5000000    273    ns/op    53 B/op   2 allocs/op
 | 
			
		||||
    BenchmarkValidateSimple-4      200000000      9.33 ns/op     0 B/op   0 allocs/op
 | 
			
		||||
    BenchmarkValidateComplex-4       3000000    469    ns/op     0 B/op   0 allocs/op
 | 
			
		||||
    BenchmarkValidateAverage-4       5000000    256    ns/op     0 B/op   0 allocs/op
 | 
			
		||||
    BenchmarkCompareSimple-4       100000000     11.8  ns/op     0 B/op   0 allocs/op
 | 
			
		||||
    BenchmarkCompareComplex-4       50000000     30.8  ns/op     0 B/op   0 allocs/op
 | 
			
		||||
    BenchmarkCompareAverage-4       30000000     41.5  ns/op     0 B/op   0 allocs/op
 | 
			
		||||
    BenchmarkSort-4                  3000000    419    ns/op   256 B/op   2 allocs/op
 | 
			
		||||
    BenchmarkRangeParseSimple-4      2000000    850    ns/op   192 B/op   5 allocs/op
 | 
			
		||||
    BenchmarkRangeParseAverage-4     1000000   1677    ns/op   400 B/op  10 allocs/op
 | 
			
		||||
    BenchmarkRangeParseComplex-4      300000   5214    ns/op  1440 B/op  30 allocs/op
 | 
			
		||||
    BenchmarkRangeMatchSimple-4     50000000     25.6  ns/op     0 B/op   0 allocs/op
 | 
			
		||||
    BenchmarkRangeMatchAverage-4    30000000     56.4  ns/op     0 B/op   0 allocs/op
 | 
			
		||||
    BenchmarkRangeMatchComplex-4    10000000    153    ns/op     0 B/op   0 allocs/op
 | 
			
		||||
 | 
			
		||||
See benchmark cases at [semver_test.go](semver_test.go)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Motivation
 | 
			
		||||
-----
 | 
			
		||||
 | 
			
		||||
I simply couldn't find any lib supporting the full spec. Others were just wrong or used reflection and regex which i don't like.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Contribution
 | 
			
		||||
-----
 | 
			
		||||
 | 
			
		||||
Feel free to make a pull request. For bigger changes create a issue first to discuss about it.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
License
 | 
			
		||||
-----
 | 
			
		||||
 | 
			
		||||
See [LICENSE](LICENSE) file.
 | 
			
		||||
							
								
								
									
										23
									
								
								vendor/github.com/blang/semver/json.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								vendor/github.com/blang/semver/json.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,23 @@
 | 
			
		||||
package semver
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"encoding/json"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// MarshalJSON implements the encoding/json.Marshaler interface.
 | 
			
		||||
func (v Version) MarshalJSON() ([]byte, error) {
 | 
			
		||||
	return json.Marshal(v.String())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// UnmarshalJSON implements the encoding/json.Unmarshaler interface.
 | 
			
		||||
func (v *Version) UnmarshalJSON(data []byte) (err error) {
 | 
			
		||||
	var versionString string
 | 
			
		||||
 | 
			
		||||
	if err = json.Unmarshal(data, &versionString); err != nil {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	*v, err = Parse(versionString)
 | 
			
		||||
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										17
									
								
								vendor/github.com/blang/semver/package.json
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								vendor/github.com/blang/semver/package.json
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,17 @@
 | 
			
		||||
{
 | 
			
		||||
  "author": "blang",
 | 
			
		||||
  "bugs": {
 | 
			
		||||
    "URL": "https://github.com/blang/semver/issues",
 | 
			
		||||
    "url": "https://github.com/blang/semver/issues"
 | 
			
		||||
  },
 | 
			
		||||
  "gx": {
 | 
			
		||||
    "dvcsimport": "github.com/blang/semver"
 | 
			
		||||
  },
 | 
			
		||||
  "gxVersion": "0.10.0",
 | 
			
		||||
  "language": "go",
 | 
			
		||||
  "license": "MIT",
 | 
			
		||||
  "name": "semver",
 | 
			
		||||
  "releaseCmd": "git commit -a -m \"gx publish $VERSION\"",
 | 
			
		||||
  "version": "3.5.1"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										416
									
								
								vendor/github.com/blang/semver/range.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										416
									
								
								vendor/github.com/blang/semver/range.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,416 @@
 | 
			
		||||
package semver
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"strconv"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"unicode"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type wildcardType int
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	noneWildcard  wildcardType = iota
 | 
			
		||||
	majorWildcard wildcardType = 1
 | 
			
		||||
	minorWildcard wildcardType = 2
 | 
			
		||||
	patchWildcard wildcardType = 3
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func wildcardTypefromInt(i int) wildcardType {
 | 
			
		||||
	switch i {
 | 
			
		||||
	case 1:
 | 
			
		||||
		return majorWildcard
 | 
			
		||||
	case 2:
 | 
			
		||||
		return minorWildcard
 | 
			
		||||
	case 3:
 | 
			
		||||
		return patchWildcard
 | 
			
		||||
	default:
 | 
			
		||||
		return noneWildcard
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type comparator func(Version, Version) bool
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	compEQ comparator = func(v1 Version, v2 Version) bool {
 | 
			
		||||
		return v1.Compare(v2) == 0
 | 
			
		||||
	}
 | 
			
		||||
	compNE = func(v1 Version, v2 Version) bool {
 | 
			
		||||
		return v1.Compare(v2) != 0
 | 
			
		||||
	}
 | 
			
		||||
	compGT = func(v1 Version, v2 Version) bool {
 | 
			
		||||
		return v1.Compare(v2) == 1
 | 
			
		||||
	}
 | 
			
		||||
	compGE = func(v1 Version, v2 Version) bool {
 | 
			
		||||
		return v1.Compare(v2) >= 0
 | 
			
		||||
	}
 | 
			
		||||
	compLT = func(v1 Version, v2 Version) bool {
 | 
			
		||||
		return v1.Compare(v2) == -1
 | 
			
		||||
	}
 | 
			
		||||
	compLE = func(v1 Version, v2 Version) bool {
 | 
			
		||||
		return v1.Compare(v2) <= 0
 | 
			
		||||
	}
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type versionRange struct {
 | 
			
		||||
	v Version
 | 
			
		||||
	c comparator
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// rangeFunc creates a Range from the given versionRange.
 | 
			
		||||
func (vr *versionRange) rangeFunc() Range {
 | 
			
		||||
	return Range(func(v Version) bool {
 | 
			
		||||
		return vr.c(v, vr.v)
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Range represents a range of versions.
 | 
			
		||||
// A Range can be used to check if a Version satisfies it:
 | 
			
		||||
//
 | 
			
		||||
//     range, err := semver.ParseRange(">1.0.0 <2.0.0")
 | 
			
		||||
//     range(semver.MustParse("1.1.1") // returns true
 | 
			
		||||
type Range func(Version) bool
 | 
			
		||||
 | 
			
		||||
// OR combines the existing Range with another Range using logical OR.
 | 
			
		||||
func (rf Range) OR(f Range) Range {
 | 
			
		||||
	return Range(func(v Version) bool {
 | 
			
		||||
		return rf(v) || f(v)
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// AND combines the existing Range with another Range using logical AND.
 | 
			
		||||
func (rf Range) AND(f Range) Range {
 | 
			
		||||
	return Range(func(v Version) bool {
 | 
			
		||||
		return rf(v) && f(v)
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ParseRange parses a range and returns a Range.
 | 
			
		||||
// If the range could not be parsed an error is returned.
 | 
			
		||||
//
 | 
			
		||||
// Valid ranges are:
 | 
			
		||||
//   - "<1.0.0"
 | 
			
		||||
//   - "<=1.0.0"
 | 
			
		||||
//   - ">1.0.0"
 | 
			
		||||
//   - ">=1.0.0"
 | 
			
		||||
//   - "1.0.0", "=1.0.0", "==1.0.0"
 | 
			
		||||
//   - "!1.0.0", "!=1.0.0"
 | 
			
		||||
//
 | 
			
		||||
// A Range can consist of multiple ranges separated by space:
 | 
			
		||||
// Ranges can be linked by logical AND:
 | 
			
		||||
//   - ">1.0.0 <2.0.0" would match between both ranges, so "1.1.1" and "1.8.7" but not "1.0.0" or "2.0.0"
 | 
			
		||||
//   - ">1.0.0 <3.0.0 !2.0.3-beta.2" would match every version between 1.0.0 and 3.0.0 except 2.0.3-beta.2
 | 
			
		||||
//
 | 
			
		||||
// Ranges can also be linked by logical OR:
 | 
			
		||||
//   - "<2.0.0 || >=3.0.0" would match "1.x.x" and "3.x.x" but not "2.x.x"
 | 
			
		||||
//
 | 
			
		||||
// AND has a higher precedence than OR. It's not possible to use brackets.
 | 
			
		||||
//
 | 
			
		||||
// Ranges can be combined by both AND and OR
 | 
			
		||||
//
 | 
			
		||||
//  - `>1.0.0 <2.0.0 || >3.0.0 !4.2.1` would match `1.2.3`, `1.9.9`, `3.1.1`, but not `4.2.1`, `2.1.1`
 | 
			
		||||
func ParseRange(s string) (Range, error) {
 | 
			
		||||
	parts := splitAndTrim(s)
 | 
			
		||||
	orParts, err := splitORParts(parts)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	expandedParts, err := expandWildcardVersion(orParts)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	var orFn Range
 | 
			
		||||
	for _, p := range expandedParts {
 | 
			
		||||
		var andFn Range
 | 
			
		||||
		for _, ap := range p {
 | 
			
		||||
			opStr, vStr, err := splitComparatorVersion(ap)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				return nil, err
 | 
			
		||||
			}
 | 
			
		||||
			vr, err := buildVersionRange(opStr, vStr)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				return nil, fmt.Errorf("Could not parse Range %q: %s", ap, err)
 | 
			
		||||
			}
 | 
			
		||||
			rf := vr.rangeFunc()
 | 
			
		||||
 | 
			
		||||
			// Set function
 | 
			
		||||
			if andFn == nil {
 | 
			
		||||
				andFn = rf
 | 
			
		||||
			} else { // Combine with existing function
 | 
			
		||||
				andFn = andFn.AND(rf)
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		if orFn == nil {
 | 
			
		||||
			orFn = andFn
 | 
			
		||||
		} else {
 | 
			
		||||
			orFn = orFn.OR(andFn)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
	return orFn, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// splitORParts splits the already cleaned parts by '||'.
 | 
			
		||||
// Checks for invalid positions of the operator and returns an
 | 
			
		||||
// error if found.
 | 
			
		||||
func splitORParts(parts []string) ([][]string, error) {
 | 
			
		||||
	var ORparts [][]string
 | 
			
		||||
	last := 0
 | 
			
		||||
	for i, p := range parts {
 | 
			
		||||
		if p == "||" {
 | 
			
		||||
			if i == 0 {
 | 
			
		||||
				return nil, fmt.Errorf("First element in range is '||'")
 | 
			
		||||
			}
 | 
			
		||||
			ORparts = append(ORparts, parts[last:i])
 | 
			
		||||
			last = i + 1
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if last == len(parts) {
 | 
			
		||||
		return nil, fmt.Errorf("Last element in range is '||'")
 | 
			
		||||
	}
 | 
			
		||||
	ORparts = append(ORparts, parts[last:])
 | 
			
		||||
	return ORparts, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// buildVersionRange takes a slice of 2: operator and version
 | 
			
		||||
// and builds a versionRange, otherwise an error.
 | 
			
		||||
func buildVersionRange(opStr, vStr string) (*versionRange, error) {
 | 
			
		||||
	c := parseComparator(opStr)
 | 
			
		||||
	if c == nil {
 | 
			
		||||
		return nil, fmt.Errorf("Could not parse comparator %q in %q", opStr, strings.Join([]string{opStr, vStr}, ""))
 | 
			
		||||
	}
 | 
			
		||||
	v, err := Parse(vStr)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, fmt.Errorf("Could not parse version %q in %q: %s", vStr, strings.Join([]string{opStr, vStr}, ""), err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return &versionRange{
 | 
			
		||||
		v: v,
 | 
			
		||||
		c: c,
 | 
			
		||||
	}, nil
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// inArray checks if a byte is contained in an array of bytes
 | 
			
		||||
func inArray(s byte, list []byte) bool {
 | 
			
		||||
	for _, el := range list {
 | 
			
		||||
		if el == s {
 | 
			
		||||
			return true
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return false
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// splitAndTrim splits a range string by spaces and cleans whitespaces
 | 
			
		||||
func splitAndTrim(s string) (result []string) {
 | 
			
		||||
	last := 0
 | 
			
		||||
	var lastChar byte
 | 
			
		||||
	excludeFromSplit := []byte{'>', '<', '='}
 | 
			
		||||
	for i := 0; i < len(s); i++ {
 | 
			
		||||
		if s[i] == ' ' && !inArray(lastChar, excludeFromSplit) {
 | 
			
		||||
			if last < i-1 {
 | 
			
		||||
				result = append(result, s[last:i])
 | 
			
		||||
			}
 | 
			
		||||
			last = i + 1
 | 
			
		||||
		} else if s[i] != ' ' {
 | 
			
		||||
			lastChar = s[i]
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if last < len(s)-1 {
 | 
			
		||||
		result = append(result, s[last:])
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for i, v := range result {
 | 
			
		||||
		result[i] = strings.Replace(v, " ", "", -1)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// parts := strings.Split(s, " ")
 | 
			
		||||
	// for _, x := range parts {
 | 
			
		||||
	// 	if s := strings.TrimSpace(x); len(s) != 0 {
 | 
			
		||||
	// 		result = append(result, s)
 | 
			
		||||
	// 	}
 | 
			
		||||
	// }
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// splitComparatorVersion splits the comparator from the version.
 | 
			
		||||
// Input must be free of leading or trailing spaces.
 | 
			
		||||
func splitComparatorVersion(s string) (string, string, error) {
 | 
			
		||||
	i := strings.IndexFunc(s, unicode.IsDigit)
 | 
			
		||||
	if i == -1 {
 | 
			
		||||
		return "", "", fmt.Errorf("Could not get version from string: %q", s)
 | 
			
		||||
	}
 | 
			
		||||
	return strings.TrimSpace(s[0:i]), s[i:], nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// getWildcardType will return the type of wildcard that the
 | 
			
		||||
// passed version contains
 | 
			
		||||
func getWildcardType(vStr string) wildcardType {
 | 
			
		||||
	parts := strings.Split(vStr, ".")
 | 
			
		||||
	nparts := len(parts)
 | 
			
		||||
	wildcard := parts[nparts-1]
 | 
			
		||||
 | 
			
		||||
	possibleWildcardType := wildcardTypefromInt(nparts)
 | 
			
		||||
	if wildcard == "x" {
 | 
			
		||||
		return possibleWildcardType
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return noneWildcard
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// createVersionFromWildcard will convert a wildcard version
 | 
			
		||||
// into a regular version, replacing 'x's with '0's, handling
 | 
			
		||||
// special cases like '1.x.x' and '1.x'
 | 
			
		||||
func createVersionFromWildcard(vStr string) string {
 | 
			
		||||
	// handle 1.x.x
 | 
			
		||||
	vStr2 := strings.Replace(vStr, ".x.x", ".x", 1)
 | 
			
		||||
	vStr2 = strings.Replace(vStr2, ".x", ".0", 1)
 | 
			
		||||
	parts := strings.Split(vStr2, ".")
 | 
			
		||||
 | 
			
		||||
	// handle 1.x
 | 
			
		||||
	if len(parts) == 2 {
 | 
			
		||||
		return vStr2 + ".0"
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return vStr2
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// incrementMajorVersion will increment the major version
 | 
			
		||||
// of the passed version
 | 
			
		||||
func incrementMajorVersion(vStr string) (string, error) {
 | 
			
		||||
	parts := strings.Split(vStr, ".")
 | 
			
		||||
	i, err := strconv.Atoi(parts[0])
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return "", err
 | 
			
		||||
	}
 | 
			
		||||
	parts[0] = strconv.Itoa(i + 1)
 | 
			
		||||
 | 
			
		||||
	return strings.Join(parts, "."), nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// incrementMajorVersion will increment the minor version
 | 
			
		||||
// of the passed version
 | 
			
		||||
func incrementMinorVersion(vStr string) (string, error) {
 | 
			
		||||
	parts := strings.Split(vStr, ".")
 | 
			
		||||
	i, err := strconv.Atoi(parts[1])
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return "", err
 | 
			
		||||
	}
 | 
			
		||||
	parts[1] = strconv.Itoa(i + 1)
 | 
			
		||||
 | 
			
		||||
	return strings.Join(parts, "."), nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// expandWildcardVersion will expand wildcards inside versions
 | 
			
		||||
// following these rules:
 | 
			
		||||
//
 | 
			
		||||
// * when dealing with patch wildcards:
 | 
			
		||||
// >= 1.2.x    will become    >= 1.2.0
 | 
			
		||||
// <= 1.2.x    will become    <  1.3.0
 | 
			
		||||
// >  1.2.x    will become    >= 1.3.0
 | 
			
		||||
// <  1.2.x    will become    <  1.2.0
 | 
			
		||||
// != 1.2.x    will become    <  1.2.0 >= 1.3.0
 | 
			
		||||
//
 | 
			
		||||
// * when dealing with minor wildcards:
 | 
			
		||||
// >= 1.x      will become    >= 1.0.0
 | 
			
		||||
// <= 1.x      will become    <  2.0.0
 | 
			
		||||
// >  1.x      will become    >= 2.0.0
 | 
			
		||||
// <  1.0      will become    <  1.0.0
 | 
			
		||||
// != 1.x      will become    <  1.0.0 >= 2.0.0
 | 
			
		||||
//
 | 
			
		||||
// * when dealing with wildcards without
 | 
			
		||||
// version operator:
 | 
			
		||||
// 1.2.x       will become    >= 1.2.0 < 1.3.0
 | 
			
		||||
// 1.x         will become    >= 1.0.0 < 2.0.0
 | 
			
		||||
func expandWildcardVersion(parts [][]string) ([][]string, error) {
 | 
			
		||||
	var expandedParts [][]string
 | 
			
		||||
	for _, p := range parts {
 | 
			
		||||
		var newParts []string
 | 
			
		||||
		for _, ap := range p {
 | 
			
		||||
			if strings.Index(ap, "x") != -1 {
 | 
			
		||||
				opStr, vStr, err := splitComparatorVersion(ap)
 | 
			
		||||
				if err != nil {
 | 
			
		||||
					return nil, err
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				versionWildcardType := getWildcardType(vStr)
 | 
			
		||||
				flatVersion := createVersionFromWildcard(vStr)
 | 
			
		||||
 | 
			
		||||
				var resultOperator string
 | 
			
		||||
				var shouldIncrementVersion bool
 | 
			
		||||
				switch opStr {
 | 
			
		||||
				case ">":
 | 
			
		||||
					resultOperator = ">="
 | 
			
		||||
					shouldIncrementVersion = true
 | 
			
		||||
				case ">=":
 | 
			
		||||
					resultOperator = ">="
 | 
			
		||||
				case "<":
 | 
			
		||||
					resultOperator = "<"
 | 
			
		||||
				case "<=":
 | 
			
		||||
					resultOperator = "<"
 | 
			
		||||
					shouldIncrementVersion = true
 | 
			
		||||
				case "", "=", "==":
 | 
			
		||||
					newParts = append(newParts, ">="+flatVersion)
 | 
			
		||||
					resultOperator = "<"
 | 
			
		||||
					shouldIncrementVersion = true
 | 
			
		||||
				case "!=", "!":
 | 
			
		||||
					newParts = append(newParts, "<"+flatVersion)
 | 
			
		||||
					resultOperator = ">="
 | 
			
		||||
					shouldIncrementVersion = true
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				var resultVersion string
 | 
			
		||||
				if shouldIncrementVersion {
 | 
			
		||||
					switch versionWildcardType {
 | 
			
		||||
					case patchWildcard:
 | 
			
		||||
						resultVersion, _ = incrementMinorVersion(flatVersion)
 | 
			
		||||
					case minorWildcard:
 | 
			
		||||
						resultVersion, _ = incrementMajorVersion(flatVersion)
 | 
			
		||||
					}
 | 
			
		||||
				} else {
 | 
			
		||||
					resultVersion = flatVersion
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				ap = resultOperator + resultVersion
 | 
			
		||||
			}
 | 
			
		||||
			newParts = append(newParts, ap)
 | 
			
		||||
		}
 | 
			
		||||
		expandedParts = append(expandedParts, newParts)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return expandedParts, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func parseComparator(s string) comparator {
 | 
			
		||||
	switch s {
 | 
			
		||||
	case "==":
 | 
			
		||||
		fallthrough
 | 
			
		||||
	case "":
 | 
			
		||||
		fallthrough
 | 
			
		||||
	case "=":
 | 
			
		||||
		return compEQ
 | 
			
		||||
	case ">":
 | 
			
		||||
		return compGT
 | 
			
		||||
	case ">=":
 | 
			
		||||
		return compGE
 | 
			
		||||
	case "<":
 | 
			
		||||
		return compLT
 | 
			
		||||
	case "<=":
 | 
			
		||||
		return compLE
 | 
			
		||||
	case "!":
 | 
			
		||||
		fallthrough
 | 
			
		||||
	case "!=":
 | 
			
		||||
		return compNE
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// MustParseRange is like ParseRange but panics if the range cannot be parsed.
 | 
			
		||||
func MustParseRange(s string) Range {
 | 
			
		||||
	r, err := ParseRange(s)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		panic(`semver: ParseRange(` + s + `): ` + err.Error())
 | 
			
		||||
	}
 | 
			
		||||
	return r
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										418
									
								
								vendor/github.com/blang/semver/semver.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										418
									
								
								vendor/github.com/blang/semver/semver.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,418 @@
 | 
			
		||||
package semver
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"errors"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"strconv"
 | 
			
		||||
	"strings"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	numbers  string = "0123456789"
 | 
			
		||||
	alphas          = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-"
 | 
			
		||||
	alphanum        = alphas + numbers
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// SpecVersion is the latest fully supported spec version of semver
 | 
			
		||||
var SpecVersion = Version{
 | 
			
		||||
	Major: 2,
 | 
			
		||||
	Minor: 0,
 | 
			
		||||
	Patch: 0,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Version represents a semver compatible version
 | 
			
		||||
type Version struct {
 | 
			
		||||
	Major uint64
 | 
			
		||||
	Minor uint64
 | 
			
		||||
	Patch uint64
 | 
			
		||||
	Pre   []PRVersion
 | 
			
		||||
	Build []string //No Precendence
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Version to string
 | 
			
		||||
func (v Version) String() string {
 | 
			
		||||
	b := make([]byte, 0, 5)
 | 
			
		||||
	b = strconv.AppendUint(b, v.Major, 10)
 | 
			
		||||
	b = append(b, '.')
 | 
			
		||||
	b = strconv.AppendUint(b, v.Minor, 10)
 | 
			
		||||
	b = append(b, '.')
 | 
			
		||||
	b = strconv.AppendUint(b, v.Patch, 10)
 | 
			
		||||
 | 
			
		||||
	if len(v.Pre) > 0 {
 | 
			
		||||
		b = append(b, '-')
 | 
			
		||||
		b = append(b, v.Pre[0].String()...)
 | 
			
		||||
 | 
			
		||||
		for _, pre := range v.Pre[1:] {
 | 
			
		||||
			b = append(b, '.')
 | 
			
		||||
			b = append(b, pre.String()...)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if len(v.Build) > 0 {
 | 
			
		||||
		b = append(b, '+')
 | 
			
		||||
		b = append(b, v.Build[0]...)
 | 
			
		||||
 | 
			
		||||
		for _, build := range v.Build[1:] {
 | 
			
		||||
			b = append(b, '.')
 | 
			
		||||
			b = append(b, build...)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return string(b)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Equals checks if v is equal to o.
 | 
			
		||||
func (v Version) Equals(o Version) bool {
 | 
			
		||||
	return (v.Compare(o) == 0)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// EQ checks if v is equal to o.
 | 
			
		||||
func (v Version) EQ(o Version) bool {
 | 
			
		||||
	return (v.Compare(o) == 0)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NE checks if v is not equal to o.
 | 
			
		||||
func (v Version) NE(o Version) bool {
 | 
			
		||||
	return (v.Compare(o) != 0)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// GT checks if v is greater than o.
 | 
			
		||||
func (v Version) GT(o Version) bool {
 | 
			
		||||
	return (v.Compare(o) == 1)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// GTE checks if v is greater than or equal to o.
 | 
			
		||||
func (v Version) GTE(o Version) bool {
 | 
			
		||||
	return (v.Compare(o) >= 0)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// GE checks if v is greater than or equal to o.
 | 
			
		||||
func (v Version) GE(o Version) bool {
 | 
			
		||||
	return (v.Compare(o) >= 0)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// LT checks if v is less than o.
 | 
			
		||||
func (v Version) LT(o Version) bool {
 | 
			
		||||
	return (v.Compare(o) == -1)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// LTE checks if v is less than or equal to o.
 | 
			
		||||
func (v Version) LTE(o Version) bool {
 | 
			
		||||
	return (v.Compare(o) <= 0)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// LE checks if v is less than or equal to o.
 | 
			
		||||
func (v Version) LE(o Version) bool {
 | 
			
		||||
	return (v.Compare(o) <= 0)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Compare compares Versions v to o:
 | 
			
		||||
// -1 == v is less than o
 | 
			
		||||
// 0 == v is equal to o
 | 
			
		||||
// 1 == v is greater than o
 | 
			
		||||
func (v Version) Compare(o Version) int {
 | 
			
		||||
	if v.Major != o.Major {
 | 
			
		||||
		if v.Major > o.Major {
 | 
			
		||||
			return 1
 | 
			
		||||
		}
 | 
			
		||||
		return -1
 | 
			
		||||
	}
 | 
			
		||||
	if v.Minor != o.Minor {
 | 
			
		||||
		if v.Minor > o.Minor {
 | 
			
		||||
			return 1
 | 
			
		||||
		}
 | 
			
		||||
		return -1
 | 
			
		||||
	}
 | 
			
		||||
	if v.Patch != o.Patch {
 | 
			
		||||
		if v.Patch > o.Patch {
 | 
			
		||||
			return 1
 | 
			
		||||
		}
 | 
			
		||||
		return -1
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Quick comparison if a version has no prerelease versions
 | 
			
		||||
	if len(v.Pre) == 0 && len(o.Pre) == 0 {
 | 
			
		||||
		return 0
 | 
			
		||||
	} else if len(v.Pre) == 0 && len(o.Pre) > 0 {
 | 
			
		||||
		return 1
 | 
			
		||||
	} else if len(v.Pre) > 0 && len(o.Pre) == 0 {
 | 
			
		||||
		return -1
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	i := 0
 | 
			
		||||
	for ; i < len(v.Pre) && i < len(o.Pre); i++ {
 | 
			
		||||
		if comp := v.Pre[i].Compare(o.Pre[i]); comp == 0 {
 | 
			
		||||
			continue
 | 
			
		||||
		} else if comp == 1 {
 | 
			
		||||
			return 1
 | 
			
		||||
		} else {
 | 
			
		||||
			return -1
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// If all pr versions are the equal but one has further prversion, this one greater
 | 
			
		||||
	if i == len(v.Pre) && i == len(o.Pre) {
 | 
			
		||||
		return 0
 | 
			
		||||
	} else if i == len(v.Pre) && i < len(o.Pre) {
 | 
			
		||||
		return -1
 | 
			
		||||
	} else {
 | 
			
		||||
		return 1
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Validate validates v and returns error in case
 | 
			
		||||
func (v Version) Validate() error {
 | 
			
		||||
	// Major, Minor, Patch already validated using uint64
 | 
			
		||||
 | 
			
		||||
	for _, pre := range v.Pre {
 | 
			
		||||
		if !pre.IsNum { //Numeric prerelease versions already uint64
 | 
			
		||||
			if len(pre.VersionStr) == 0 {
 | 
			
		||||
				return fmt.Errorf("Prerelease can not be empty %q", pre.VersionStr)
 | 
			
		||||
			}
 | 
			
		||||
			if !containsOnly(pre.VersionStr, alphanum) {
 | 
			
		||||
				return fmt.Errorf("Invalid character(s) found in prerelease %q", pre.VersionStr)
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for _, build := range v.Build {
 | 
			
		||||
		if len(build) == 0 {
 | 
			
		||||
			return fmt.Errorf("Build meta data can not be empty %q", build)
 | 
			
		||||
		}
 | 
			
		||||
		if !containsOnly(build, alphanum) {
 | 
			
		||||
			return fmt.Errorf("Invalid character(s) found in build meta data %q", build)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// New is an alias for Parse and returns a pointer, parses version string and returns a validated Version or error
 | 
			
		||||
func New(s string) (vp *Version, err error) {
 | 
			
		||||
	v, err := Parse(s)
 | 
			
		||||
	vp = &v
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Make is an alias for Parse, parses version string and returns a validated Version or error
 | 
			
		||||
func Make(s string) (Version, error) {
 | 
			
		||||
	return Parse(s)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ParseTolerant allows for certain version specifications that do not strictly adhere to semver
 | 
			
		||||
// specs to be parsed by this library. It does so by normalizing versions before passing them to
 | 
			
		||||
// Parse(). It currently trims spaces, removes a "v" prefix, and adds a 0 patch number to versions
 | 
			
		||||
// with only major and minor components specified
 | 
			
		||||
func ParseTolerant(s string) (Version, error) {
 | 
			
		||||
	s = strings.TrimSpace(s)
 | 
			
		||||
	s = strings.TrimPrefix(s, "v")
 | 
			
		||||
 | 
			
		||||
	// Split into major.minor.(patch+pr+meta)
 | 
			
		||||
	parts := strings.SplitN(s, ".", 3)
 | 
			
		||||
	if len(parts) < 3 {
 | 
			
		||||
		if strings.ContainsAny(parts[len(parts)-1], "+-") {
 | 
			
		||||
			return Version{}, errors.New("Short version cannot contain PreRelease/Build meta data")
 | 
			
		||||
		}
 | 
			
		||||
		for len(parts) < 3 {
 | 
			
		||||
			parts = append(parts, "0")
 | 
			
		||||
		}
 | 
			
		||||
		s = strings.Join(parts, ".")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return Parse(s)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Parse parses version string and returns a validated Version or error
 | 
			
		||||
func Parse(s string) (Version, error) {
 | 
			
		||||
	if len(s) == 0 {
 | 
			
		||||
		return Version{}, errors.New("Version string empty")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Split into major.minor.(patch+pr+meta)
 | 
			
		||||
	parts := strings.SplitN(s, ".", 3)
 | 
			
		||||
	if len(parts) != 3 {
 | 
			
		||||
		return Version{}, errors.New("No Major.Minor.Patch elements found")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Major
 | 
			
		||||
	if !containsOnly(parts[0], numbers) {
 | 
			
		||||
		return Version{}, fmt.Errorf("Invalid character(s) found in major number %q", parts[0])
 | 
			
		||||
	}
 | 
			
		||||
	if hasLeadingZeroes(parts[0]) {
 | 
			
		||||
		return Version{}, fmt.Errorf("Major number must not contain leading zeroes %q", parts[0])
 | 
			
		||||
	}
 | 
			
		||||
	major, err := strconv.ParseUint(parts[0], 10, 64)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return Version{}, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Minor
 | 
			
		||||
	if !containsOnly(parts[1], numbers) {
 | 
			
		||||
		return Version{}, fmt.Errorf("Invalid character(s) found in minor number %q", parts[1])
 | 
			
		||||
	}
 | 
			
		||||
	if hasLeadingZeroes(parts[1]) {
 | 
			
		||||
		return Version{}, fmt.Errorf("Minor number must not contain leading zeroes %q", parts[1])
 | 
			
		||||
	}
 | 
			
		||||
	minor, err := strconv.ParseUint(parts[1], 10, 64)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return Version{}, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	v := Version{}
 | 
			
		||||
	v.Major = major
 | 
			
		||||
	v.Minor = minor
 | 
			
		||||
 | 
			
		||||
	var build, prerelease []string
 | 
			
		||||
	patchStr := parts[2]
 | 
			
		||||
 | 
			
		||||
	if buildIndex := strings.IndexRune(patchStr, '+'); buildIndex != -1 {
 | 
			
		||||
		build = strings.Split(patchStr[buildIndex+1:], ".")
 | 
			
		||||
		patchStr = patchStr[:buildIndex]
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if preIndex := strings.IndexRune(patchStr, '-'); preIndex != -1 {
 | 
			
		||||
		prerelease = strings.Split(patchStr[preIndex+1:], ".")
 | 
			
		||||
		patchStr = patchStr[:preIndex]
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if !containsOnly(patchStr, numbers) {
 | 
			
		||||
		return Version{}, fmt.Errorf("Invalid character(s) found in patch number %q", patchStr)
 | 
			
		||||
	}
 | 
			
		||||
	if hasLeadingZeroes(patchStr) {
 | 
			
		||||
		return Version{}, fmt.Errorf("Patch number must not contain leading zeroes %q", patchStr)
 | 
			
		||||
	}
 | 
			
		||||
	patch, err := strconv.ParseUint(patchStr, 10, 64)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return Version{}, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	v.Patch = patch
 | 
			
		||||
 | 
			
		||||
	// Prerelease
 | 
			
		||||
	for _, prstr := range prerelease {
 | 
			
		||||
		parsedPR, err := NewPRVersion(prstr)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return Version{}, err
 | 
			
		||||
		}
 | 
			
		||||
		v.Pre = append(v.Pre, parsedPR)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Build meta data
 | 
			
		||||
	for _, str := range build {
 | 
			
		||||
		if len(str) == 0 {
 | 
			
		||||
			return Version{}, errors.New("Build meta data is empty")
 | 
			
		||||
		}
 | 
			
		||||
		if !containsOnly(str, alphanum) {
 | 
			
		||||
			return Version{}, fmt.Errorf("Invalid character(s) found in build meta data %q", str)
 | 
			
		||||
		}
 | 
			
		||||
		v.Build = append(v.Build, str)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return v, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// MustParse is like Parse but panics if the version cannot be parsed.
 | 
			
		||||
func MustParse(s string) Version {
 | 
			
		||||
	v, err := Parse(s)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		panic(`semver: Parse(` + s + `): ` + err.Error())
 | 
			
		||||
	}
 | 
			
		||||
	return v
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// PRVersion represents a PreRelease Version
 | 
			
		||||
type PRVersion struct {
 | 
			
		||||
	VersionStr string
 | 
			
		||||
	VersionNum uint64
 | 
			
		||||
	IsNum      bool
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewPRVersion creates a new valid prerelease version
 | 
			
		||||
func NewPRVersion(s string) (PRVersion, error) {
 | 
			
		||||
	if len(s) == 0 {
 | 
			
		||||
		return PRVersion{}, errors.New("Prerelease is empty")
 | 
			
		||||
	}
 | 
			
		||||
	v := PRVersion{}
 | 
			
		||||
	if containsOnly(s, numbers) {
 | 
			
		||||
		if hasLeadingZeroes(s) {
 | 
			
		||||
			return PRVersion{}, fmt.Errorf("Numeric PreRelease version must not contain leading zeroes %q", s)
 | 
			
		||||
		}
 | 
			
		||||
		num, err := strconv.ParseUint(s, 10, 64)
 | 
			
		||||
 | 
			
		||||
		// Might never be hit, but just in case
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return PRVersion{}, err
 | 
			
		||||
		}
 | 
			
		||||
		v.VersionNum = num
 | 
			
		||||
		v.IsNum = true
 | 
			
		||||
	} else if containsOnly(s, alphanum) {
 | 
			
		||||
		v.VersionStr = s
 | 
			
		||||
		v.IsNum = false
 | 
			
		||||
	} else {
 | 
			
		||||
		return PRVersion{}, fmt.Errorf("Invalid character(s) found in prerelease %q", s)
 | 
			
		||||
	}
 | 
			
		||||
	return v, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// IsNumeric checks if prerelease-version is numeric
 | 
			
		||||
func (v PRVersion) IsNumeric() bool {
 | 
			
		||||
	return v.IsNum
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Compare compares two PreRelease Versions v and o:
 | 
			
		||||
// -1 == v is less than o
 | 
			
		||||
// 0 == v is equal to o
 | 
			
		||||
// 1 == v is greater than o
 | 
			
		||||
func (v PRVersion) Compare(o PRVersion) int {
 | 
			
		||||
	if v.IsNum && !o.IsNum {
 | 
			
		||||
		return -1
 | 
			
		||||
	} else if !v.IsNum && o.IsNum {
 | 
			
		||||
		return 1
 | 
			
		||||
	} else if v.IsNum && o.IsNum {
 | 
			
		||||
		if v.VersionNum == o.VersionNum {
 | 
			
		||||
			return 0
 | 
			
		||||
		} else if v.VersionNum > o.VersionNum {
 | 
			
		||||
			return 1
 | 
			
		||||
		} else {
 | 
			
		||||
			return -1
 | 
			
		||||
		}
 | 
			
		||||
	} else { // both are Alphas
 | 
			
		||||
		if v.VersionStr == o.VersionStr {
 | 
			
		||||
			return 0
 | 
			
		||||
		} else if v.VersionStr > o.VersionStr {
 | 
			
		||||
			return 1
 | 
			
		||||
		} else {
 | 
			
		||||
			return -1
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// PreRelease version to string
 | 
			
		||||
func (v PRVersion) String() string {
 | 
			
		||||
	if v.IsNum {
 | 
			
		||||
		return strconv.FormatUint(v.VersionNum, 10)
 | 
			
		||||
	}
 | 
			
		||||
	return v.VersionStr
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func containsOnly(s string, set string) bool {
 | 
			
		||||
	return strings.IndexFunc(s, func(r rune) bool {
 | 
			
		||||
		return !strings.ContainsRune(set, r)
 | 
			
		||||
	}) == -1
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func hasLeadingZeroes(s string) bool {
 | 
			
		||||
	return len(s) > 1 && s[0] == '0'
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewBuildVersion creates a new valid build version
 | 
			
		||||
func NewBuildVersion(s string) (string, error) {
 | 
			
		||||
	if len(s) == 0 {
 | 
			
		||||
		return "", errors.New("Buildversion is empty")
 | 
			
		||||
	}
 | 
			
		||||
	if !containsOnly(s, alphanum) {
 | 
			
		||||
		return "", fmt.Errorf("Invalid character(s) found in build meta data %q", s)
 | 
			
		||||
	}
 | 
			
		||||
	return s, nil
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										28
									
								
								vendor/github.com/blang/semver/sort.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								vendor/github.com/blang/semver/sort.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,28 @@
 | 
			
		||||
package semver
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"sort"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Versions represents multiple versions.
 | 
			
		||||
type Versions []Version
 | 
			
		||||
 | 
			
		||||
// Len returns length of version collection
 | 
			
		||||
func (s Versions) Len() int {
 | 
			
		||||
	return len(s)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Swap swaps two versions inside the collection by its indices
 | 
			
		||||
func (s Versions) Swap(i, j int) {
 | 
			
		||||
	s[i], s[j] = s[j], s[i]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Less checks if version at index i is less than version at index j
 | 
			
		||||
func (s Versions) Less(i, j int) bool {
 | 
			
		||||
	return s[i].LT(s[j])
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Sort sorts a slice of versions
 | 
			
		||||
func Sort(versions []Version) {
 | 
			
		||||
	sort.Sort(Versions(versions))
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										30
									
								
								vendor/github.com/blang/semver/sql.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								vendor/github.com/blang/semver/sql.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,30 @@
 | 
			
		||||
package semver
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"database/sql/driver"
 | 
			
		||||
	"fmt"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Scan implements the database/sql.Scanner interface.
 | 
			
		||||
func (v *Version) Scan(src interface{}) (err error) {
 | 
			
		||||
	var str string
 | 
			
		||||
	switch src := src.(type) {
 | 
			
		||||
	case string:
 | 
			
		||||
		str = src
 | 
			
		||||
	case []byte:
 | 
			
		||||
		str = string(src)
 | 
			
		||||
	default:
 | 
			
		||||
		return fmt.Errorf("Version.Scan: cannot convert %T to string.", src)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if t, err := Parse(str); err == nil {
 | 
			
		||||
		*v = t
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Value implements the database/sql/driver.Valuer interface.
 | 
			
		||||
func (v Version) Value() (driver.Value, error) {
 | 
			
		||||
	return v.String(), nil
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										1
									
								
								vendor/github.com/d5/tengo/v2/Makefile
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								vendor/github.com/d5/tengo/v2/Makefile
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -6,6 +6,7 @@ lint:
 | 
			
		||||
 | 
			
		||||
test: generate lint
 | 
			
		||||
	go test -race -cover ./...
 | 
			
		||||
	go run ./cmd/tengo -resolve ./testdata/cli/test.tengo
 | 
			
		||||
 | 
			
		||||
fmt:
 | 
			
		||||
	go fmt ./...
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										35
									
								
								vendor/github.com/d5/tengo/v2/README.md
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										35
									
								
								vendor/github.com/d5/tengo/v2/README.md
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -5,8 +5,8 @@
 | 
			
		||||
# The Tengo Language
 | 
			
		||||
 | 
			
		||||
[](https://godoc.org/github.com/d5/tengo)
 | 
			
		||||

 | 
			
		||||
[](https://goreportcard.com/report/github.com/d5/tengo)
 | 
			
		||||
[](https://circleci.com/gh/d5/tengo)
 | 
			
		||||
 | 
			
		||||
**Tengo is a small, dynamic, fast, secure script language for Go.** 
 | 
			
		||||
 | 
			
		||||
@@ -51,19 +51,21 @@ fmt.println(sum("", [1, 2, 3]))  // "123"
 | 
			
		||||
 | 
			
		||||
## Benchmark
 | 
			
		||||
 | 
			
		||||
| | fib(35) | fibt(35) |  Type  |
 | 
			
		||||
| | fib(35) | fibt(35) |  Language (Type)  |
 | 
			
		||||
| :--- |    ---: |     ---: |  :---: |
 | 
			
		||||
| Go | `48ms` | `3ms` | Go (native) |
 | 
			
		||||
| [**Tengo**](https://github.com/d5/tengo) | `2,349ms` | `5ms` | VM on Go |
 | 
			
		||||
| Lua | `1,416ms` | `3ms` | Lua (native) |
 | 
			
		||||
| [go-lua](https://github.com/Shopify/go-lua) | `4,402ms` | `5ms` | Lua VM on Go |
 | 
			
		||||
| [GopherLua](https://github.com/yuin/gopher-lua) | `4,023ms` | `5ms` | Lua VM on Go |
 | 
			
		||||
| Python | `2,588ms` | `26ms` | Python (native) |
 | 
			
		||||
| [starlark-go](https://github.com/google/starlark-go) | `11,126ms` | `6ms` | Python-like Interpreter on Go |
 | 
			
		||||
| [gpython](https://github.com/go-python/gpython) | `15,035ms` | `4ms` | Python Interpreter on Go |
 | 
			
		||||
| [goja](https://github.com/dop251/goja) | `5,089ms` | `5ms` | JS VM on Go |
 | 
			
		||||
| [otto](https://github.com/robertkrimen/otto) | `68,377ms` | `11ms` | JS Interpreter on Go |
 | 
			
		||||
| [Anko](https://github.com/mattn/anko) | `92,579ms` | `18ms` | Interpreter on Go |
 | 
			
		||||
| [**Tengo**](https://github.com/d5/tengo) | `2,931ms` | `4ms` | Tengo (VM) |
 | 
			
		||||
| [go-lua](https://github.com/Shopify/go-lua) | `4,824ms` | `4ms` | Lua (VM) |
 | 
			
		||||
| [GopherLua](https://github.com/yuin/gopher-lua) | `5,365ms` | `4ms` | Lua (VM) |
 | 
			
		||||
| [goja](https://github.com/dop251/goja) | `5,533ms` | `5ms` | JavaScript (VM) |
 | 
			
		||||
| [starlark-go](https://github.com/google/starlark-go) | `11,495ms` | `5ms` | Starlark (Interpreter) |
 | 
			
		||||
| [Yaegi](https://github.com/containous/yaegi) | `15,645ms` | `12ms` | Yaegi (Interpreter) |
 | 
			
		||||
| [gpython](https://github.com/go-python/gpython) | `16,322ms` | `5ms` | Python (Interpreter) |
 | 
			
		||||
| [otto](https://github.com/robertkrimen/otto) | `73,093ms` | `10ms` | JavaScript (Interpreter) |
 | 
			
		||||
| [Anko](https://github.com/mattn/anko) | `79,809ms` | `8ms` | Anko (Interpreter) |
 | 
			
		||||
| - | - | - | - |
 | 
			
		||||
| Go | `53ms` | `3ms` | Go (Native) |
 | 
			
		||||
| Lua | `1,612ms` | `3ms` | Lua (Native) |
 | 
			
		||||
| Python | `2,632ms` | `23ms` | Python 2 (Native) |
 | 
			
		||||
 | 
			
		||||
_* [fib(35)](https://github.com/d5/tengobench/blob/master/code/fib.tengo):
 | 
			
		||||
Fibonacci(35)_  
 | 
			
		||||
@@ -136,3 +138,10 @@ each([a, b, c, d], func(x) {
 | 
			
		||||
- [Interoperability](https://github.com/d5/tengo/blob/master/docs/interoperability.md)
 | 
			
		||||
- [Tengo CLI](https://github.com/d5/tengo/blob/master/docs/tengo-cli.md)
 | 
			
		||||
- [Standard Library](https://github.com/d5/tengo/blob/master/docs/stdlib.md)
 | 
			
		||||
- Syntax Highlighters: [VSCode](https://github.com/lissein/vscode-tengo), [Atom](https://github.com/d5/tengo-atom)
 | 
			
		||||
- **Why the name Tengo?** It's from [1Q84](https://en.wikipedia.org/wiki/1Q84).
 | 
			
		||||
 | 
			
		||||
##
 | 
			
		||||
 | 
			
		||||
:hearts: Like writing Go code? Come work at Skool. [We're hiring!](https://jobs.lever.co/skool)
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										12
									
								
								vendor/github.com/d5/tengo/v2/bytecode.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										12
									
								
								vendor/github.com/d5/tengo/v2/bytecode.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -97,6 +97,7 @@ func (b *Bytecode) RemoveDuplicates() {
 | 
			
		||||
	var deduped []Object
 | 
			
		||||
 | 
			
		||||
	indexMap := make(map[int]int) // mapping from old constant index to new index
 | 
			
		||||
	fns := make(map[*CompiledFunction]int)
 | 
			
		||||
	ints := make(map[int64]int)
 | 
			
		||||
	strings := make(map[string]int)
 | 
			
		||||
	floats := make(map[float64]int)
 | 
			
		||||
@@ -106,9 +107,14 @@ func (b *Bytecode) RemoveDuplicates() {
 | 
			
		||||
	for curIdx, c := range b.Constants {
 | 
			
		||||
		switch c := c.(type) {
 | 
			
		||||
		case *CompiledFunction:
 | 
			
		||||
			// add to deduped list
 | 
			
		||||
			indexMap[curIdx] = len(deduped)
 | 
			
		||||
			deduped = append(deduped, c)
 | 
			
		||||
			if newIdx, ok := fns[c]; ok {
 | 
			
		||||
				indexMap[curIdx] = newIdx
 | 
			
		||||
			} else {
 | 
			
		||||
				newIdx = len(deduped)
 | 
			
		||||
				fns[c] = newIdx
 | 
			
		||||
				indexMap[curIdx] = newIdx
 | 
			
		||||
				deduped = append(deduped, c)
 | 
			
		||||
			}
 | 
			
		||||
		case *ImmutableMap:
 | 
			
		||||
			modName := inferModuleName(c)
 | 
			
		||||
			newIdx, ok := immutableMaps[modName]
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										56
									
								
								vendor/github.com/d5/tengo/v2/compiler.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										56
									
								
								vendor/github.com/d5/tengo/v2/compiler.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -44,6 +44,7 @@ type Compiler struct {
 | 
			
		||||
	file            *parser.SourceFile
 | 
			
		||||
	parent          *Compiler
 | 
			
		||||
	modulePath      string
 | 
			
		||||
	importDir       string
 | 
			
		||||
	constants       []Object
 | 
			
		||||
	symbolTable     *SymbolTable
 | 
			
		||||
	scopes          []compilationScope
 | 
			
		||||
@@ -322,7 +323,7 @@ func (c *Compiler) Compile(node parser.Node) error {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
	case *parser.Ident:
 | 
			
		||||
		symbol, _, ok := c.symbolTable.Resolve(node.Name)
 | 
			
		||||
		symbol, _, ok := c.symbolTable.Resolve(node.Name, false)
 | 
			
		||||
		if !ok {
 | 
			
		||||
			return c.errorf(node, "unresolved reference '%s'", node.Name)
 | 
			
		||||
		}
 | 
			
		||||
@@ -505,7 +506,11 @@ func (c *Compiler) Compile(node parser.Node) error {
 | 
			
		||||
				return err
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		c.emit(node, parser.OpCall, len(node.Args))
 | 
			
		||||
		ellipsis := 0
 | 
			
		||||
		if node.Ellipsis.IsValid() {
 | 
			
		||||
			ellipsis = 1
 | 
			
		||||
		}
 | 
			
		||||
		c.emit(node, parser.OpCall, len(node.Args), ellipsis)
 | 
			
		||||
	case *parser.ImportExpr:
 | 
			
		||||
		if node.ModuleName == "" {
 | 
			
		||||
			return c.errorf(node, "empty module name")
 | 
			
		||||
@@ -520,12 +525,12 @@ func (c *Compiler) Compile(node parser.Node) error {
 | 
			
		||||
			switch v := v.(type) {
 | 
			
		||||
			case []byte: // module written in Tengo
 | 
			
		||||
				compiled, err := c.compileModule(node,
 | 
			
		||||
					node.ModuleName, node.ModuleName, v)
 | 
			
		||||
					node.ModuleName, v, false)
 | 
			
		||||
				if err != nil {
 | 
			
		||||
					return err
 | 
			
		||||
				}
 | 
			
		||||
				c.emit(node, parser.OpConstant, c.addConstant(compiled))
 | 
			
		||||
				c.emit(node, parser.OpCall, 0)
 | 
			
		||||
				c.emit(node, parser.OpCall, 0, 0)
 | 
			
		||||
			case Object: // builtin module
 | 
			
		||||
				c.emit(node, parser.OpConstant, c.addConstant(v))
 | 
			
		||||
			default:
 | 
			
		||||
@@ -537,29 +542,25 @@ func (c *Compiler) Compile(node parser.Node) error {
 | 
			
		||||
				moduleName += ".tengo"
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			modulePath, err := filepath.Abs(moduleName)
 | 
			
		||||
			modulePath, err := filepath.Abs(
 | 
			
		||||
				filepath.Join(c.importDir, moduleName))
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				return c.errorf(node, "module file path error: %s",
 | 
			
		||||
					err.Error())
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if err := c.checkCyclicImports(node, modulePath); err != nil {
 | 
			
		||||
				return err
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			moduleSrc, err := ioutil.ReadFile(moduleName)
 | 
			
		||||
			moduleSrc, err := ioutil.ReadFile(modulePath)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				return c.errorf(node, "module file read error: %s",
 | 
			
		||||
					err.Error())
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			compiled, err := c.compileModule(node,
 | 
			
		||||
				moduleName, modulePath, moduleSrc)
 | 
			
		||||
			compiled, err := c.compileModule(node, modulePath, moduleSrc, true)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				return err
 | 
			
		||||
			}
 | 
			
		||||
			c.emit(node, parser.OpConstant, c.addConstant(compiled))
 | 
			
		||||
			c.emit(node, parser.OpCall, 0)
 | 
			
		||||
			c.emit(node, parser.OpCall, 0, 0)
 | 
			
		||||
		} else {
 | 
			
		||||
			return c.errorf(node, "module '%s' not found", node.ModuleName)
 | 
			
		||||
		}
 | 
			
		||||
@@ -634,6 +635,11 @@ func (c *Compiler) EnableFileImport(enable bool) {
 | 
			
		||||
	c.allowFileImport = enable
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SetImportDir sets the initial import directory path for file imports.
 | 
			
		||||
func (c *Compiler) SetImportDir(dir string) {
 | 
			
		||||
	c.importDir = dir
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *Compiler) compileAssign(
 | 
			
		||||
	node parser.Node,
 | 
			
		||||
	lhs, rhs []parser.Expr,
 | 
			
		||||
@@ -653,7 +659,7 @@ func (c *Compiler) compileAssign(
 | 
			
		||||
		return c.errorf(node, "operator ':=' not allowed with selector")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	symbol, depth, exists := c.symbolTable.Resolve(ident)
 | 
			
		||||
	symbol, depth, exists := c.symbolTable.Resolve(ident, false)
 | 
			
		||||
	if op == token.Define {
 | 
			
		||||
		if depth == 0 && exists {
 | 
			
		||||
			return c.errorf(node, "'%s' redeclared in this block", ident)
 | 
			
		||||
@@ -847,8 +853,8 @@ func (c *Compiler) compileForInStmt(stmt *parser.ForInStmt) error {
 | 
			
		||||
	//     ... body ...
 | 
			
		||||
	//   }
 | 
			
		||||
	//
 | 
			
		||||
	// ":it" is a local variable but will be conflict with other user variables
 | 
			
		||||
	// because character ":" is not allowed.
 | 
			
		||||
	// ":it" is a local variable but it will not conflict with other user variables
 | 
			
		||||
	// because character ":" is not allowed in the variable names.
 | 
			
		||||
 | 
			
		||||
	// init
 | 
			
		||||
	//   :it = iterator(iterable)
 | 
			
		||||
@@ -893,6 +899,7 @@ func (c *Compiler) compileForInStmt(stmt *parser.ForInStmt) error {
 | 
			
		||||
		if keySymbol.Scope == ScopeGlobal {
 | 
			
		||||
			c.emit(stmt, parser.OpSetGlobal, keySymbol.Index)
 | 
			
		||||
		} else {
 | 
			
		||||
			keySymbol.LocalAssigned = true
 | 
			
		||||
			c.emit(stmt, parser.OpDefineLocal, keySymbol.Index)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
@@ -909,6 +916,7 @@ func (c *Compiler) compileForInStmt(stmt *parser.ForInStmt) error {
 | 
			
		||||
		if valueSymbol.Scope == ScopeGlobal {
 | 
			
		||||
			c.emit(stmt, parser.OpSetGlobal, valueSymbol.Index)
 | 
			
		||||
		} else {
 | 
			
		||||
			valueSymbol.LocalAssigned = true
 | 
			
		||||
			c.emit(stmt, parser.OpDefineLocal, valueSymbol.Index)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
@@ -955,8 +963,9 @@ func (c *Compiler) checkCyclicImports(
 | 
			
		||||
 | 
			
		||||
func (c *Compiler) compileModule(
 | 
			
		||||
	node parser.Node,
 | 
			
		||||
	moduleName, modulePath string,
 | 
			
		||||
	modulePath string,
 | 
			
		||||
	src []byte,
 | 
			
		||||
	isFile bool,
 | 
			
		||||
) (*CompiledFunction, error) {
 | 
			
		||||
	if err := c.checkCyclicImports(node, modulePath); err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
@@ -967,7 +976,7 @@ func (c *Compiler) compileModule(
 | 
			
		||||
		return compiledModule, nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	modFile := c.file.Set().AddFile(moduleName, -1, len(src))
 | 
			
		||||
	modFile := c.file.Set().AddFile(modulePath, -1, len(src))
 | 
			
		||||
	p := parser.NewParser(modFile, src, nil)
 | 
			
		||||
	file, err := p.ParseFile()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
@@ -984,7 +993,7 @@ func (c *Compiler) compileModule(
 | 
			
		||||
	symbolTable = symbolTable.Fork(false)
 | 
			
		||||
 | 
			
		||||
	// compile module
 | 
			
		||||
	moduleCompiler := c.fork(modFile, modulePath, symbolTable)
 | 
			
		||||
	moduleCompiler := c.fork(modFile, modulePath, symbolTable, isFile)
 | 
			
		||||
	if err := moduleCompiler.Compile(file); err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
@@ -1082,10 +1091,16 @@ func (c *Compiler) fork(
 | 
			
		||||
	file *parser.SourceFile,
 | 
			
		||||
	modulePath string,
 | 
			
		||||
	symbolTable *SymbolTable,
 | 
			
		||||
	isFile bool,
 | 
			
		||||
) *Compiler {
 | 
			
		||||
	child := NewCompiler(file, symbolTable, nil, c.modules, c.trace)
 | 
			
		||||
	child.modulePath = modulePath // module file path
 | 
			
		||||
	child.parent = c              // parent to set to current compiler
 | 
			
		||||
	child.allowFileImport = c.allowFileImport
 | 
			
		||||
	child.importDir = c.importDir
 | 
			
		||||
	if isFile && c.importDir != "" {
 | 
			
		||||
		child.importDir = filepath.Dir(modulePath)
 | 
			
		||||
	}
 | 
			
		||||
	return child
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -1192,6 +1207,7 @@ func (c *Compiler) optimizeFunc(node parser.Node) {
 | 
			
		||||
	var lastOp parser.Opcode
 | 
			
		||||
	var appendReturn bool
 | 
			
		||||
	endPos := len(c.scopes[c.scopeIndex].Instructions)
 | 
			
		||||
	newEndPost := len(newInsts)
 | 
			
		||||
	iterateInstructions(newInsts,
 | 
			
		||||
		func(pos int, opcode parser.Opcode, operands []int) bool {
 | 
			
		||||
			switch opcode {
 | 
			
		||||
@@ -1204,6 +1220,8 @@ func (c *Compiler) optimizeFunc(node parser.Node) {
 | 
			
		||||
				} else if endPos == operands[0] {
 | 
			
		||||
					// there's a jump instruction that jumps to the end of
 | 
			
		||||
					// function compiler should append "return".
 | 
			
		||||
					copy(newInsts[pos:],
 | 
			
		||||
						MakeInstruction(opcode, newEndPost))
 | 
			
		||||
					appendReturn = true
 | 
			
		||||
				} else {
 | 
			
		||||
					panic(fmt.Errorf("invalid jump position: %d", newDst))
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										32
									
								
								vendor/github.com/d5/tengo/v2/objects.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										32
									
								
								vendor/github.com/d5/tengo/v2/objects.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1342,6 +1342,38 @@ func (o *String) BinaryOp(op token.Token, rhs Object) (Object, error) {
 | 
			
		||||
			}
 | 
			
		||||
			return &String{Value: o.Value + rhsStr}, nil
 | 
			
		||||
		}
 | 
			
		||||
	case token.Less:
 | 
			
		||||
		switch rhs := rhs.(type) {
 | 
			
		||||
		case *String:
 | 
			
		||||
			if o.Value < rhs.Value {
 | 
			
		||||
				return TrueValue, nil
 | 
			
		||||
			}
 | 
			
		||||
			return FalseValue, nil
 | 
			
		||||
		}
 | 
			
		||||
	case token.LessEq:
 | 
			
		||||
		switch rhs := rhs.(type) {
 | 
			
		||||
		case *String:
 | 
			
		||||
			if o.Value <= rhs.Value {
 | 
			
		||||
				return TrueValue, nil
 | 
			
		||||
			}
 | 
			
		||||
			return FalseValue, nil
 | 
			
		||||
		}
 | 
			
		||||
	case token.Greater:
 | 
			
		||||
		switch rhs := rhs.(type) {
 | 
			
		||||
		case *String:
 | 
			
		||||
			if o.Value > rhs.Value {
 | 
			
		||||
				return TrueValue, nil
 | 
			
		||||
			}
 | 
			
		||||
			return FalseValue, nil
 | 
			
		||||
		}
 | 
			
		||||
	case token.GreaterEq:
 | 
			
		||||
		switch rhs := rhs.(type) {
 | 
			
		||||
		case *String:
 | 
			
		||||
			if o.Value >= rhs.Value {
 | 
			
		||||
				return TrueValue, nil
 | 
			
		||||
			}
 | 
			
		||||
			return FalseValue, nil
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return nil, ErrInvalidOperator
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										12
									
								
								vendor/github.com/d5/tengo/v2/parser/expr.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										12
									
								
								vendor/github.com/d5/tengo/v2/parser/expr.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -111,10 +111,11 @@ func (e *BoolLit) String() string {
 | 
			
		||||
 | 
			
		||||
// CallExpr represents a function call expression.
 | 
			
		||||
type CallExpr struct {
 | 
			
		||||
	Func   Expr
 | 
			
		||||
	LParen Pos
 | 
			
		||||
	Args   []Expr
 | 
			
		||||
	RParen Pos
 | 
			
		||||
	Func     Expr
 | 
			
		||||
	LParen   Pos
 | 
			
		||||
	Args     []Expr
 | 
			
		||||
	Ellipsis Pos
 | 
			
		||||
	RParen   Pos
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (e *CallExpr) exprNode() {}
 | 
			
		||||
@@ -134,6 +135,9 @@ func (e *CallExpr) String() string {
 | 
			
		||||
	for _, e := range e.Args {
 | 
			
		||||
		args = append(args, e.String())
 | 
			
		||||
	}
 | 
			
		||||
	if len(args) > 0 && e.Ellipsis.IsValid() {
 | 
			
		||||
		args[len(args)-1] = args[len(args)-1] + "..."
 | 
			
		||||
	}
 | 
			
		||||
	return e.Func.String() + "(" + strings.Join(args, ", ") + ")"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										2
									
								
								vendor/github.com/d5/tengo/v2/parser/opcodes.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/d5/tengo/v2/parser/opcodes.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -120,7 +120,7 @@ var OpcodeOperands = [...][]int{
 | 
			
		||||
	OpImmutable:     {},
 | 
			
		||||
	OpIndex:         {},
 | 
			
		||||
	OpSliceIndex:    {},
 | 
			
		||||
	OpCall:          {1},
 | 
			
		||||
	OpCall:          {1, 1},
 | 
			
		||||
	OpReturn:        {1},
 | 
			
		||||
	OpGetLocal:      {1},
 | 
			
		||||
	OpSetLocal:      {1},
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										17
									
								
								vendor/github.com/d5/tengo/v2/parser/parser.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										17
									
								
								vendor/github.com/d5/tengo/v2/parser/parser.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -270,9 +270,13 @@ func (p *Parser) parseCall(x Expr) *CallExpr {
 | 
			
		||||
	p.exprLevel++
 | 
			
		||||
 | 
			
		||||
	var list []Expr
 | 
			
		||||
	for p.token != token.RParen && p.token != token.EOF {
 | 
			
		||||
	var ellipsis Pos
 | 
			
		||||
	for p.token != token.RParen && p.token != token.EOF && !ellipsis.IsValid() {
 | 
			
		||||
		list = append(list, p.parseExpr())
 | 
			
		||||
 | 
			
		||||
		if p.token == token.Ellipsis {
 | 
			
		||||
			ellipsis = p.pos
 | 
			
		||||
			p.next()
 | 
			
		||||
		}
 | 
			
		||||
		if !p.expectComma(token.RParen, "call argument") {
 | 
			
		||||
			break
 | 
			
		||||
		}
 | 
			
		||||
@@ -281,10 +285,11 @@ func (p *Parser) parseCall(x Expr) *CallExpr {
 | 
			
		||||
	p.exprLevel--
 | 
			
		||||
	rparen := p.expect(token.RParen)
 | 
			
		||||
	return &CallExpr{
 | 
			
		||||
		Func:   x,
 | 
			
		||||
		LParen: lparen,
 | 
			
		||||
		RParen: rparen,
 | 
			
		||||
		Args:   list,
 | 
			
		||||
		Func:     x,
 | 
			
		||||
		LParen:   lparen,
 | 
			
		||||
		RParen:   rparen,
 | 
			
		||||
		Ellipsis: ellipsis,
 | 
			
		||||
		Args:     list,
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										15
									
								
								vendor/github.com/d5/tengo/v2/script.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										15
									
								
								vendor/github.com/d5/tengo/v2/script.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -3,6 +3,7 @@ package tengo
 | 
			
		||||
import (
 | 
			
		||||
	"context"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"path/filepath"
 | 
			
		||||
	"sync"
 | 
			
		||||
 | 
			
		||||
	"github.com/d5/tengo/v2/parser"
 | 
			
		||||
@@ -16,6 +17,7 @@ type Script struct {
 | 
			
		||||
	maxAllocs        int64
 | 
			
		||||
	maxConstObjects  int
 | 
			
		||||
	enableFileImport bool
 | 
			
		||||
	importDir        string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewScript creates a Script instance with an input script.
 | 
			
		||||
@@ -56,6 +58,16 @@ func (s *Script) SetImports(modules *ModuleMap) {
 | 
			
		||||
	s.modules = modules
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SetImportDir sets the initial import directory for script files.
 | 
			
		||||
func (s *Script) SetImportDir(dir string) error {
 | 
			
		||||
	dir, err := filepath.Abs(dir)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	s.importDir = dir
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SetMaxAllocs sets the maximum number of objects allocations during the run
 | 
			
		||||
// time. Compiled script will return ErrObjectAllocLimit error if it
 | 
			
		||||
// exceeds this limit.
 | 
			
		||||
@@ -93,6 +105,7 @@ func (s *Script) Compile() (*Compiled, error) {
 | 
			
		||||
 | 
			
		||||
	c := NewCompiler(srcFile, symbolTable, nil, s.modules, nil)
 | 
			
		||||
	c.EnableFileImport(s.enableFileImport)
 | 
			
		||||
	c.SetImportDir(s.importDir)
 | 
			
		||||
	if err := c.Compile(file); err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
@@ -103,7 +116,7 @@ func (s *Script) Compile() (*Compiled, error) {
 | 
			
		||||
	// global symbol names to indexes
 | 
			
		||||
	globalIndexes := make(map[string]int, len(globals))
 | 
			
		||||
	for _, name := range symbolTable.Names() {
 | 
			
		||||
		symbol, _, _ := symbolTable.Resolve(name)
 | 
			
		||||
		symbol, _, _ := symbolTable.Resolve(name, false)
 | 
			
		||||
		if symbol.Scope == ScopeGlobal {
 | 
			
		||||
			globalIndexes[name] = symbol.Index
 | 
			
		||||
		}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										195
									
								
								vendor/github.com/d5/tengo/v2/stdlib/json/encode.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										195
									
								
								vendor/github.com/d5/tengo/v2/stdlib/json/encode.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,20 +1,129 @@
 | 
			
		||||
// A modified version of Go's JSON implementation.
 | 
			
		||||
 | 
			
		||||
// Copyright 2010 The Go Authors. All rights reserved.
 | 
			
		||||
// Copyright 2010, 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 json
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"bytes"
 | 
			
		||||
	"encoding/base64"
 | 
			
		||||
	"errors"
 | 
			
		||||
	"math"
 | 
			
		||||
	"strconv"
 | 
			
		||||
	"unicode/utf8"
 | 
			
		||||
 | 
			
		||||
	"github.com/d5/tengo/v2"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// safeSet holds the value true if the ASCII character with the given array
 | 
			
		||||
// position can be represented inside a JSON string without any further
 | 
			
		||||
// escaping.
 | 
			
		||||
//
 | 
			
		||||
// All values are true except for the ASCII control characters (0-31), the
 | 
			
		||||
// double quote ("), and the backslash character ("\").
 | 
			
		||||
var safeSet = [utf8.RuneSelf]bool{
 | 
			
		||||
	' ':      true,
 | 
			
		||||
	'!':      true,
 | 
			
		||||
	'"':      false,
 | 
			
		||||
	'#':      true,
 | 
			
		||||
	'$':      true,
 | 
			
		||||
	'%':      true,
 | 
			
		||||
	'&':      true,
 | 
			
		||||
	'\'':     true,
 | 
			
		||||
	'(':      true,
 | 
			
		||||
	')':      true,
 | 
			
		||||
	'*':      true,
 | 
			
		||||
	'+':      true,
 | 
			
		||||
	',':      true,
 | 
			
		||||
	'-':      true,
 | 
			
		||||
	'.':      true,
 | 
			
		||||
	'/':      true,
 | 
			
		||||
	'0':      true,
 | 
			
		||||
	'1':      true,
 | 
			
		||||
	'2':      true,
 | 
			
		||||
	'3':      true,
 | 
			
		||||
	'4':      true,
 | 
			
		||||
	'5':      true,
 | 
			
		||||
	'6':      true,
 | 
			
		||||
	'7':      true,
 | 
			
		||||
	'8':      true,
 | 
			
		||||
	'9':      true,
 | 
			
		||||
	':':      true,
 | 
			
		||||
	';':      true,
 | 
			
		||||
	'<':      true,
 | 
			
		||||
	'=':      true,
 | 
			
		||||
	'>':      true,
 | 
			
		||||
	'?':      true,
 | 
			
		||||
	'@':      true,
 | 
			
		||||
	'A':      true,
 | 
			
		||||
	'B':      true,
 | 
			
		||||
	'C':      true,
 | 
			
		||||
	'D':      true,
 | 
			
		||||
	'E':      true,
 | 
			
		||||
	'F':      true,
 | 
			
		||||
	'G':      true,
 | 
			
		||||
	'H':      true,
 | 
			
		||||
	'I':      true,
 | 
			
		||||
	'J':      true,
 | 
			
		||||
	'K':      true,
 | 
			
		||||
	'L':      true,
 | 
			
		||||
	'M':      true,
 | 
			
		||||
	'N':      true,
 | 
			
		||||
	'O':      true,
 | 
			
		||||
	'P':      true,
 | 
			
		||||
	'Q':      true,
 | 
			
		||||
	'R':      true,
 | 
			
		||||
	'S':      true,
 | 
			
		||||
	'T':      true,
 | 
			
		||||
	'U':      true,
 | 
			
		||||
	'V':      true,
 | 
			
		||||
	'W':      true,
 | 
			
		||||
	'X':      true,
 | 
			
		||||
	'Y':      true,
 | 
			
		||||
	'Z':      true,
 | 
			
		||||
	'[':      true,
 | 
			
		||||
	'\\':     false,
 | 
			
		||||
	']':      true,
 | 
			
		||||
	'^':      true,
 | 
			
		||||
	'_':      true,
 | 
			
		||||
	'`':      true,
 | 
			
		||||
	'a':      true,
 | 
			
		||||
	'b':      true,
 | 
			
		||||
	'c':      true,
 | 
			
		||||
	'd':      true,
 | 
			
		||||
	'e':      true,
 | 
			
		||||
	'f':      true,
 | 
			
		||||
	'g':      true,
 | 
			
		||||
	'h':      true,
 | 
			
		||||
	'i':      true,
 | 
			
		||||
	'j':      true,
 | 
			
		||||
	'k':      true,
 | 
			
		||||
	'l':      true,
 | 
			
		||||
	'm':      true,
 | 
			
		||||
	'n':      true,
 | 
			
		||||
	'o':      true,
 | 
			
		||||
	'p':      true,
 | 
			
		||||
	'q':      true,
 | 
			
		||||
	'r':      true,
 | 
			
		||||
	's':      true,
 | 
			
		||||
	't':      true,
 | 
			
		||||
	'u':      true,
 | 
			
		||||
	'v':      true,
 | 
			
		||||
	'w':      true,
 | 
			
		||||
	'x':      true,
 | 
			
		||||
	'y':      true,
 | 
			
		||||
	'z':      true,
 | 
			
		||||
	'{':      true,
 | 
			
		||||
	'|':      true,
 | 
			
		||||
	'}':      true,
 | 
			
		||||
	'~':      true,
 | 
			
		||||
	'\u007f': true,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var hex = "0123456789abcdef"
 | 
			
		||||
 | 
			
		||||
// Encode returns the JSON encoding of the object.
 | 
			
		||||
func Encode(o tengo.Object) ([]byte, error) {
 | 
			
		||||
	var b []byte
 | 
			
		||||
@@ -53,7 +162,7 @@ func Encode(o tengo.Object) ([]byte, error) {
 | 
			
		||||
		len1 := len(o.Value) - 1
 | 
			
		||||
		idx := 0
 | 
			
		||||
		for key, value := range o.Value {
 | 
			
		||||
			b = strconv.AppendQuote(b, key)
 | 
			
		||||
			b = encodeString(b, key)
 | 
			
		||||
			b = append(b, ':')
 | 
			
		||||
			eb, err := Encode(value)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
@@ -71,7 +180,7 @@ func Encode(o tengo.Object) ([]byte, error) {
 | 
			
		||||
		len1 := len(o.Value) - 1
 | 
			
		||||
		idx := 0
 | 
			
		||||
		for key, value := range o.Value {
 | 
			
		||||
			b = strconv.AppendQuote(b, key)
 | 
			
		||||
			b = encodeString(b, key)
 | 
			
		||||
			b = append(b, ':')
 | 
			
		||||
			eb, err := Encode(value)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
@@ -130,7 +239,9 @@ func Encode(o tengo.Object) ([]byte, error) {
 | 
			
		||||
	case *tengo.Int:
 | 
			
		||||
		b = strconv.AppendInt(b, o.Value, 10)
 | 
			
		||||
	case *tengo.String:
 | 
			
		||||
		b = strconv.AppendQuote(b, o.Value)
 | 
			
		||||
		// string encoding bug is fixed with newly introduced function
 | 
			
		||||
		// encodeString(). See: https://github.com/d5/tengo/issues/268
 | 
			
		||||
		b = encodeString(b, o.Value)
 | 
			
		||||
	case *tengo.Time:
 | 
			
		||||
		y, err := o.Value.MarshalJSON()
 | 
			
		||||
		if err != nil {
 | 
			
		||||
@@ -144,3 +255,79 @@ func Encode(o tengo.Object) ([]byte, error) {
 | 
			
		||||
	}
 | 
			
		||||
	return b, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// encodeString encodes given string as JSON string according to
 | 
			
		||||
// https://www.json.org/img/string.png
 | 
			
		||||
// Implementation is inspired by https://github.com/json-iterator/go
 | 
			
		||||
// See encodeStringSlowPath() for more information.
 | 
			
		||||
func encodeString(b []byte, val string) []byte {
 | 
			
		||||
	valLen := len(val)
 | 
			
		||||
	buf := bytes.NewBuffer(b)
 | 
			
		||||
	buf.WriteByte('"')
 | 
			
		||||
 | 
			
		||||
	// write string, the fast path, without utf8 and escape support
 | 
			
		||||
	i := 0
 | 
			
		||||
	for ; i < valLen; i++ {
 | 
			
		||||
		c := val[i]
 | 
			
		||||
		if c > 31 && c != '"' && c != '\\' {
 | 
			
		||||
			buf.WriteByte(c)
 | 
			
		||||
		} else {
 | 
			
		||||
			break
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if i == valLen {
 | 
			
		||||
		buf.WriteByte('"')
 | 
			
		||||
		return buf.Bytes()
 | 
			
		||||
	}
 | 
			
		||||
	encodeStringSlowPath(buf, i, val, valLen)
 | 
			
		||||
	buf.WriteByte('"')
 | 
			
		||||
	return buf.Bytes()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// encodeStringSlowPath is ported from Go 1.14.2 encoding/json package.
 | 
			
		||||
// U+2028 U+2029 JSONP security holes can be fixed with addition call to
 | 
			
		||||
// json.html_escape() thus it is removed from the implementation below.
 | 
			
		||||
// Note: Invalid runes are not checked as they are checked in original
 | 
			
		||||
// implementation.
 | 
			
		||||
func encodeStringSlowPath(buf *bytes.Buffer, i int, val string, valLen int) {
 | 
			
		||||
	start := i
 | 
			
		||||
	for i < valLen {
 | 
			
		||||
		if b := val[i]; b < utf8.RuneSelf {
 | 
			
		||||
			if safeSet[b] {
 | 
			
		||||
				i++
 | 
			
		||||
				continue
 | 
			
		||||
			}
 | 
			
		||||
			if start < i {
 | 
			
		||||
				buf.WriteString(val[start:i])
 | 
			
		||||
			}
 | 
			
		||||
			buf.WriteByte('\\')
 | 
			
		||||
			switch b {
 | 
			
		||||
			case '\\', '"':
 | 
			
		||||
				buf.WriteByte(b)
 | 
			
		||||
			case '\n':
 | 
			
		||||
				buf.WriteByte('n')
 | 
			
		||||
			case '\r':
 | 
			
		||||
				buf.WriteByte('r')
 | 
			
		||||
			case '\t':
 | 
			
		||||
				buf.WriteByte('t')
 | 
			
		||||
			default:
 | 
			
		||||
				// This encodes bytes < 0x20 except for \t, \n and \r.
 | 
			
		||||
				// If escapeHTML is set, it also escapes <, >, and &
 | 
			
		||||
				// because they can lead to security holes when
 | 
			
		||||
				// user-controlled strings are rendered into JSON
 | 
			
		||||
				// and served to some browsers.
 | 
			
		||||
				buf.WriteString(`u00`)
 | 
			
		||||
				buf.WriteByte(hex[b>>4])
 | 
			
		||||
				buf.WriteByte(hex[b&0xF])
 | 
			
		||||
			}
 | 
			
		||||
			i++
 | 
			
		||||
			start = i
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		i++
 | 
			
		||||
		continue
 | 
			
		||||
	}
 | 
			
		||||
	if start < valLen {
 | 
			
		||||
		buf.WriteString(val[start:])
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										56
									
								
								vendor/github.com/d5/tengo/v2/symbol_table.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										56
									
								
								vendor/github.com/d5/tengo/v2/symbol_table.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -44,6 +44,17 @@ func (t *SymbolTable) Define(name string) *Symbol {
 | 
			
		||||
 | 
			
		||||
	if t.Parent(true) == nil {
 | 
			
		||||
		symbol.Scope = ScopeGlobal
 | 
			
		||||
 | 
			
		||||
		// if symbol is defined in a block of global scope, symbol index must
 | 
			
		||||
		// be tracked at the root-level table instead.
 | 
			
		||||
		if p := t.parent; p != nil {
 | 
			
		||||
			for p.parent != nil {
 | 
			
		||||
				p = p.parent
 | 
			
		||||
			}
 | 
			
		||||
			t.numDefinition--
 | 
			
		||||
			p.numDefinition++
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	} else {
 | 
			
		||||
		symbol.Scope = ScopeLocal
 | 
			
		||||
	}
 | 
			
		||||
@@ -71,25 +82,36 @@ func (t *SymbolTable) DefineBuiltin(index int, name string) *Symbol {
 | 
			
		||||
// Resolve resolves a symbol with a given name.
 | 
			
		||||
func (t *SymbolTable) Resolve(
 | 
			
		||||
	name string,
 | 
			
		||||
) (symbol *Symbol, depth int, ok bool) {
 | 
			
		||||
	symbol, ok = t.store[name]
 | 
			
		||||
	if !ok && t.parent != nil {
 | 
			
		||||
		symbol, depth, ok = t.parent.Resolve(name)
 | 
			
		||||
		if !ok {
 | 
			
		||||
			return
 | 
			
		||||
	recur bool,
 | 
			
		||||
) (*Symbol, int, bool) {
 | 
			
		||||
	symbol, ok := t.store[name]
 | 
			
		||||
	if ok {
 | 
			
		||||
		// symbol can be used if
 | 
			
		||||
		if symbol.Scope != ScopeLocal || // it's not of local scope, OR,
 | 
			
		||||
			symbol.LocalAssigned || // it's assigned at least once, OR,
 | 
			
		||||
			recur { // it's defined in higher level
 | 
			
		||||
			return symbol, 0, true
 | 
			
		||||
		}
 | 
			
		||||
		depth++
 | 
			
		||||
 | 
			
		||||
		// if symbol is defined in parent table and if it's not global/builtin
 | 
			
		||||
		// then it's free variable.
 | 
			
		||||
		if !t.block && depth > 0 &&
 | 
			
		||||
			symbol.Scope != ScopeGlobal &&
 | 
			
		||||
			symbol.Scope != ScopeBuiltin {
 | 
			
		||||
			return t.defineFree(symbol), depth, true
 | 
			
		||||
		}
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	return
 | 
			
		||||
 | 
			
		||||
	if t.parent == nil {
 | 
			
		||||
		return nil, 0, false
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	symbol, depth, ok := t.parent.Resolve(name, true)
 | 
			
		||||
	if !ok {
 | 
			
		||||
		return nil, 0, false
 | 
			
		||||
	}
 | 
			
		||||
	depth++
 | 
			
		||||
 | 
			
		||||
	// if symbol is defined in parent table and if it's not global/builtin
 | 
			
		||||
	// then it's free variable.
 | 
			
		||||
	if !t.block && depth > 0 &&
 | 
			
		||||
		symbol.Scope != ScopeGlobal &&
 | 
			
		||||
		symbol.Scope != ScopeBuiltin {
 | 
			
		||||
		return t.defineFree(symbol), depth, true
 | 
			
		||||
	}
 | 
			
		||||
	return symbol, depth, true
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Fork creates a new symbol table for a new scope.
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										26
									
								
								vendor/github.com/d5/tengo/v2/vm.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										26
									
								
								vendor/github.com/d5/tengo/v2/vm.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -537,12 +537,36 @@ func (v *VM) run() {
 | 
			
		||||
			}
 | 
			
		||||
		case parser.OpCall:
 | 
			
		||||
			numArgs := int(v.curInsts[v.ip+1])
 | 
			
		||||
			v.ip++
 | 
			
		||||
			spread := int(v.curInsts[v.ip+2])
 | 
			
		||||
			v.ip += 2
 | 
			
		||||
 | 
			
		||||
			value := v.stack[v.sp-1-numArgs]
 | 
			
		||||
			if !value.CanCall() {
 | 
			
		||||
				v.err = fmt.Errorf("not callable: %s", value.TypeName())
 | 
			
		||||
				return
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if spread == 1 {
 | 
			
		||||
				v.sp--
 | 
			
		||||
				switch arr := v.stack[v.sp].(type) {
 | 
			
		||||
				case *Array:
 | 
			
		||||
					for _, item := range arr.Value {
 | 
			
		||||
						v.stack[v.sp] = item
 | 
			
		||||
						v.sp++
 | 
			
		||||
					}
 | 
			
		||||
					numArgs += len(arr.Value) - 1
 | 
			
		||||
				case *ImmutableArray:
 | 
			
		||||
					for _, item := range arr.Value {
 | 
			
		||||
						v.stack[v.sp] = item
 | 
			
		||||
						v.sp++
 | 
			
		||||
					}
 | 
			
		||||
					numArgs += len(arr.Value) - 1
 | 
			
		||||
				default:
 | 
			
		||||
					v.err = fmt.Errorf("not an array: %s", arr.TypeName())
 | 
			
		||||
					return
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if callee, ok := value.(*CompiledFunction); ok {
 | 
			
		||||
				if callee.VarArgs {
 | 
			
		||||
					// if the closure is variadic,
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										22
									
								
								vendor/github.com/dyatlov/go-opengraph/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								vendor/github.com/dyatlov/go-opengraph/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,22 @@
 | 
			
		||||
The MIT License (MIT)
 | 
			
		||||
 | 
			
		||||
Copyright (c) 2015 Vitaly Dyatlov
 | 
			
		||||
 | 
			
		||||
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.
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										365
									
								
								vendor/github.com/dyatlov/go-opengraph/opengraph/opengraph.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										365
									
								
								vendor/github.com/dyatlov/go-opengraph/opengraph/opengraph.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,365 @@
 | 
			
		||||
package opengraph
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"encoding/json"
 | 
			
		||||
	"io"
 | 
			
		||||
	"strconv"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"golang.org/x/net/html"
 | 
			
		||||
	"golang.org/x/net/html/atom"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Image defines Open Graph Image type
 | 
			
		||||
type Image struct {
 | 
			
		||||
	URL       string `json:"url"`
 | 
			
		||||
	SecureURL string `json:"secure_url"`
 | 
			
		||||
	Type      string `json:"type"`
 | 
			
		||||
	Width     uint64 `json:"width"`
 | 
			
		||||
	Height    uint64 `json:"height"`
 | 
			
		||||
	draft     bool    `json:"-"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Video defines Open Graph Video type
 | 
			
		||||
type Video struct {
 | 
			
		||||
	URL       string `json:"url"`
 | 
			
		||||
	SecureURL string `json:"secure_url"`
 | 
			
		||||
	Type      string `json:"type"`
 | 
			
		||||
	Width     uint64 `json:"width"`
 | 
			
		||||
	Height    uint64 `json:"height"`
 | 
			
		||||
	draft     bool    `json:"-"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Audio defines Open Graph Audio Type
 | 
			
		||||
type Audio struct {
 | 
			
		||||
	URL       string `json:"url"`
 | 
			
		||||
	SecureURL string `json:"secure_url"`
 | 
			
		||||
	Type      string `json:"type"`
 | 
			
		||||
	draft     bool    `json:"-"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Article contain Open Graph Article structure
 | 
			
		||||
type Article struct {
 | 
			
		||||
	PublishedTime  *time.Time `json:"published_time"`
 | 
			
		||||
	ModifiedTime   *time.Time `json:"modified_time"`
 | 
			
		||||
	ExpirationTime *time.Time `json:"expiration_time"`
 | 
			
		||||
	Section        string     `json:"section"`
 | 
			
		||||
	Tags           []string   `json:"tags"`
 | 
			
		||||
	Authors        []*Profile `json:"authors"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Profile contains Open Graph Profile structure
 | 
			
		||||
type Profile struct {
 | 
			
		||||
	FirstName string `json:"first_name"`
 | 
			
		||||
	LastName  string `json:"last_name"`
 | 
			
		||||
	Username  string `json:"username"`
 | 
			
		||||
	Gender    string `json:"gender"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Book contains Open Graph Book structure
 | 
			
		||||
type Book struct {
 | 
			
		||||
	ISBN        string     `json:"isbn"`
 | 
			
		||||
	ReleaseDate *time.Time `json:"release_date"`
 | 
			
		||||
	Tags        []string   `json:"tags"`
 | 
			
		||||
	Authors     []*Profile `json:"authors"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// OpenGraph contains facebook og data
 | 
			
		||||
type OpenGraph struct {
 | 
			
		||||
	isArticle        bool
 | 
			
		||||
	isBook           bool
 | 
			
		||||
	isProfile        bool
 | 
			
		||||
	Type             string   `json:"type"`
 | 
			
		||||
	URL              string   `json:"url"`
 | 
			
		||||
	Title            string   `json:"title"`
 | 
			
		||||
	Description      string   `json:"description"`
 | 
			
		||||
	Determiner       string   `json:"determiner"`
 | 
			
		||||
	SiteName         string   `json:"site_name"`
 | 
			
		||||
	Locale           string   `json:"locale"`
 | 
			
		||||
	LocalesAlternate []string `json:"locales_alternate"`
 | 
			
		||||
	Images           []*Image `json:"images"`
 | 
			
		||||
	Audios           []*Audio `json:"audios"`
 | 
			
		||||
	Videos           []*Video `json:"videos"`
 | 
			
		||||
	Article          *Article `json:"article,omitempty"`
 | 
			
		||||
	Book             *Book    `json:"book,omitempty"`
 | 
			
		||||
	Profile          *Profile `json:"profile,omitempty"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewOpenGraph returns new instance of Open Graph structure
 | 
			
		||||
func NewOpenGraph() *OpenGraph {
 | 
			
		||||
	return &OpenGraph{}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ToJSON a simple wrapper around json.Marshal
 | 
			
		||||
func (og *OpenGraph) ToJSON() ([]byte, error) {
 | 
			
		||||
	return json.Marshal(og)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// String return json representation of structure, or error string
 | 
			
		||||
func (og *OpenGraph) String() string {
 | 
			
		||||
	data, err := og.ToJSON()
 | 
			
		||||
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err.Error()
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return string(data[:])
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ProcessHTML parses given html from Reader interface and fills up OpenGraph structure
 | 
			
		||||
func (og *OpenGraph) ProcessHTML(buffer io.Reader) error {
 | 
			
		||||
	z := html.NewTokenizer(buffer)
 | 
			
		||||
	for {
 | 
			
		||||
		tt := z.Next()
 | 
			
		||||
		switch tt {
 | 
			
		||||
		case html.ErrorToken:
 | 
			
		||||
			if z.Err() == io.EOF {
 | 
			
		||||
				return nil
 | 
			
		||||
			}
 | 
			
		||||
			return z.Err()
 | 
			
		||||
		case html.StartTagToken, html.SelfClosingTagToken, html.EndTagToken:
 | 
			
		||||
			name, hasAttr := z.TagName()
 | 
			
		||||
			if atom.Lookup(name) == atom.Body {
 | 
			
		||||
				return nil // OpenGraph is only in head, so we don't need body
 | 
			
		||||
			}
 | 
			
		||||
			if atom.Lookup(name) != atom.Meta || !hasAttr {
 | 
			
		||||
				continue
 | 
			
		||||
			}
 | 
			
		||||
			m := make(map[string]string)
 | 
			
		||||
			var key, val []byte
 | 
			
		||||
			for hasAttr {
 | 
			
		||||
				key, val, hasAttr = z.TagAttr()
 | 
			
		||||
				m[atom.String(key)] = string(val)
 | 
			
		||||
			}
 | 
			
		||||
			og.ProcessMeta(m)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (og *OpenGraph) ensureHasVideo() {
 | 
			
		||||
	if len(og.Videos) > 0 {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	og.Videos = append(og.Videos, &Video{draft: true})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (og *OpenGraph) ensureHasImage() {
 | 
			
		||||
	if len(og.Images) > 0 {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	og.Images = append(og.Images, &Image{draft: true})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (og *OpenGraph) ensureHasAudio() {
 | 
			
		||||
	if len(og.Audios) > 0 {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	og.Audios = append(og.Audios, &Audio{draft: true})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ProcessMeta processes meta attributes and adds them to Open Graph structure if they are suitable for that
 | 
			
		||||
func (og *OpenGraph) ProcessMeta(metaAttrs map[string]string) {
 | 
			
		||||
	switch metaAttrs["property"] {
 | 
			
		||||
	case "og:description":
 | 
			
		||||
		og.Description = metaAttrs["content"]
 | 
			
		||||
	case "og:type":
 | 
			
		||||
		og.Type = metaAttrs["content"]
 | 
			
		||||
		switch og.Type {
 | 
			
		||||
		case "article":
 | 
			
		||||
			og.isArticle = true
 | 
			
		||||
		case "book":
 | 
			
		||||
			og.isBook = true
 | 
			
		||||
		case "profile":
 | 
			
		||||
			og.isProfile = true
 | 
			
		||||
		}
 | 
			
		||||
	case "og:title":
 | 
			
		||||
		og.Title = metaAttrs["content"]
 | 
			
		||||
	case "og:url":
 | 
			
		||||
		og.URL = metaAttrs["content"]
 | 
			
		||||
	case "og:determiner":
 | 
			
		||||
		og.Determiner = metaAttrs["content"]
 | 
			
		||||
	case "og:site_name":
 | 
			
		||||
		og.SiteName = metaAttrs["content"]
 | 
			
		||||
	case "og:locale":
 | 
			
		||||
		og.Locale = metaAttrs["content"]
 | 
			
		||||
	case "og:locale:alternate":
 | 
			
		||||
		og.LocalesAlternate = append(og.LocalesAlternate, metaAttrs["content"])
 | 
			
		||||
	case "og:audio":
 | 
			
		||||
		if len(og.Audios)>0 && og.Audios[len(og.Audios)-1].draft {
 | 
			
		||||
			og.Audios[len(og.Audios)-1].URL = metaAttrs["content"]
 | 
			
		||||
			og.Audios[len(og.Audios)-1].draft = false
 | 
			
		||||
		} else {
 | 
			
		||||
			og.Audios = append(og.Audios, &Audio{URL: metaAttrs["content"]})
 | 
			
		||||
		}
 | 
			
		||||
	case "og:audio:secure_url":
 | 
			
		||||
		og.ensureHasAudio()
 | 
			
		||||
		og.Audios[len(og.Audios)-1].SecureURL = metaAttrs["content"]
 | 
			
		||||
	case "og:audio:type":
 | 
			
		||||
		og.ensureHasAudio()
 | 
			
		||||
		og.Audios[len(og.Audios)-1].Type = metaAttrs["content"]
 | 
			
		||||
	case "og:image":
 | 
			
		||||
		if len(og.Images)>0 && og.Images[len(og.Images)-1].draft {
 | 
			
		||||
			og.Images[len(og.Images)-1].URL = metaAttrs["content"]
 | 
			
		||||
			og.Images[len(og.Images)-1].draft = false
 | 
			
		||||
		} else {
 | 
			
		||||
			og.Images = append(og.Images, &Image{URL: metaAttrs["content"]})
 | 
			
		||||
		}
 | 
			
		||||
	case "og:image:url":
 | 
			
		||||
		og.ensureHasImage()
 | 
			
		||||
		og.Images[len(og.Images)-1].URL = metaAttrs["content"]
 | 
			
		||||
	case "og:image:secure_url":
 | 
			
		||||
		og.ensureHasImage()
 | 
			
		||||
		og.Images[len(og.Images)-1].SecureURL = metaAttrs["content"]
 | 
			
		||||
	case "og:image:type":
 | 
			
		||||
		og.ensureHasImage()
 | 
			
		||||
		og.Images[len(og.Images)-1].Type = metaAttrs["content"]
 | 
			
		||||
	case "og:image:width":
 | 
			
		||||
		w, err := strconv.ParseUint(metaAttrs["content"], 10, 64)
 | 
			
		||||
		if err == nil {
 | 
			
		||||
			og.ensureHasImage()
 | 
			
		||||
			og.Images[len(og.Images)-1].Width = w
 | 
			
		||||
		}
 | 
			
		||||
	case "og:image:height":
 | 
			
		||||
		h, err := strconv.ParseUint(metaAttrs["content"], 10, 64)
 | 
			
		||||
		if err == nil {
 | 
			
		||||
			og.ensureHasImage()
 | 
			
		||||
			og.Images[len(og.Images)-1].Height = h
 | 
			
		||||
		}
 | 
			
		||||
	case "og:video":
 | 
			
		||||
		if len(og.Videos)>0 && og.Videos[len(og.Videos)-1].draft {
 | 
			
		||||
			og.Videos[len(og.Videos)-1].URL = metaAttrs["content"]
 | 
			
		||||
			og.Videos[len(og.Videos)-1].draft = false
 | 
			
		||||
		} else {
 | 
			
		||||
			og.Videos = append(og.Videos, &Video{URL: metaAttrs["content"]})
 | 
			
		||||
		}
 | 
			
		||||
	case "og:video:url":
 | 
			
		||||
		og.ensureHasVideo()
 | 
			
		||||
		og.Videos[len(og.Videos)-1].URL = metaAttrs["content"]
 | 
			
		||||
	case "og:video:secure_url":
 | 
			
		||||
		og.ensureHasVideo()
 | 
			
		||||
		og.Videos[len(og.Videos)-1].SecureURL = metaAttrs["content"]
 | 
			
		||||
	case "og:video:type":
 | 
			
		||||
		og.ensureHasVideo()
 | 
			
		||||
		og.Videos[len(og.Videos)-1].Type = metaAttrs["content"]
 | 
			
		||||
	case "og:video:width":
 | 
			
		||||
		w, err := strconv.ParseUint(metaAttrs["content"], 10, 64)
 | 
			
		||||
		if err == nil {
 | 
			
		||||
			og.ensureHasVideo()
 | 
			
		||||
			og.Videos[len(og.Videos)-1].Width = w
 | 
			
		||||
		}
 | 
			
		||||
	case "og:video:height":
 | 
			
		||||
		h, err := strconv.ParseUint(metaAttrs["content"], 10, 64)
 | 
			
		||||
		if err == nil {
 | 
			
		||||
			og.ensureHasVideo()
 | 
			
		||||
			og.Videos[len(og.Videos)-1].Height = h
 | 
			
		||||
		}
 | 
			
		||||
	default:
 | 
			
		||||
		if og.isArticle {
 | 
			
		||||
			og.processArticleMeta(metaAttrs)
 | 
			
		||||
		} else if og.isBook {
 | 
			
		||||
			og.processBookMeta(metaAttrs)
 | 
			
		||||
		} else if og.isProfile {
 | 
			
		||||
			og.processProfileMeta(metaAttrs)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (og *OpenGraph) processArticleMeta(metaAttrs map[string]string) {
 | 
			
		||||
	if og.Article == nil {
 | 
			
		||||
		og.Article = &Article{}
 | 
			
		||||
	}
 | 
			
		||||
	switch metaAttrs["property"] {
 | 
			
		||||
	case "article:published_time":
 | 
			
		||||
		t, err := time.Parse(time.RFC3339, metaAttrs["content"])
 | 
			
		||||
		if err == nil {
 | 
			
		||||
			og.Article.PublishedTime = &t
 | 
			
		||||
		}
 | 
			
		||||
	case "article:modified_time":
 | 
			
		||||
		t, err := time.Parse(time.RFC3339, metaAttrs["content"])
 | 
			
		||||
		if err == nil {
 | 
			
		||||
			og.Article.ModifiedTime = &t
 | 
			
		||||
		}
 | 
			
		||||
	case "article:expiration_time":
 | 
			
		||||
		t, err := time.Parse(time.RFC3339, metaAttrs["content"])
 | 
			
		||||
		if err == nil {
 | 
			
		||||
			og.Article.ExpirationTime = &t
 | 
			
		||||
		}
 | 
			
		||||
	case "article:section":
 | 
			
		||||
		og.Article.Section = metaAttrs["content"]
 | 
			
		||||
	case "article:tag":
 | 
			
		||||
		og.Article.Tags = append(og.Article.Tags, metaAttrs["content"])
 | 
			
		||||
	case "article:author:first_name":
 | 
			
		||||
		if len(og.Article.Authors) == 0 {
 | 
			
		||||
			og.Article.Authors = append(og.Article.Authors, &Profile{})
 | 
			
		||||
		}
 | 
			
		||||
		og.Article.Authors[len(og.Article.Authors)-1].FirstName = metaAttrs["content"]
 | 
			
		||||
	case "article:author:last_name":
 | 
			
		||||
		if len(og.Article.Authors) == 0 {
 | 
			
		||||
			og.Article.Authors = append(og.Article.Authors, &Profile{})
 | 
			
		||||
		}
 | 
			
		||||
		og.Article.Authors[len(og.Article.Authors)-1].LastName = metaAttrs["content"]
 | 
			
		||||
	case "article:author:username":
 | 
			
		||||
		if len(og.Article.Authors) == 0 {
 | 
			
		||||
			og.Article.Authors = append(og.Article.Authors, &Profile{})
 | 
			
		||||
		}
 | 
			
		||||
		og.Article.Authors[len(og.Article.Authors)-1].Username = metaAttrs["content"]
 | 
			
		||||
	case "article:author:gender":
 | 
			
		||||
		if len(og.Article.Authors) == 0 {
 | 
			
		||||
			og.Article.Authors = append(og.Article.Authors, &Profile{})
 | 
			
		||||
		}
 | 
			
		||||
		og.Article.Authors[len(og.Article.Authors)-1].Gender = metaAttrs["content"]
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (og *OpenGraph) processBookMeta(metaAttrs map[string]string) {
 | 
			
		||||
	if og.Book == nil {
 | 
			
		||||
		og.Book = &Book{}
 | 
			
		||||
	}
 | 
			
		||||
	switch metaAttrs["property"] {
 | 
			
		||||
	case "book:release_date":
 | 
			
		||||
		t, err := time.Parse(time.RFC3339, metaAttrs["content"])
 | 
			
		||||
		if err == nil {
 | 
			
		||||
			og.Book.ReleaseDate = &t
 | 
			
		||||
		}
 | 
			
		||||
	case "book:isbn":
 | 
			
		||||
		og.Book.ISBN = metaAttrs["content"]
 | 
			
		||||
	case "book:tag":
 | 
			
		||||
		og.Book.Tags = append(og.Book.Tags, metaAttrs["content"])
 | 
			
		||||
	case "book:author:first_name":
 | 
			
		||||
		if len(og.Book.Authors) == 0 {
 | 
			
		||||
			og.Book.Authors = append(og.Book.Authors, &Profile{})
 | 
			
		||||
		}
 | 
			
		||||
		og.Book.Authors[len(og.Book.Authors)-1].FirstName = metaAttrs["content"]
 | 
			
		||||
	case "book:author:last_name":
 | 
			
		||||
		if len(og.Book.Authors) == 0 {
 | 
			
		||||
			og.Book.Authors = append(og.Book.Authors, &Profile{})
 | 
			
		||||
		}
 | 
			
		||||
		og.Book.Authors[len(og.Book.Authors)-1].LastName = metaAttrs["content"]
 | 
			
		||||
	case "book:author:username":
 | 
			
		||||
		if len(og.Book.Authors) == 0 {
 | 
			
		||||
			og.Book.Authors = append(og.Book.Authors, &Profile{})
 | 
			
		||||
		}
 | 
			
		||||
		og.Book.Authors[len(og.Book.Authors)-1].Username = metaAttrs["content"]
 | 
			
		||||
	case "book:author:gender":
 | 
			
		||||
		if len(og.Book.Authors) == 0 {
 | 
			
		||||
			og.Book.Authors = append(og.Book.Authors, &Profile{})
 | 
			
		||||
		}
 | 
			
		||||
		og.Book.Authors[len(og.Book.Authors)-1].Gender = metaAttrs["content"]
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (og *OpenGraph) processProfileMeta(metaAttrs map[string]string) {
 | 
			
		||||
	if og.Profile == nil {
 | 
			
		||||
		og.Profile = &Profile{}
 | 
			
		||||
	}
 | 
			
		||||
	switch metaAttrs["property"] {
 | 
			
		||||
	case "profile:first_name":
 | 
			
		||||
		og.Profile.FirstName = metaAttrs["content"]
 | 
			
		||||
	case "profile:last_name":
 | 
			
		||||
		og.Profile.LastName = metaAttrs["content"]
 | 
			
		||||
	case "profile:username":
 | 
			
		||||
		og.Profile.Username = metaAttrs["content"]
 | 
			
		||||
	case "profile:gender":
 | 
			
		||||
		og.Profile.Gender = metaAttrs["content"]
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										5
									
								
								vendor/github.com/francoispqt/gojay/.gitignore
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								vendor/github.com/francoispqt/gojay/.gitignore
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,5 @@
 | 
			
		||||
vendor
 | 
			
		||||
*.out
 | 
			
		||||
*.log
 | 
			
		||||
*.test
 | 
			
		||||
.vscode
 | 
			
		||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user