Initial commit: Bzzz P2P Task Coordination System with Antennae meta-discussion layer
- libp2p networking with mDNS discovery - GitHub Issues integration for atomic task management - PubSub messaging for coordination and meta-discussion - Hypercore-inspired distributed logging - Tested P2P network formation between WALNUT and IRONWOOD nodes 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
36
.gitignore
vendored
Normal file
36
.gitignore
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
# Binaries
|
||||
bzzz
|
||||
*.exe
|
||||
*.exe~
|
||||
*.dll
|
||||
*.so
|
||||
*.dylib
|
||||
|
||||
# Test binary, built with `go test -c`
|
||||
*.test
|
||||
|
||||
# Output of the go coverage tool
|
||||
*.out
|
||||
|
||||
# Go workspace file
|
||||
go.work
|
||||
|
||||
# IDE files
|
||||
.vscode/
|
||||
.idea/
|
||||
|
||||
# OS generated files
|
||||
.DS_Store
|
||||
.DS_Store?
|
||||
._*
|
||||
.Spotlight-V100
|
||||
.Trashes
|
||||
ehthumbs.db
|
||||
Thumbs.db
|
||||
|
||||
# Logs
|
||||
*.log
|
||||
|
||||
# Temporary files
|
||||
*.tmp
|
||||
*.temp
|
||||
192
DEVELOPMENT_PLAN.md
Normal file
192
DEVELOPMENT_PLAN.md
Normal file
@@ -0,0 +1,192 @@
|
||||
# Project Bzzz: Decentralized Task Execution Network - Development Plan
|
||||
|
||||
## 1. Overview & Vision
|
||||
|
||||
This document outlines the development plan for **Project Bzzz**, a decentralized task execution network designed to enhance the existing **Hive Cluster**.
|
||||
|
||||
The vision is to evolve from a centrally coordinated system to a resilient, peer-to-peer (P2P) mesh of autonomous agents. This architecture eliminates single points of failure, improves scalability, and allows for dynamic, collaborative task resolution. Bzzz will complement the existing N8N orchestration layer, acting as a powerful, self-organizing execution fabric.
|
||||
|
||||
---
|
||||
|
||||
## 2. Core Architecture
|
||||
|
||||
The system is built on three key pillars: decentralized networking, GitHub-native task management, and verifiable, distributed logging.
|
||||
|
||||
| Component | Technology | Purpose |
|
||||
| :--- | :--- | :--- |
|
||||
| **Networking** | **libp2p** | For peer discovery (mDNS, DHT), identity, and secure P2P communication. |
|
||||
| **Task Management** | **GitHub Issues** | The single source of truth for task definition, allocation, and tracking. |
|
||||
| **Messaging** | **libp2p Pub/Sub** | For broadcasting capabilities and coordinating collaborative help requests. |
|
||||
| **Logging** | **Hypercore Protocol** | For creating a tamper-proof, decentralized, and replicable logging system for debugging. |
|
||||
|
||||
---
|
||||
|
||||
## 3. Architectural Refinements & Key Features
|
||||
|
||||
Based on our analysis, the following refinements will be adopted:
|
||||
|
||||
### 3.1. Task Allocation via GitHub Assignment
|
||||
|
||||
To prevent race conditions and simplify logic, we will use GitHub's native issue assignment mechanism as an atomic lock. The `task_claim` pub/sub topic is no longer needed.
|
||||
|
||||
**Workflow:**
|
||||
1. A `bzzz-agent` discovers a new, *unassigned* issue in the target repository.
|
||||
2. The agent immediately attempts to **assign itself** to the issue via the GitHub API.
|
||||
3. **Success:** If the assignment succeeds, the agent has exclusive ownership of the task and begins execution.
|
||||
4. **Failure:** If the assignment fails (because another agent was faster), the agent logs the contention and looks for another task.
|
||||
|
||||
### 3.2. Collaborative Task Execution with Hop Limit
|
||||
|
||||
The `task_help_request` feature enables agents to collaborate on complex tasks. To prevent infinite request loops and network flooding, we will implement a **hop limit**.
|
||||
|
||||
- **Hop Limit:** A `task_help_request` will be discarded after being forwarded **3 times**.
|
||||
- If a task cannot be completed after 3 help requests, it will be marked as "failed," and a comment will be added to the GitHub issue for manual review.
|
||||
|
||||
### 3.3. Decentralized Logging with Hypercore
|
||||
|
||||
To solve the challenge of debugging a distributed system, each agent will manage its own secure, append-only log stream using the Hypercore Protocol.
|
||||
|
||||
- **Log Creation:** Each agent generates a `hypercore` and broadcasts its public key via the `capabilities` message.
|
||||
- **Log Replication:** Any other agent (or a dedicated monitoring node) can use this key to replicate the log stream in real-time or after the fact.
|
||||
- **Benefits:** This creates a verifiable and resilient audit trail for every agent's actions, which is invaluable for debugging without relying on a centralized logging server.
|
||||
|
||||
---
|
||||
|
||||
## 4. Integration with the Hive Ecosystem
|
||||
|
||||
Bzzz is designed to integrate seamlessly with the existing cluster infrastructure.
|
||||
|
||||
### 4.1. Deployment Strategy: Docker + Host Networking (PREFERRED APPROACH)
|
||||
|
||||
Based on comprehensive analysis of the existing Hive infrastructure and Bzzz's P2P requirements, we will use a **hybrid deployment approach** that combines Docker containerization with host networking:
|
||||
|
||||
```yaml
|
||||
# Docker Compose configuration for bzzz-agent
|
||||
services:
|
||||
bzzz-agent:
|
||||
image: bzzz-agent:latest
|
||||
network_mode: "host" # Direct host network access for P2P
|
||||
volumes:
|
||||
- ./data:/app/data
|
||||
- /var/run/docker.sock:/var/run/docker.sock # Docker API access
|
||||
environment:
|
||||
- NODE_ID=${HOSTNAME}
|
||||
- GITHUB_TOKEN_FILE=/run/secrets/github-token
|
||||
secrets:
|
||||
- github-token
|
||||
restart: unless-stopped
|
||||
deploy:
|
||||
placement:
|
||||
constraints:
|
||||
- node.role == worker # Deploy on all worker nodes
|
||||
```
|
||||
|
||||
**Rationale for Docker + Host Networking:**
|
||||
- ✅ **P2P Networking Advantages**: Direct access to host networking enables efficient mDNS discovery, NAT traversal, and lower latency communication
|
||||
- ✅ **Infrastructure Consistency**: Maintains Docker Swarm deployment patterns and existing operational procedures
|
||||
- ✅ **Resource Efficiency**: Eliminates Docker overlay network overhead for P2P communication
|
||||
- ✅ **Best of Both Worlds**: Container portability and management with native network performance
|
||||
|
||||
### 4.2. Cluster Integration Points
|
||||
|
||||
- **Phased Rollout:** Deploy `bzzz-agent` containers across all cluster nodes (ACACIA, WALNUT, IRONWOOD, ROSEWOOD, FORSTEINET) using Docker Swarm
|
||||
- **Network Architecture**: Leverages existing 192.168.1.0/24 LAN for P2P mesh communication
|
||||
- **Resource Coordination**: Agents discover and utilize existing Ollama endpoints (port 11434) and CLI tools
|
||||
- **Storage Integration**: Uses NFS shares (/rust/containers/) for shared configuration and Hypercore log storage
|
||||
|
||||
### 4.3. Integration with Existing Services
|
||||
|
||||
- **N8N as a Task Initiator:** High-level workflows in N8N will now terminate by creating a detailed GitHub Issue. This action triggers the Bzzz mesh, which handles the execution and reports back by creating a Pull Request.
|
||||
- **Hive Coexistence**: Bzzz will run alongside existing Hive services on different ports, allowing gradual migration of workloads
|
||||
- **The "Mesh Visualizer":** A dedicated monitoring dashboard will be created. It will:
|
||||
1. Subscribe to the `capabilities` pub/sub topic to visualize the live network topology.
|
||||
2. Replicate and display the Hypercore log streams from all active agents.
|
||||
3. Integrate with existing Grafana dashboards for unified monitoring
|
||||
|
||||
---
|
||||
|
||||
## 5. Security Strategy
|
||||
|
||||
- **GitHub Token Management:** Agents will use short-lived, fine-grained Personal Access Tokens. These tokens will be stored securely in **HashiCorp Vault** or a similar secrets management tool, and retrieved by the agent at runtime.
|
||||
- **Network Security:** All peer-to-peer communication is automatically **encrypted end-to-end** by `libp2p`.
|
||||
|
||||
---
|
||||
|
||||
## 6. Recommended Tech Stack
|
||||
|
||||
| Category | Recommendation | Notes |
|
||||
| :--- | :--- | :--- |
|
||||
| **Language** | **Go** or **Rust** | Strongly recommended for performance, concurrency, and system-level programming. |
|
||||
| **Networking** | `go-libp2p` / `rust-libp2p` | The official and most mature implementations. |
|
||||
| **Logging** | `hypercore-go` / `hypercore-rs` | Libraries for implementing the Hypercore Protocol. |
|
||||
| **GitHub API** | `go-github` / `octokit.rs` | Official and community-maintained clients for interacting with GitHub. |
|
||||
|
||||
---
|
||||
|
||||
## 7. Development Milestones
|
||||
|
||||
This 8-week plan incorporates the refined architecture.
|
||||
|
||||
| Week | Deliverables | Key Features |
|
||||
| :--- | :--- | :--- |
|
||||
| **1** | **P2P Foundation & Logging** | Setup libp2p peer discovery and establish a **Hypercore log stream** for each agent. |
|
||||
| **2** | **Capability Broadcasting** | Implement `capability_detector` and broadcast agent status via pub/sub. |
|
||||
| **3** | **GitHub Task Claiming** | Ingest issues from GitHub and implement the **assignment-based task claiming** logic. |
|
||||
| **4** | **Core Task Execution** | Integrate local CLIs (Ollama, etc.) to perform basic tasks based on issue content. |
|
||||
| **5** | **GitHub Result Workflow** | Implement logic to create Pull Requests or follow-up issues upon task completion. |
|
||||
| **6** | **Collaborative Help** | Implement the `task_help_request` and `task_help_response` flow with the **hop limit**. |
|
||||
| **7** | **Monitoring & Visualization** | Build the first version of the **Mesh Visualizer** dashboard to display agent status and logs. |
|
||||
| **8** | **Deployment & Testing** | Package the agent as a Docker container with host networking, write Docker Swarm deployment guide, and conduct end-to-end testing across cluster nodes. |
|
||||
|
||||
---
|
||||
|
||||
## 8. Potential Risks & Mitigation
|
||||
|
||||
- **Network Partitions ("Split-Brain"):**
|
||||
- **Risk:** A network partition could lead to two separate meshes trying to work on the same task.
|
||||
- **Mitigation:** Using GitHub's issue assignment as the atomic lock effectively solves this. The first agent to successfully claim the issue wins, regardless of network state.
|
||||
- **Dependency on GitHub:**
|
||||
- **Risk:** The system's ability to acquire new tasks is dependent on the availability of the GitHub API.
|
||||
- **Mitigation:** This is an accepted trade-off for gaining a robust, native task management platform. Agents can be designed to continue working on already-claimed tasks during a GitHub outage.
|
||||
- **Debugging Complexity:**
|
||||
- **Risk:** Debugging distributed systems remains challenging.
|
||||
- **Mitigation:** The Hypercore-based logging system provides a powerful and verifiable audit trail, which is a significant step towards mitigating this complexity. The Mesh Visualizer will also be a critical tool.
|
||||
- **Docker Host Networking Security:**
|
||||
- **Risk:** Host networking mode exposes containers directly to the host network, reducing isolation.
|
||||
- **Mitigation:**
|
||||
- Implement strict firewall rules on each node
|
||||
- Use libp2p's built-in encryption for all P2P communication
|
||||
- Run containers with restricted user privileges (non-root)
|
||||
- Regular security audits of exposed ports and services
|
||||
|
||||
---
|
||||
|
||||
## 9. Migration Strategy from Hive
|
||||
|
||||
### 9.1. Gradual Transition Plan
|
||||
|
||||
1. **Phase 1: Parallel Deployment** (Weeks 1-2)
|
||||
- Deploy Bzzz agents alongside existing Hive infrastructure
|
||||
- Use different port ranges to avoid conflicts
|
||||
- Monitor resource usage and network performance
|
||||
|
||||
2. **Phase 2: Simple Task Migration** (Weeks 3-4)
|
||||
- Route basic code generation tasks through GitHub issues → Bzzz
|
||||
- Keep complex multi-agent workflows in existing Hive + n8n
|
||||
- Compare performance metrics between systems
|
||||
|
||||
3. **Phase 3: Workflow Integration** (Weeks 5-6)
|
||||
- Modify n8n workflows to create GitHub issues as final step
|
||||
- Implement Bzzz → Hive result reporting for hybrid workflows
|
||||
- Test end-to-end task lifecycle
|
||||
|
||||
4. **Phase 4: Full Migration** (Weeks 7-8)
|
||||
- Migrate majority of workloads to Bzzz mesh
|
||||
- Retain Hive for monitoring and dashboard functionality
|
||||
- Plan eventual deprecation of centralized coordinator
|
||||
|
||||
### 9.2. Compatibility Layer
|
||||
|
||||
- **API Bridge**: Maintain existing Hive API endpoints that proxy to Bzzz mesh
|
||||
- **Data Migration**: Export task history and agent configurations from PostgreSQL
|
||||
- **Monitoring Continuity**: Integrate Bzzz metrics into existing Grafana dashboards
|
||||
224
PROJECT_PLAN.md
Normal file
224
PROJECT_PLAN.md
Normal file
@@ -0,0 +1,224 @@
|
||||
🐝 Project: Bzzz — P2P Task Coordination System
|
||||
|
||||
## 🔧 Architecture Overview (libp2p + pubsub + JSON)
|
||||
|
||||
This system will compliment and partially replace elements of the Hive Software System. This is intended to be a replacement for the multitude of MCP, and API calls to the ollama and gemini-cli agents over port 11434 etc. By replacing the master/slave paradigm with a mesh network we allow each node to trigger workflows or respond to calls for work as availability dictates rather than being stuck in endless timeouts awaiting responses. We also eliminate the central coordinator as a single point of failure.
|
||||
|
||||
### 📂 Components
|
||||
|
||||
#### 1. **Peer Node**
|
||||
|
||||
Each machine runs a P2P agent that:
|
||||
|
||||
- Connects to other peers via libp2p
|
||||
- Subscribes to pubsub topics
|
||||
- Periodically broadcasts status/capabilities
|
||||
- Receives and executes tasks
|
||||
- Publishes task results as GitHub pull requests or issues
|
||||
- Can request assistance from other peers
|
||||
- Monitors a GitHub repository for new issues (task source)
|
||||
|
||||
Each node uses a dedicated GitHub account with:
|
||||
- A personal access token (fine-scoped to repo/PRs)
|
||||
- A configured `.gitconfig` for commit identity
|
||||
|
||||
#### 2. **libp2p Network**
|
||||
|
||||
- All peers discover each other using mDNS, Bootstrap peers, or DHT
|
||||
- Peer identity is cryptographic (libp2p peer ID)
|
||||
- Communication is encrypted end-to-end
|
||||
|
||||
#### 3. **GitHub Integration**
|
||||
|
||||
- Tasks are sourced from GitHub Issues in a designated repository
|
||||
- Nodes will claim and respond to tasks by:
|
||||
- Forking the repository (once)
|
||||
- Creating a working branch
|
||||
- Making changes to files as instructed by task input
|
||||
- Committing changes using their GitHub identity
|
||||
- Creating a pull request or additional GitHub issues
|
||||
- Publishing final result as a PR, issue(s), or failure report
|
||||
|
||||
#### 4. **PubSub Topics**
|
||||
|
||||
| Topic | Direction | Purpose |
|
||||
|------------------|------------------|---------------------------------------------|
|
||||
| `capabilities` | Peer → All Peers | Broadcast available models, status |
|
||||
| `task_broadcast` | Peer → All Peers | Publish a GitHub issue as task |
|
||||
| `task_claim` | Peer → All Peers | Claim responsibility for a task |
|
||||
| `task_result` | Peer → All Peers | Share PR, issue, or failure result |
|
||||
| `presence_ping` | Peer → All Peers | Lightweight presence signal |
|
||||
| `task_help_request` | Peer → All Peers | Request assistance for a task |
|
||||
| `task_help_response`| Peer → All Peers | Offer help or handle sub-task |
|
||||
|
||||
### 📊 Data Flow Diagram
|
||||
```
|
||||
+------------------+ libp2p +------------------+
|
||||
| Peer A |<------------------->| Peer B |
|
||||
| |<------------------->| |
|
||||
| - Publishes: | | - Publishes: |
|
||||
| capabilities | | task_result |
|
||||
| task_broadcast | | capabilities |
|
||||
| help_request | | help_response |
|
||||
| - Subscribes to: | | - Subscribes to: |
|
||||
| task_result | | task_broadcast |
|
||||
| help_request | | help_request |
|
||||
+------------------+ +------------------+
|
||||
^ ^
|
||||
| |
|
||||
| |
|
||||
+----------------------+-----------------+
|
||||
|
|
||||
v
|
||||
+------------------+
|
||||
| Peer C |
|
||||
+------------------+
|
||||
```
|
||||
|
||||
### 📂 Sample JSON Messages
|
||||
|
||||
#### `capabilities`
|
||||
```json
|
||||
{
|
||||
"type": "capabilities",
|
||||
"node_id": "pi-node-1",
|
||||
"cpu": 43.5,
|
||||
"gpu": 2.3,
|
||||
"models": ["llama3", "mistral"],
|
||||
"installed": ["ollama", "gemini-cli"],
|
||||
"status": "idle",
|
||||
"timestamp": "2025-07-12T01:23:45Z"
|
||||
}
|
||||
```
|
||||
|
||||
#### `task_broadcast`
|
||||
```json
|
||||
{
|
||||
"type": "task",
|
||||
"task_id": "#42",
|
||||
"repo": "example-org/task-repo",
|
||||
"issue_url": "https://github.com/example-org/task-repo/issues/42",
|
||||
"model": "ollama",
|
||||
"input": "Add unit tests to utils module",
|
||||
"params": {"branch_prefix": "task-42-"},
|
||||
"timestamp": "2025-07-12T02:00:00Z"
|
||||
}
|
||||
```
|
||||
|
||||
#### `task_claim`
|
||||
```json
|
||||
{
|
||||
"type": "task_claim",
|
||||
"task_id": "#42",
|
||||
"node_id": "pi-node-2",
|
||||
"timestamp": "2025-07-12T02:00:03Z"
|
||||
}
|
||||
```
|
||||
|
||||
#### `task_result`
|
||||
```json
|
||||
{
|
||||
"type": "task_result",
|
||||
"task_id": "#42",
|
||||
"node_id": "pi-node-2",
|
||||
"result_type": "pull_request",
|
||||
"result_url": "https://github.com/example-org/task-repo/pull/97",
|
||||
"duration_ms": 15830,
|
||||
"timestamp": "2025-07-12T02:10:05Z"
|
||||
}
|
||||
```
|
||||
|
||||
#### `task_help_request`
|
||||
```json
|
||||
{
|
||||
"type": "task_help_request",
|
||||
"task_id": "#42",
|
||||
"from_node": "pi-node-2",
|
||||
"reason": "Long-running task or missing capability",
|
||||
"requested_capability": "claude-cli",
|
||||
"timestamp": "2025-07-12T02:05:00Z"
|
||||
}
|
||||
```
|
||||
|
||||
#### `task_help_response`
|
||||
```json
|
||||
{
|
||||
"type": "task_help_response",
|
||||
"task_id": "#42",
|
||||
"from_node": "pi-node-3",
|
||||
"can_help": true,
|
||||
"capabilities": ["claude-cli"],
|
||||
"eta_seconds": 30,
|
||||
"timestamp": "2025-07-12T02:05:02Z"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Development Brief
|
||||
|
||||
### 🧱 Tech Stack
|
||||
|
||||
- **Language**: Node.js (or Go/Rust)
|
||||
- **Networking**: libp2p
|
||||
- **Messaging**: pubsub with JSON
|
||||
- **Task Execution**: Local CLI (ollama, gemini, claude)
|
||||
- **System Monitoring**: `os-utils`, `psutil`, `nvidia-smi`
|
||||
- **Runtime**: systemd services on Linux
|
||||
- **GitHub Interaction**: `octokit` (Node), Git CLI
|
||||
|
||||
### 🛠 Key Modules
|
||||
|
||||
#### 1. `peer_agent.js`
|
||||
|
||||
- Initializes libp2p node
|
||||
- Joins pubsub topics
|
||||
- Periodically publishes capabilities
|
||||
- Listens for tasks, runs them, and reports PR/results
|
||||
- Handles help requests and responses
|
||||
|
||||
#### 2. `capability_detector.js`
|
||||
|
||||
- Detects:
|
||||
- CPU/GPU load
|
||||
- Installed models (via `ollama list`)
|
||||
- Installed CLIs (`which gemini`, `which claude`)
|
||||
|
||||
#### 3. `task_executor.js`
|
||||
|
||||
- Parses GitHub issue input
|
||||
- Forks repo (if needed)
|
||||
- Creates working branch, applies changes
|
||||
- Commits changes using local Git identity
|
||||
- Pushes branch and creates pull request or follow-up issues
|
||||
|
||||
#### 4. `github_bot.js`
|
||||
|
||||
- Authenticates GitHub API client
|
||||
- Watches for new issues in repo
|
||||
- Publishes them as `task_broadcast`
|
||||
- Handles PR/issue creation and error handling
|
||||
|
||||
#### 5. `state_manager.js`
|
||||
|
||||
- Keeps internal view of network state
|
||||
- Tracks peers’ capabilities, liveness
|
||||
- Matches help requests to eligible peers
|
||||
|
||||
### 📆 Milestones
|
||||
|
||||
| Week | Deliverables |
|
||||
| ---- | ------------------------------------------------------------ |
|
||||
| 1 | libp2p peer bootstrapping + pubsub skeleton |
|
||||
| 2 | JSON messaging spec + capability broadcasting |
|
||||
| 3 | GitHub issue ingestion + task broadcast |
|
||||
| 4 | CLI integration with Ollama/Gemini/Claude |
|
||||
| 5 | GitHub PR/issue/failure workflows |
|
||||
| 6 | Help request/response logic, delegation framework |
|
||||
| 7 | systemd setup, CLI utilities, and resilience |
|
||||
| 8 | End-to-end testing, GitHub org coordination, deployment guide|
|
||||
|
||||
---
|
||||
|
||||
Would you like a prototype `task_help_request` matchmaking function or sample test matrix for capability validation?
|
||||
|
||||
32
README.md
Normal file
32
README.md
Normal file
@@ -0,0 +1,32 @@
|
||||
# Bzzz + Antennae: Distributed P2P Task Coordination
|
||||
|
||||
Bzzz is a P2P task coordination system with the Antennae meta-discussion layer for collaborative AI reasoning.
|
||||
|
||||
## Architecture
|
||||
|
||||
- **P2P Networking**: libp2p-based mesh networking with mDNS discovery
|
||||
- **Task Coordination**: GitHub Issues as atomic task units
|
||||
- **Meta-Discussion**: Antennae layer for collaborative reasoning between agents
|
||||
- **Distributed Logging**: Hypercore-based tamper-proof audit trails
|
||||
|
||||
## Components
|
||||
|
||||
- `p2p/` - Core P2P networking using libp2p
|
||||
- `discovery/` - mDNS peer discovery for local network
|
||||
- `pubsub/` - Publish/subscribe messaging for coordination
|
||||
- `github/` - GitHub API integration for task management
|
||||
- `logging/` - Hypercore-based distributed logging
|
||||
- `cmd/` - Command-line interfaces
|
||||
|
||||
## Development Status
|
||||
|
||||
This project is being developed collaboratively across the deepblackcloud cluster:
|
||||
- **WALNUT**: P2P Networking Foundation (starcoder2:15b)
|
||||
- **IRONWOOD**: Distributed Logging System (phi4:14b)
|
||||
- **ACACIA**: GitHub Integration Module (codellama)
|
||||
|
||||
## Network Configuration
|
||||
|
||||
- **Local Network**: 192.168.1.0/24
|
||||
- **mDNS Discovery**: Automatic peer discovery
|
||||
- **Docker Deployment**: Host networking mode for P2P connectivity
|
||||
112
TASK_BACKLOG.md
Normal file
112
TASK_BACKLOG.md
Normal file
@@ -0,0 +1,112 @@
|
||||
# Bzzz + Antennae Development Task Backlog
|
||||
|
||||
Based on the UNIFIED_DEVELOPMENT_PLAN.md, here are the development tasks ready for distribution to the Hive cluster:
|
||||
|
||||
## Week 1-2: Foundation Tasks
|
||||
|
||||
### Task 1: P2P Networking Foundation 🔧
|
||||
**Assigned to**: WALNUT (Advanced Coding - starcoder2:15b)
|
||||
**Priority**: 5 (Critical)
|
||||
**Objective**: Design and implement core P2P networking foundation for Project Bzzz using libp2p in Go
|
||||
|
||||
**Requirements**:
|
||||
- Use go-libp2p library for mesh networking
|
||||
- Implement mDNS peer discovery for local network (192.168.1.0/24)
|
||||
- Create secure encrypted P2P connections with peer identity
|
||||
- Design pub/sub topics for both task coordination (Bzzz) and meta-discussion (Antennae)
|
||||
- Prepare for Docker + host networking deployment
|
||||
- Create modular Go code structure in `/home/tony/AI/projects/Bzzz/`
|
||||
|
||||
**Deliverables**:
|
||||
- `main.go` - Entry point and peer initialization
|
||||
- `p2p/` - P2P networking module with libp2p integration
|
||||
- `discovery/` - mDNS peer discovery implementation
|
||||
- `pubsub/` - Pub/sub messaging for capability broadcasting
|
||||
- `go.mod` - Go module definition with dependencies
|
||||
- `Dockerfile` - Container with host networking support
|
||||
|
||||
### Task 2: Distributed Logging System 📊
|
||||
**Assigned to**: IRONWOOD (Reasoning Analysis - phi4:14b)
|
||||
**Priority**: 4 (High)
|
||||
**Dependencies**: Task 1 (P2P Foundation)
|
||||
**Objective**: Architect and implement Hypercore-based distributed logging system
|
||||
|
||||
**Requirements**:
|
||||
- Design append-only log streams using Hypercore Protocol
|
||||
- Implement public key broadcasting for log identity
|
||||
- Create log replication capabilities between peers
|
||||
- Store both execution logs (Bzzz) and discussion transcripts (Antennae)
|
||||
- Ensure tamper-proof audit trails for debugging
|
||||
- Integrate with P2P capability detection module
|
||||
|
||||
**Deliverables**:
|
||||
- `logging/` - Hypercore-based logging module
|
||||
- `replication/` - Log replication and synchronization
|
||||
- `audit/` - Tamper-proof audit trail verification
|
||||
- Documentation on log schema and replication protocol
|
||||
|
||||
### Task 3: GitHub Integration Module 📋
|
||||
**Assigned to**: ACACIA (Code Review/Docs - codellama)
|
||||
**Priority**: 4 (High)
|
||||
**Dependencies**: Task 1 (P2P Foundation)
|
||||
**Objective**: Implement GitHub integration for atomic task claiming and collaborative workflows
|
||||
|
||||
**Requirements**:
|
||||
- Create atomic issue assignment mechanism (GitHub's native assignment)
|
||||
- Implement repository forking, branch creation, and commit workflows
|
||||
- Generate pull requests with discussion transcript links
|
||||
- Handle task result posting and failure reporting
|
||||
- Use GitHub API for all interactions
|
||||
- Include comprehensive error handling and retry logic
|
||||
|
||||
**Deliverables**:
|
||||
- `github/` - GitHub API integration module
|
||||
- `workflows/` - Repository and branch management
|
||||
- `tasks/` - Task claiming and result posting
|
||||
- Integration tests with GitHub API
|
||||
- Documentation on GitHub workflow process
|
||||
|
||||
## Week 3-4: Integration Tasks
|
||||
|
||||
### Task 4: Meta-Discussion Implementation 💬
|
||||
**Assigned to**: IRONWOOD (Reasoning Analysis)
|
||||
**Priority**: 3 (Medium)
|
||||
**Dependencies**: Task 1, Task 2
|
||||
**Objective**: Implement Antennae meta-discussion layer for collaborative reasoning
|
||||
|
||||
**Requirements**:
|
||||
- Create structured messaging for agent collaboration
|
||||
- Implement "propose plan" and "objection period" logic
|
||||
- Add hop limits (3 hops) and participant caps for safety
|
||||
- Design escalation paths to human intervention
|
||||
- Integrate with Hypercore logging for discussion transcripts
|
||||
|
||||
### Task 5: End-to-End Integration 🔄
|
||||
**Assigned to**: WALNUT (Advanced Coding)
|
||||
**Priority**: 2 (Normal)
|
||||
**Dependencies**: All previous tasks
|
||||
**Objective**: Integrate all components and create working Bzzz+Antennae system
|
||||
|
||||
**Requirements**:
|
||||
- Combine P2P networking, logging, and GitHub integration
|
||||
- Implement full task lifecycle with meta-discussion
|
||||
- Create Docker Swarm deployment configuration
|
||||
- Add monitoring and health checks
|
||||
- Comprehensive testing across cluster nodes
|
||||
|
||||
## Current Status
|
||||
|
||||
✅ **Hive Cluster Ready**: 3 agents registered with proper specializations
|
||||
- walnut: starcoder2:15b (kernel_dev)
|
||||
- ironwood: phi4:14b (reasoning)
|
||||
- acacia: codellama (docs_writer)
|
||||
|
||||
✅ **Authentication Working**: Dev user and API access configured
|
||||
|
||||
⚠️ **Task Submission**: Need to resolve API endpoint issues for automated task distribution
|
||||
|
||||
**Next Steps**:
|
||||
1. Fix task creation API endpoint issues
|
||||
2. Submit tasks to respective agents based on specializations
|
||||
3. Monitor execution and coordinate between agents
|
||||
4. Test the collaborative reasoning (Antennae) layer once P2P foundation is complete
|
||||
87
UNIFIED_DEVELOPMENT_PLAN.md
Normal file
87
UNIFIED_DEVELOPMENT_PLAN.md
Normal file
@@ -0,0 +1,87 @@
|
||||
# Project Bzzz & Antennae: Integrated Development Plan
|
||||
|
||||
## 1. Unified Vision
|
||||
|
||||
This document outlines a unified development plan for **Project Bzzz** and its integrated meta-discussion layer, **Project Antennae**. The vision is to build a decentralized task execution network where autonomous agents can not only **act** but also **reason and collaborate** before acting.
|
||||
|
||||
- **Bzzz** provides the core P2P execution fabric (task claiming, execution, results).
|
||||
- **Antennae** provides the collaborative "social brain" (task clarification, debate, knowledge sharing).
|
||||
|
||||
By developing them together, we create a system that is both resilient and intelligent.
|
||||
|
||||
---
|
||||
|
||||
## 2. Core Architecture
|
||||
|
||||
The combined architecture remains consistent with the principles of decentralization, leveraging a unified tech stack.
|
||||
|
||||
| Component | Technology | Purpose |
|
||||
| :--- | :--- | :--- |
|
||||
| **Networking** | **libp2p** | Peer discovery, identity, and secure P2P communication. |
|
||||
| **Task Management** | **GitHub Issues** | The single source of truth for task definition and atomic allocation via assignment. |
|
||||
| **Messaging** | **libp2p Pub/Sub** | Used for both `bzzz` (capabilities) and `antennae` (meta-discussion) topics. |
|
||||
| **Logging** | **Hypercore Protocol** | A single, tamper-proof log stream per agent will store both execution logs (Bzzz) and discussion transcripts (Antennae). |
|
||||
|
||||
---
|
||||
|
||||
## 3. Key Features & Refinements
|
||||
|
||||
### 3.1. Task Lifecycle with Meta-Discussion
|
||||
|
||||
The agent's task lifecycle will be enhanced to include a reasoning step:
|
||||
|
||||
1. **Discover & Claim:** An agent discovers an unassigned GitHub issue and claims it by assigning itself.
|
||||
2. **Open Meta-Channel:** The agent immediately joins a dedicated pub/sub topic: `bzzz/meta/issue/{id}`.
|
||||
3. **Propose Plan:** The agent posts its proposed plan of action to the channel. *e.g., "I will address this by modifying `file.py` and adding a new function `x()`."*
|
||||
4. **Listen & Discuss:** The agent waits for a brief "objection period" (e.g., 30 seconds). Other agents can chime in with suggestions, corrections, or questions. This is the core loop of the Antennae layer.
|
||||
5. **Execute:** If no major objections are raised, the agent proceeds with its plan.
|
||||
6. **Report:** The agent creates a Pull Request. The PR description will include a link to the Hypercore log containing the full transcript of the pre-execution discussion.
|
||||
|
||||
### 3.2. Safeguards and Structured Messaging
|
||||
|
||||
- **Combined Safeguards:** Hop limits, participant caps, and TTLs will apply to all meta-discussions to prevent runaway conversations.
|
||||
- **Structured Messages:** To improve machine comprehension, `meta_msg` payloads will be structured.
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "meta_msg",
|
||||
"issue_id": 42,
|
||||
"node_id": "bzzz-07",
|
||||
"msg_id": "abc123",
|
||||
"parent_id": null,
|
||||
"hop_count": 1,
|
||||
"content": {
|
||||
"query_type": "clarification_needed",
|
||||
"text": "What is the expected output format?",
|
||||
"parameters": { "field": "output_format" }
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 3.3. Human Escalation Path
|
||||
|
||||
- A dedicated pub/sub topic (`bzzz/meta/escalation`) will be used to flag discussions requiring human intervention.
|
||||
- An N8N workflow will monitor this topic and create alerts in a designated Slack channel or project management tool.
|
||||
|
||||
---
|
||||
|
||||
## 4. Integrated Development Milestones
|
||||
|
||||
This 8-week plan merges the development of both projects into a single, cohesive timeline.
|
||||
|
||||
| Week | Core Deliverable | Key Features & Integration Points |
|
||||
| :--- | :--- | :--- |
|
||||
| **1** | **P2P Foundation & Logging** | Establish the core agent identity and a unified **Hypercore log stream** for both action and discussion events. |
|
||||
| **2** | **Capability Broadcasting** | Agents broadcast capabilities, including which reasoning models they have available (e.g., `claude-3-opus`). |
|
||||
| **3** | **GitHub Task Claiming & Channel Creation** | Implement assignment-based task claiming. Upon claim, the agent **creates and subscribes to the meta-discussion channel**. |
|
||||
| **4** | **Pre-Execution Discussion** | Implement the "propose plan" and "listen for objections" logic. This is the first functional version of the Antennae layer. |
|
||||
| **5** | **Result Workflow with Logging** | Implement PR creation. The PR body **must link to the Hypercore discussion log**. |
|
||||
| **6** | **Full Collaborative Help** | Implement the full `task_help_request` and `meta_msg` response flow, respecting all safeguards (hop limits, TTLs). |
|
||||
| **7** | **Unified Monitoring** | The Mesh Visualizer dashboard will display agent status, execution logs, and **live meta-discussion transcripts**. |
|
||||
| **8** | **End-to-End Scenario Testing** | Conduct comprehensive tests for combined scenarios: task clarification, collaborative debugging, and successful escalation to a human. |
|
||||
|
||||
---
|
||||
|
||||
## 5. Conclusion
|
||||
|
||||
By integrating Antennae from the outset, we are not just building a distributed task runner; we are building a **distributed reasoning system**. This approach will lead to a more robust, intelligent, and auditable Hive, where agents think and collaborate before they act.
|
||||
124
discovery/mdns.go
Normal file
124
discovery/mdns.go
Normal file
@@ -0,0 +1,124 @@
|
||||
package discovery
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/libp2p/go-libp2p/core/host"
|
||||
"github.com/libp2p/go-libp2p/core/peer"
|
||||
"github.com/libp2p/go-libp2p/p2p/discovery/mdns"
|
||||
)
|
||||
|
||||
// MDNSDiscovery handles mDNS peer discovery for local network
|
||||
type MDNSDiscovery struct {
|
||||
host host.Host
|
||||
service mdns.Service
|
||||
notifee *mdnsNotifee
|
||||
ctx context.Context
|
||||
cancel context.CancelFunc
|
||||
serviceTag string
|
||||
}
|
||||
|
||||
// mdnsNotifee handles discovered peers
|
||||
type mdnsNotifee struct {
|
||||
h host.Host
|
||||
ctx context.Context
|
||||
peersChan chan peer.AddrInfo
|
||||
}
|
||||
|
||||
// NewMDNSDiscovery creates a new mDNS discovery service
|
||||
func NewMDNSDiscovery(ctx context.Context, h host.Host, serviceTag string) (*MDNSDiscovery, error) {
|
||||
if serviceTag == "" {
|
||||
serviceTag = "bzzz-peer-discovery"
|
||||
}
|
||||
|
||||
discoveryCtx, cancel := context.WithCancel(ctx)
|
||||
|
||||
// Create notifee to handle discovered peers
|
||||
notifee := &mdnsNotifee{
|
||||
h: h,
|
||||
ctx: discoveryCtx,
|
||||
peersChan: make(chan peer.AddrInfo, 10),
|
||||
}
|
||||
|
||||
// Create mDNS service
|
||||
service := mdns.NewMdnsService(h, serviceTag, notifee)
|
||||
|
||||
discovery := &MDNSDiscovery{
|
||||
host: h,
|
||||
service: service,
|
||||
notifee: notifee,
|
||||
ctx: discoveryCtx,
|
||||
cancel: cancel,
|
||||
serviceTag: serviceTag,
|
||||
}
|
||||
|
||||
// Start the service
|
||||
if err := service.Start(); err != nil {
|
||||
cancel()
|
||||
return nil, fmt.Errorf("failed to start mDNS service: %w", err)
|
||||
}
|
||||
|
||||
// Start background peer connection handler
|
||||
go discovery.handleDiscoveredPeers()
|
||||
|
||||
fmt.Printf("🔍 mDNS Discovery started with service tag: %s\n", serviceTag)
|
||||
return discovery, nil
|
||||
}
|
||||
|
||||
// PeersChan returns a channel that receives discovered peers
|
||||
func (d *MDNSDiscovery) PeersChan() <-chan peer.AddrInfo {
|
||||
return d.notifee.peersChan
|
||||
}
|
||||
|
||||
// handleDiscoveredPeers processes discovered peers and attempts connections
|
||||
func (d *MDNSDiscovery) handleDiscoveredPeers() {
|
||||
for {
|
||||
select {
|
||||
case <-d.ctx.Done():
|
||||
return
|
||||
case peerInfo := <-d.notifee.peersChan:
|
||||
// Skip self
|
||||
if peerInfo.ID == d.host.ID() {
|
||||
continue
|
||||
}
|
||||
|
||||
// Check if already connected
|
||||
if d.host.Network().Connectedness(peerInfo.ID) == 1 { // Connected
|
||||
continue
|
||||
}
|
||||
|
||||
// Attempt to connect
|
||||
fmt.Printf("🤝 Discovered peer %s, attempting connection...\n", peerInfo.ID.ShortString())
|
||||
|
||||
connectCtx, cancel := context.WithTimeout(d.ctx, 10*time.Second)
|
||||
if err := d.host.Connect(connectCtx, peerInfo); err != nil {
|
||||
fmt.Printf("❌ Failed to connect to peer %s: %v\n", peerInfo.ID.ShortString(), err)
|
||||
} else {
|
||||
fmt.Printf("✅ Successfully connected to peer %s\n", peerInfo.ID.ShortString())
|
||||
}
|
||||
cancel()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Close shuts down the mDNS discovery service
|
||||
func (d *MDNSDiscovery) Close() error {
|
||||
d.cancel()
|
||||
close(d.notifee.peersChan)
|
||||
return d.service.Close()
|
||||
}
|
||||
|
||||
// HandlePeerFound is called when a peer is discovered via mDNS
|
||||
func (n *mdnsNotifee) HandlePeerFound(pi peer.AddrInfo) {
|
||||
select {
|
||||
case <-n.ctx.Done():
|
||||
return
|
||||
case n.peersChan <- pi:
|
||||
// Peer info sent to channel
|
||||
default:
|
||||
// Channel is full, skip this peer
|
||||
fmt.Printf("⚠️ Discovery channel full, skipping peer %s\n", pi.ID.ShortString())
|
||||
}
|
||||
}
|
||||
381
github/client.go
Normal file
381
github/client.go
Normal file
@@ -0,0 +1,381 @@
|
||||
package github
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/google/go-github/v57/github"
|
||||
"golang.org/x/oauth2"
|
||||
)
|
||||
|
||||
// Client wraps the GitHub API client for Bzzz task management
|
||||
type Client struct {
|
||||
client *github.Client
|
||||
ctx context.Context
|
||||
config *Config
|
||||
}
|
||||
|
||||
// Config holds GitHub integration configuration
|
||||
type Config struct {
|
||||
AccessToken string
|
||||
Owner string // GitHub organization/user
|
||||
Repository string // Repository for task coordination
|
||||
|
||||
// Task management settings
|
||||
TaskLabel string // Label for Bzzz tasks
|
||||
InProgressLabel string // Label for tasks in progress
|
||||
CompletedLabel string // Label for completed tasks
|
||||
|
||||
// Branch management
|
||||
BaseBranch string // Base branch for task branches
|
||||
BranchPrefix string // Prefix for task branches
|
||||
}
|
||||
|
||||
// NewClient creates a new GitHub client for Bzzz integration
|
||||
func NewClient(ctx context.Context, config *Config) (*Client, error) {
|
||||
if config.AccessToken == "" {
|
||||
return nil, fmt.Errorf("GitHub access token is required")
|
||||
}
|
||||
|
||||
if config.Owner == "" || config.Repository == "" {
|
||||
return nil, fmt.Errorf("GitHub owner and repository are required")
|
||||
}
|
||||
|
||||
// Set defaults
|
||||
if config.TaskLabel == "" {
|
||||
config.TaskLabel = "bzzz-task"
|
||||
}
|
||||
if config.InProgressLabel == "" {
|
||||
config.InProgressLabel = "in-progress"
|
||||
}
|
||||
if config.CompletedLabel == "" {
|
||||
config.CompletedLabel = "completed"
|
||||
}
|
||||
if config.BaseBranch == "" {
|
||||
config.BaseBranch = "main"
|
||||
}
|
||||
if config.BranchPrefix == "" {
|
||||
config.BranchPrefix = "bzzz/task-"
|
||||
}
|
||||
|
||||
// Create OAuth2 token source
|
||||
ts := oauth2.StaticTokenSource(
|
||||
&oauth2.Token{AccessToken: config.AccessToken},
|
||||
)
|
||||
tc := oauth2.NewClient(ctx, ts)
|
||||
|
||||
client := &Client{
|
||||
client: github.NewClient(tc),
|
||||
ctx: ctx,
|
||||
config: config,
|
||||
}
|
||||
|
||||
// Verify access to repository
|
||||
if err := client.verifyAccess(); err != nil {
|
||||
return nil, fmt.Errorf("failed to verify GitHub access: %w", err)
|
||||
}
|
||||
|
||||
return client, nil
|
||||
}
|
||||
|
||||
// verifyAccess checks if we can access the configured repository
|
||||
func (c *Client) verifyAccess() error {
|
||||
_, _, err := c.client.Repositories.Get(c.ctx, c.config.Owner, c.config.Repository)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot access repository %s/%s: %w",
|
||||
c.config.Owner, c.config.Repository, err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Task represents a Bzzz task as a GitHub issue
|
||||
type Task struct {
|
||||
ID int64 `json:"id"`
|
||||
Number int `json:"number"`
|
||||
Title string `json:"title"`
|
||||
Description string `json:"description"`
|
||||
State string `json:"state"` // open, closed
|
||||
Labels []string `json:"labels"`
|
||||
Assignee string `json:"assignee"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
|
||||
// Bzzz-specific fields
|
||||
TaskType string `json:"task_type"`
|
||||
Priority int `json:"priority"`
|
||||
Requirements []string `json:"requirements"`
|
||||
Deliverables []string `json:"deliverables"`
|
||||
Context map[string]interface{} `json:"context"`
|
||||
}
|
||||
|
||||
// CreateTask creates a new GitHub issue for a Bzzz task
|
||||
func (c *Client) CreateTask(task *Task) (*Task, error) {
|
||||
// Prepare issue request
|
||||
issue := &github.IssueRequest{
|
||||
Title: &task.Title,
|
||||
Body: github.String(c.formatTaskBody(task)),
|
||||
Labels: &[]string{
|
||||
c.config.TaskLabel,
|
||||
fmt.Sprintf("priority-%d", task.Priority),
|
||||
fmt.Sprintf("type-%s", task.TaskType),
|
||||
},
|
||||
}
|
||||
|
||||
// Create the issue
|
||||
createdIssue, _, err := c.client.Issues.Create(
|
||||
c.ctx,
|
||||
c.config.Owner,
|
||||
c.config.Repository,
|
||||
issue,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create GitHub issue: %w", err)
|
||||
}
|
||||
|
||||
// Convert back to our Task format
|
||||
return c.issueToTask(createdIssue), nil
|
||||
}
|
||||
|
||||
// ClaimTask atomically assigns a task to an agent
|
||||
func (c *Client) ClaimTask(issueNumber int, agentID string) (*Task, error) {
|
||||
// Get current issue state
|
||||
issue, _, err := c.client.Issues.Get(
|
||||
c.ctx,
|
||||
c.config.Owner,
|
||||
c.config.Repository,
|
||||
issueNumber,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get issue: %w", err)
|
||||
}
|
||||
|
||||
// Check if already assigned
|
||||
if issue.Assignee != nil {
|
||||
return nil, fmt.Errorf("task already assigned to %s", issue.Assignee.GetLogin())
|
||||
}
|
||||
|
||||
// Attempt atomic assignment using GitHub's native assignment
|
||||
issueRequest := &github.IssueRequest{
|
||||
Assignee: &agentID,
|
||||
}
|
||||
|
||||
// Add in-progress label
|
||||
currentLabels := make([]string, 0, len(issue.Labels)+1)
|
||||
for _, label := range issue.Labels {
|
||||
currentLabels = append(currentLabels, label.GetName())
|
||||
}
|
||||
currentLabels = append(currentLabels, c.config.InProgressLabel)
|
||||
issueRequest.Labels = ¤tLabels
|
||||
|
||||
// Update the issue
|
||||
updatedIssue, _, err := c.client.Issues.Edit(
|
||||
c.ctx,
|
||||
c.config.Owner,
|
||||
c.config.Repository,
|
||||
issueNumber,
|
||||
issueRequest,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to claim task: %w", err)
|
||||
}
|
||||
|
||||
// Create a task branch
|
||||
if err := c.createTaskBranch(issueNumber, agentID); err != nil {
|
||||
// Log error but don't fail the claim
|
||||
fmt.Printf("⚠️ Failed to create task branch: %v\n", err)
|
||||
}
|
||||
|
||||
return c.issueToTask(updatedIssue), nil
|
||||
}
|
||||
|
||||
// CompleteTask marks a task as completed and creates a pull request
|
||||
func (c *Client) CompleteTask(issueNumber int, agentID string, results map[string]interface{}) error {
|
||||
// Update issue labels
|
||||
issue, _, err := c.client.Issues.Get(
|
||||
c.ctx,
|
||||
c.config.Owner,
|
||||
c.config.Repository,
|
||||
issueNumber,
|
||||
)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get issue: %w", err)
|
||||
}
|
||||
|
||||
// Remove in-progress label, add completed label
|
||||
newLabels := make([]string, 0, len(issue.Labels))
|
||||
for _, label := range issue.Labels {
|
||||
labelName := label.GetName()
|
||||
if labelName != c.config.InProgressLabel {
|
||||
newLabels = append(newLabels, labelName)
|
||||
}
|
||||
}
|
||||
newLabels = append(newLabels, c.config.CompletedLabel)
|
||||
|
||||
// Add completion comment
|
||||
comment := &github.IssueComment{
|
||||
Body: github.String(c.formatCompletionComment(agentID, results)),
|
||||
}
|
||||
|
||||
_, _, err = c.client.Issues.CreateComment(
|
||||
c.ctx,
|
||||
c.config.Owner,
|
||||
c.config.Repository,
|
||||
issueNumber,
|
||||
comment,
|
||||
)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to add completion comment: %w", err)
|
||||
}
|
||||
|
||||
// Update labels
|
||||
issueRequest := &github.IssueRequest{
|
||||
Labels: &newLabels,
|
||||
State: github.String("closed"),
|
||||
}
|
||||
|
||||
_, _, err = c.client.Issues.Edit(
|
||||
c.ctx,
|
||||
c.config.Owner,
|
||||
c.config.Repository,
|
||||
issueNumber,
|
||||
issueRequest,
|
||||
)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to update issue: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ListAvailableTasks returns unassigned Bzzz tasks
|
||||
func (c *Client) ListAvailableTasks() ([]*Task, error) {
|
||||
// Search for open issues with Bzzz task label and no assignee
|
||||
opts := &github.IssueListByRepoOptions{
|
||||
State: "open",
|
||||
Labels: []string{c.config.TaskLabel},
|
||||
Assignee: "none",
|
||||
Sort: "created",
|
||||
Direction: "desc",
|
||||
ListOptions: github.ListOptions{PerPage: 50},
|
||||
}
|
||||
|
||||
issues, _, err := c.client.Issues.ListByRepo(
|
||||
c.ctx,
|
||||
c.config.Owner,
|
||||
c.config.Repository,
|
||||
opts,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to list issues: %w", err)
|
||||
}
|
||||
|
||||
tasks := make([]*Task, 0, len(issues))
|
||||
for _, issue := range issues {
|
||||
tasks = append(tasks, c.issueToTask(issue))
|
||||
}
|
||||
|
||||
return tasks, nil
|
||||
}
|
||||
|
||||
// createTaskBranch creates a new branch for task work
|
||||
func (c *Client) createTaskBranch(issueNumber int, agentID string) error {
|
||||
branchName := fmt.Sprintf("%s%d-%s", c.config.BranchPrefix, issueNumber, agentID)
|
||||
|
||||
// Get the base branch reference
|
||||
baseRef, _, err := c.client.Git.GetRef(
|
||||
c.ctx,
|
||||
c.config.Owner,
|
||||
c.config.Repository,
|
||||
"refs/heads/"+c.config.BaseBranch,
|
||||
)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get base branch: %w", err)
|
||||
}
|
||||
|
||||
// Create new branch
|
||||
newRef := &github.Reference{
|
||||
Ref: github.String("refs/heads/" + branchName),
|
||||
Object: &github.GitObject{
|
||||
SHA: baseRef.Object.SHA,
|
||||
},
|
||||
}
|
||||
|
||||
_, _, err = c.client.Git.CreateRef(
|
||||
c.ctx,
|
||||
c.config.Owner,
|
||||
c.config.Repository,
|
||||
newRef,
|
||||
)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create branch: %w", err)
|
||||
}
|
||||
|
||||
fmt.Printf("🌿 Created task branch: %s\n", branchName)
|
||||
return nil
|
||||
}
|
||||
|
||||
// formatTaskBody formats task details into GitHub issue body
|
||||
func (c *Client) formatTaskBody(task *Task) string {
|
||||
body := fmt.Sprintf("**Task Type:** %s\n", task.TaskType)
|
||||
body += fmt.Sprintf("**Priority:** %d\n", task.Priority)
|
||||
body += fmt.Sprintf("\n**Description:**\n%s\n", task.Description)
|
||||
|
||||
if len(task.Requirements) > 0 {
|
||||
body += "\n**Requirements:**\n"
|
||||
for _, req := range task.Requirements {
|
||||
body += fmt.Sprintf("- %s\n", req)
|
||||
}
|
||||
}
|
||||
|
||||
if len(task.Deliverables) > 0 {
|
||||
body += "\n**Deliverables:**\n"
|
||||
for _, deliverable := range task.Deliverables {
|
||||
body += fmt.Sprintf("- %s\n", deliverable)
|
||||
}
|
||||
}
|
||||
|
||||
body += "\n---\n*This task is managed by Bzzz P2P Task Coordination System*"
|
||||
return body
|
||||
}
|
||||
|
||||
// formatCompletionComment formats task completion results
|
||||
func (c *Client) formatCompletionComment(agentID string, results map[string]interface{}) string {
|
||||
comment := fmt.Sprintf("✅ **Task completed by agent: %s**\n\n", agentID)
|
||||
comment += fmt.Sprintf("**Completion time:** %s\n\n", time.Now().Format(time.RFC3339))
|
||||
|
||||
if len(results) > 0 {
|
||||
comment += "**Results:**\n"
|
||||
for key, value := range results {
|
||||
comment += fmt.Sprintf("- **%s:** %v\n", key, value)
|
||||
}
|
||||
}
|
||||
|
||||
return comment
|
||||
}
|
||||
|
||||
// issueToTask converts a GitHub issue to a Bzzz task
|
||||
func (c *Client) issueToTask(issue *github.Issue) *Task {
|
||||
task := &Task{
|
||||
ID: issue.GetID(),
|
||||
Number: issue.GetNumber(),
|
||||
Title: issue.GetTitle(),
|
||||
Description: issue.GetBody(),
|
||||
State: issue.GetState(),
|
||||
CreatedAt: issue.GetCreatedAt().Time,
|
||||
UpdatedAt: issue.GetUpdatedAt().Time,
|
||||
}
|
||||
|
||||
// Extract labels
|
||||
task.Labels = make([]string, 0, len(issue.Labels))
|
||||
for _, label := range issue.Labels {
|
||||
task.Labels = append(task.Labels, label.GetName())
|
||||
}
|
||||
|
||||
// Extract assignee
|
||||
if issue.Assignee != nil {
|
||||
task.Assignee = issue.Assignee.GetLogin()
|
||||
}
|
||||
|
||||
return task
|
||||
}
|
||||
207
github/integration.go
Normal file
207
github/integration.go
Normal file
@@ -0,0 +1,207 @@
|
||||
package github
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/deepblackcloud/bzzz/pubsub"
|
||||
)
|
||||
|
||||
// Integration handles the integration between GitHub tasks and Bzzz P2P coordination
|
||||
type Integration struct {
|
||||
client *Client
|
||||
pubsub *pubsub.PubSub
|
||||
ctx context.Context
|
||||
config *IntegrationConfig
|
||||
}
|
||||
|
||||
// IntegrationConfig holds configuration for GitHub-Bzzz integration
|
||||
type IntegrationConfig struct {
|
||||
PollInterval time.Duration // How often to check for new tasks
|
||||
MaxTasks int // Maximum tasks to process simultaneously
|
||||
AgentID string // This agent's identifier
|
||||
Capabilities []string // What types of tasks this agent can handle
|
||||
}
|
||||
|
||||
// NewIntegration creates a new GitHub-Bzzz integration
|
||||
func NewIntegration(ctx context.Context, client *Client, ps *pubsub.PubSub, config *IntegrationConfig) *Integration {
|
||||
if config.PollInterval == 0 {
|
||||
config.PollInterval = 30 * time.Second
|
||||
}
|
||||
if config.MaxTasks == 0 {
|
||||
config.MaxTasks = 3
|
||||
}
|
||||
|
||||
return &Integration{
|
||||
client: client,
|
||||
pubsub: ps,
|
||||
ctx: ctx,
|
||||
config: config,
|
||||
}
|
||||
}
|
||||
|
||||
// Start begins the GitHub-Bzzz integration
|
||||
func (i *Integration) Start() {
|
||||
fmt.Printf("🔗 Starting GitHub-Bzzz integration for agent: %s\n", i.config.AgentID)
|
||||
|
||||
// Start task polling
|
||||
go i.pollForTasks()
|
||||
|
||||
// Start listening for P2P task announcements
|
||||
go i.listenForTaskAnnouncements()
|
||||
}
|
||||
|
||||
// pollForTasks periodically checks GitHub for available tasks
|
||||
func (i *Integration) pollForTasks() {
|
||||
ticker := time.NewTicker(i.config.PollInterval)
|
||||
defer ticker.Stop()
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-i.ctx.Done():
|
||||
return
|
||||
case <-ticker.C:
|
||||
if err := i.checkAndClaimTasks(); err != nil {
|
||||
fmt.Printf("❌ Error checking tasks: %v\n", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// checkAndClaimTasks looks for available tasks and claims suitable ones
|
||||
func (i *Integration) checkAndClaimTasks() error {
|
||||
// Get available tasks
|
||||
tasks, err := i.client.ListAvailableTasks()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to list tasks: %w", err)
|
||||
}
|
||||
|
||||
if len(tasks) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
fmt.Printf("📋 Found %d available tasks\n", len(tasks))
|
||||
|
||||
// Filter tasks based on capabilities
|
||||
suitableTasks := i.filterSuitableTasks(tasks)
|
||||
|
||||
if len(suitableTasks) == 0 {
|
||||
fmt.Printf("⚠️ No suitable tasks for agent capabilities: %v\n", i.config.Capabilities)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Claim the highest priority suitable task
|
||||
task := suitableTasks[0] // Assuming sorted by priority
|
||||
claimedTask, err := i.client.ClaimTask(task.Number, i.config.AgentID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to claim task %d: %w", task.Number, err)
|
||||
}
|
||||
|
||||
fmt.Printf("✋ Claimed task #%d: %s\n", claimedTask.Number, claimedTask.Title)
|
||||
|
||||
// Announce the claim over P2P
|
||||
if err := i.announceTaskClaim(claimedTask); err != nil {
|
||||
fmt.Printf("⚠️ Failed to announce task claim: %v\n", err)
|
||||
}
|
||||
|
||||
// Start working on the task
|
||||
go i.executeTask(claimedTask)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// filterSuitableTasks filters tasks based on agent capabilities
|
||||
func (i *Integration) filterSuitableTasks(tasks []*Task) []*Task {
|
||||
suitable := make([]*Task, 0)
|
||||
|
||||
for _, task := range tasks {
|
||||
// Check if this agent can handle this task type
|
||||
if i.canHandleTaskType(task.TaskType) {
|
||||
suitable = append(suitable, task)
|
||||
}
|
||||
}
|
||||
|
||||
return suitable
|
||||
}
|
||||
|
||||
// canHandleTaskType checks if this agent can handle the given task type
|
||||
func (i *Integration) canHandleTaskType(taskType string) bool {
|
||||
for _, capability := range i.config.Capabilities {
|
||||
if capability == taskType || capability == "general" {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// announceTaskClaim announces a task claim over the P2P network
|
||||
func (i *Integration) announceTaskClaim(task *Task) error {
|
||||
data := map[string]interface{}{
|
||||
"task_id": task.Number,
|
||||
"task_title": task.Title,
|
||||
"task_type": task.TaskType,
|
||||
"agent_id": i.config.AgentID,
|
||||
"claimed_at": time.Now().Unix(),
|
||||
"github_url": fmt.Sprintf("https://github.com/%s/%s/issues/%d",
|
||||
i.client.config.Owner, i.client.config.Repository, task.Number),
|
||||
}
|
||||
|
||||
return i.pubsub.PublishBzzzMessage(pubsub.TaskClaim, data)
|
||||
}
|
||||
|
||||
// executeTask simulates task execution
|
||||
func (i *Integration) executeTask(task *Task) {
|
||||
fmt.Printf("🚀 Starting execution of task #%d: %s\n", task.Number, task.Title)
|
||||
|
||||
// Announce task progress
|
||||
progressData := map[string]interface{}{
|
||||
"task_id": task.Number,
|
||||
"agent_id": i.config.AgentID,
|
||||
"status": "started",
|
||||
"timestamp": time.Now().Unix(),
|
||||
}
|
||||
|
||||
if err := i.pubsub.PublishBzzzMessage(pubsub.TaskProgress, progressData); err != nil {
|
||||
fmt.Printf("⚠️ Failed to announce task progress: %v\n", err)
|
||||
}
|
||||
|
||||
// Simulate work (in a real implementation, this would be actual task execution)
|
||||
workDuration := time.Duration(30+task.Priority*10) * time.Second
|
||||
fmt.Printf("⏳ Working on task for %v...\n", workDuration)
|
||||
time.Sleep(workDuration)
|
||||
|
||||
// Complete the task
|
||||
results := map[string]interface{}{
|
||||
"status": "completed",
|
||||
"execution_time": workDuration.String(),
|
||||
"agent_id": i.config.AgentID,
|
||||
"deliverables": []string{"Implementation completed", "Tests passed", "Documentation updated"},
|
||||
}
|
||||
|
||||
if err := i.client.CompleteTask(task.Number, i.config.AgentID, results); err != nil {
|
||||
fmt.Printf("❌ Failed to complete task #%d: %v\n", task.Number, err)
|
||||
return
|
||||
}
|
||||
|
||||
// Announce completion over P2P
|
||||
completionData := map[string]interface{}{
|
||||
"task_id": task.Number,
|
||||
"agent_id": i.config.AgentID,
|
||||
"completed_at": time.Now().Unix(),
|
||||
"results": results,
|
||||
}
|
||||
|
||||
if err := i.pubsub.PublishBzzzMessage(pubsub.TaskComplete, completionData); err != nil {
|
||||
fmt.Printf("⚠️ Failed to announce task completion: %v\n", err)
|
||||
}
|
||||
|
||||
fmt.Printf("✅ Completed task #%d: %s\n", task.Number, task.Title)
|
||||
}
|
||||
|
||||
// listenForTaskAnnouncements listens for task announcements from other agents
|
||||
func (i *Integration) listenForTaskAnnouncements() {
|
||||
// This would integrate with the pubsub message handlers
|
||||
// For now, it's a placeholder that demonstrates the pattern
|
||||
fmt.Printf("👂 Listening for task announcements from other agents...\n")
|
||||
}
|
||||
99
go.mod
Normal file
99
go.mod
Normal file
@@ -0,0 +1,99 @@
|
||||
module github.com/deepblackcloud/bzzz
|
||||
|
||||
go 1.21
|
||||
|
||||
require (
|
||||
github.com/google/go-github/v57 v57.0.0
|
||||
github.com/libp2p/go-libp2p v0.32.0
|
||||
github.com/libp2p/go-libp2p-pubsub v0.10.0
|
||||
github.com/multiformats/go-multiaddr v0.12.0
|
||||
golang.org/x/oauth2 v0.15.0
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/benbjohnson/clock v1.3.5 // indirect
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.2.0 // indirect
|
||||
github.com/containerd/cgroups v1.1.0 // indirect
|
||||
github.com/coreos/go-systemd/v22 v22.5.0 // indirect
|
||||
github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c // indirect
|
||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect
|
||||
github.com/docker/go-units v0.5.0 // indirect
|
||||
github.com/elastic/gosigar v0.14.2 // indirect
|
||||
github.com/flynn/noise v1.0.0 // indirect
|
||||
github.com/francoispqt/gojay v1.2.13 // indirect
|
||||
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect
|
||||
github.com/godbus/dbus/v5 v5.1.0 // indirect
|
||||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
github.com/golang/protobuf v1.5.3 // indirect
|
||||
github.com/google/go-querystring v1.1.0 // indirect
|
||||
github.com/google/gopacket v1.1.19 // indirect
|
||||
github.com/google/pprof v0.0.0-20231023181126-ff6d637d2a7b // indirect
|
||||
github.com/gorilla/websocket v1.5.0 // indirect
|
||||
github.com/hashicorp/golang-lru/v2 v2.0.5 // indirect
|
||||
github.com/huin/goupnp v1.3.0 // indirect
|
||||
github.com/ipfs/go-cid v0.4.1 // indirect
|
||||
github.com/ipfs/go-log/v2 v2.5.1 // indirect
|
||||
github.com/jackpal/go-nat-pmp v1.0.2 // indirect
|
||||
github.com/jbenet/go-temp-err-catcher v0.1.0 // indirect
|
||||
github.com/klauspost/compress v1.17.2 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.2.5 // indirect
|
||||
github.com/koron/go-ssdp v0.0.4 // indirect
|
||||
github.com/libp2p/go-buffer-pool v0.1.0 // indirect
|
||||
github.com/libp2p/go-cidranger v1.1.0 // indirect
|
||||
github.com/libp2p/go-flow-metrics v0.1.0 // indirect
|
||||
github.com/libp2p/go-libp2p-asn-util v0.3.0 // indirect
|
||||
github.com/libp2p/go-msgio v0.3.0 // indirect
|
||||
github.com/libp2p/go-nat v0.2.0 // indirect
|
||||
github.com/libp2p/go-netroute v0.2.1 // indirect
|
||||
github.com/libp2p/go-reuseport v0.4.0 // indirect
|
||||
github.com/libp2p/go-yamux/v4 v4.0.1 // indirect
|
||||
github.com/libp2p/zeroconf/v2 v2.2.0 // indirect
|
||||
github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
|
||||
github.com/miekg/dns v1.1.56 // indirect
|
||||
github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b // indirect
|
||||
github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc // indirect
|
||||
github.com/minio/sha256-simd v1.0.1 // indirect
|
||||
github.com/mr-tron/base58 v1.2.0 // indirect
|
||||
github.com/multiformats/go-base32 v0.1.0 // indirect
|
||||
github.com/multiformats/go-base36 v0.2.0 // indirect
|
||||
github.com/multiformats/go-multiaddr-dns v0.3.1 // indirect
|
||||
github.com/multiformats/go-multiaddr-fmt v0.1.0 // indirect
|
||||
github.com/multiformats/go-multibase v0.2.0 // indirect
|
||||
github.com/multiformats/go-multicodec v0.9.0 // indirect
|
||||
github.com/multiformats/go-multihash v0.2.3 // indirect
|
||||
github.com/multiformats/go-multistream v0.5.0 // indirect
|
||||
github.com/multiformats/go-varint v0.0.7 // indirect
|
||||
github.com/onsi/ginkgo/v2 v2.13.0 // indirect
|
||||
github.com/opencontainers/runtime-spec v1.1.0 // indirect
|
||||
github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/prometheus/client_golang v1.14.0 // indirect
|
||||
github.com/prometheus/client_model v0.4.0 // indirect
|
||||
github.com/prometheus/common v0.37.0 // indirect
|
||||
github.com/prometheus/procfs v0.8.0 // indirect
|
||||
github.com/quic-go/qpack v0.4.0 // indirect
|
||||
github.com/quic-go/qtls-go1-20 v0.3.4 // indirect
|
||||
github.com/quic-go/quic-go v0.39.3 // indirect
|
||||
github.com/quic-go/webtransport-go v0.6.0 // indirect
|
||||
github.com/raulk/go-watchdog v1.3.0 // indirect
|
||||
github.com/spaolacci/murmur3 v1.1.0 // indirect
|
||||
go.uber.org/dig v1.17.1 // indirect
|
||||
go.uber.org/fx v1.20.1 // indirect
|
||||
go.uber.org/mock v0.3.0 // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
go.uber.org/zap v1.26.0 // indirect
|
||||
golang.org/x/crypto v0.16.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20231006140011-7918f672742d // indirect
|
||||
golang.org/x/mod v0.13.0 // indirect
|
||||
golang.org/x/net v0.19.0 // indirect
|
||||
golang.org/x/sync v0.4.0 // indirect
|
||||
golang.org/x/sys v0.15.0 // indirect
|
||||
golang.org/x/text v0.14.0 // indirect
|
||||
golang.org/x/tools v0.14.0 // indirect
|
||||
google.golang.org/appengine v1.6.7 // indirect
|
||||
google.golang.org/protobuf v1.31.0 // indirect
|
||||
lukechampine.com/blake3 v1.2.1 // indirect
|
||||
)
|
||||
837
go.sum
Normal file
837
go.sum
Normal file
@@ -0,0 +1,837 @@
|
||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
cloud.google.com/go v0.31.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
cloud.google.com/go v0.37.0/go.mod h1:TS1dMSSfndXH133OKGwekG838Om/cQT0BUHV3HcBgoo=
|
||||
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
|
||||
cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=
|
||||
cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
|
||||
cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=
|
||||
cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=
|
||||
cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To=
|
||||
cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4=
|
||||
cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M=
|
||||
cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc=
|
||||
cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk=
|
||||
cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=
|
||||
cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=
|
||||
cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=
|
||||
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
|
||||
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
|
||||
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
|
||||
cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
|
||||
cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
|
||||
cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
|
||||
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
|
||||
cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
|
||||
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
|
||||
cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
|
||||
cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
|
||||
cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU=
|
||||
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
|
||||
cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
|
||||
cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
|
||||
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
|
||||
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
|
||||
dmitri.shuralyov.com/app/changes v0.0.0-20180602232624-0a106ad413e3/go.mod h1:Yl+fi1br7+Rr3LqpNJf1/uxUdtRUV+Tnj0o93V2B9MU=
|
||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||
dmitri.shuralyov.com/html/belt v0.0.0-20180602232347-f7d459c86be0/go.mod h1:JLBrvjyP0v+ecvNYvCpyZgu5/xkfAUhi6wJj28eUfSU=
|
||||
dmitri.shuralyov.com/service/change v0.0.0-20181023043359-a85b471d5412/go.mod h1:a1inKt/atXimZ4Mv927x+r7UpyzRUf4emIoiiSC2TN4=
|
||||
dmitri.shuralyov.com/state v0.0.0-20180228185332-28bcc343414c/go.mod h1:0PRwlb0D6DFvNNtx+9ybjezNCa8XF0xaYcETyp6rHWU=
|
||||
git.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
|
||||
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
|
||||
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
|
||||
github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
|
||||
github.com/benbjohnson/clock v1.3.5 h1:VvXlSJBzZpA/zum6Sj74hxwYI2DIxRWuNIoXAzHZz5o=
|
||||
github.com/benbjohnson/clock v1.3.5/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
|
||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
||||
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||
github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g=
|
||||
github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
|
||||
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||
github.com/cilium/ebpf v0.2.0/go.mod h1:To2CFviqOWL/M0gIMsvSMlqe7em/l1ALkX1PyjrX2Qs=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||
github.com/containerd/cgroups v0.0.0-20201119153540-4cbc285b3327/go.mod h1:ZJeTFisyysqgcCdecO57Dj79RfL0LNeGiFUqLYQRYLE=
|
||||
github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaDFBM=
|
||||
github.com/containerd/cgroups v1.1.0/go.mod h1:6ppBcbh/NOOUU+dMKrykgaBnK9lCIBxHqJDGwsa1mIw=
|
||||
github.com/coreos/go-systemd v0.0.0-20181012123002-c6f51f82210d/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||
github.com/coreos/go-systemd/v22 v22.1.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk=
|
||||
github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs=
|
||||
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
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/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c h1:pFUpOrbxDR6AkioZ1ySsx5yxlDQZ8stG2b88gTPxgJU=
|
||||
github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c/go.mod h1:6UhI8N9EjYm1c2odKpFpAYeR8dsBeM7PtzQhRgxRr9U=
|
||||
github.com/decred/dcrd/crypto/blake256 v1.0.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5ilcvdfma9wOH6Y=
|
||||
github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo=
|
||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 h1:8UrgZ3GkP4i/CLijOJx79Yu+etlyjdBU4sfcs2WYQMs=
|
||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0=
|
||||
github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
||||
github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
|
||||
github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
||||
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||
github.com/elastic/gosigar v0.12.0/go.mod h1:iXRIGg2tLnu7LBdpqzyQfGDEidKCfWcCMS0WKyPWoMs=
|
||||
github.com/elastic/gosigar v0.14.2 h1:Dg80n8cr90OZ7x+bAax/QjoW/XqTI11RmA79ZwIm9/4=
|
||||
github.com/elastic/gosigar v0.14.2/go.mod h1:iXRIGg2tLnu7LBdpqzyQfGDEidKCfWcCMS0WKyPWoMs=
|
||||
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
|
||||
github.com/flynn/noise v1.0.0 h1:DlTHqmzmvcEiKj+4RYo/imoswx/4r6iBlCMfVtrMXpQ=
|
||||
github.com/flynn/noise v1.0.0/go.mod h1:xbMo+0i6+IGbYdJhF31t2eR1BIU0CYc12+BNAKwUTag=
|
||||
github.com/francoispqt/gojay v1.2.13 h1:d2m3sFjloqoIUQU3TsHBgj6qg/BVGlTBeHDUmyJnXKk=
|
||||
github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0=
|
||||
github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q=
|
||||
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY=
|
||||
github.com/go-kit/log v0.2.0/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0=
|
||||
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
||||
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
||||
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
|
||||
github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=
|
||||
github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ=
|
||||
github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
|
||||
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls=
|
||||
github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk=
|
||||
github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
|
||||
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E=
|
||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
|
||||
github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
||||
github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
||||
github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
||||
github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
||||
github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
||||
github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
|
||||
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.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
|
||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
|
||||
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
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/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ=
|
||||
github.com/google/go-github/v57 v57.0.0 h1:L+Y3UPTY8ALM8x+TV0lg+IEBI+upibemtBD8Q9u7zHs=
|
||||
github.com/google/go-github/v57 v57.0.0/go.mod h1:s0omdnye0hvK/ecLvpsGfJMiRt85PimQh4oygmLIxHw=
|
||||
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
|
||||
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
|
||||
github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8=
|
||||
github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo=
|
||||
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
||||
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
|
||||
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||
github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20231023181126-ff6d637d2a7b h1:RMpPgZTSApbPf7xaVel+QkoGPRLFLrwFO89uDUHEGf0=
|
||||
github.com/google/pprof v0.0.0-20231023181126-ff6d637d2a7b/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik=
|
||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||
github.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY=
|
||||
github.com/googleapis/gax-go/v2 v2.0.3/go.mod h1:LLvjysVCY1JZeum8Z6l8qUty8fiNwE08qbEPm1M08qg=
|
||||
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
||||
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
|
||||
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.5.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw=
|
||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/golang-lru/v2 v2.0.5 h1:wW7h1TG88eUIJ2i69gaE3uNVtEPIagzhGvHgwfx2Vm4=
|
||||
github.com/hashicorp/golang-lru/v2 v2.0.5/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM=
|
||||
github.com/huin/goupnp v1.3.0 h1:UvLUlWDNpoUdYzb2TCn+MuTWtcjXKSza2n6CBdQ0xXc=
|
||||
github.com/huin/goupnp v1.3.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/ipfs/go-cid v0.4.1 h1:A/T3qGvxi4kpKWWcPC/PgbvDA2bjVLO7n4UeVwnbs/s=
|
||||
github.com/ipfs/go-cid v0.4.1/go.mod h1:uQHwDeX4c6CtyrFwdqyhpNcxVewur1M7l7fNU7LKwZk=
|
||||
github.com/ipfs/go-detect-race v0.0.1 h1:qX/xay2W3E4Q1U7d9lNs1sU9nvguX0a7319XbyQ6cOk=
|
||||
github.com/ipfs/go-detect-race v0.0.1/go.mod h1:8BNT7shDZPo99Q74BpGMK+4D8Mn4j46UU0LZ723meps=
|
||||
github.com/ipfs/go-log/v2 v2.5.1 h1:1XdUzF7048prq4aBjDQQ4SL5RxftpRGdXhNRwKSAlcY=
|
||||
github.com/ipfs/go-log/v2 v2.5.1/go.mod h1:prSpmC1Gpllc9UYWxDiZDreBYw7zp4Iqp1kOLU9U5UI=
|
||||
github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus=
|
||||
github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc=
|
||||
github.com/jbenet/go-temp-err-catcher v0.1.0 h1:zpb3ZH6wIE8Shj2sKS+khgRvf7T7RABoLk/+KKHggpk=
|
||||
github.com/jbenet/go-temp-err-catcher v0.1.0/go.mod h1:0kJRvmDZXNMIiJirNPEYfhpPwbGVtZVWC34vc5WLsDk=
|
||||
github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0B/fFc00Y+Rasa88328GlI/XbtyysCtTHZS8h7IrBU=
|
||||
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
|
||||
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
||||
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
||||
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
|
||||
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
||||
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
|
||||
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
|
||||
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/klauspost/compress v1.17.2 h1:RlWWUY/Dr4fL8qk9YG7DTZ7PDgME2V4csBXA8L/ixi4=
|
||||
github.com/klauspost/compress v1.17.2/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
|
||||
github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg=
|
||||
github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/koron/go-ssdp v0.0.4 h1:1IDwrghSKYM7yLf7XCzbByg2sJ/JcNOZRXS2jczTwz0=
|
||||
github.com/koron/go-ssdp v0.0.4/go.mod h1:oDXq+E5IL5q0U8uSBcoAXzTzInwy5lEgC91HoKtbmZk=
|
||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI=
|
||||
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/pty v1.1.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6cdF0Y8=
|
||||
github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QTWy5HSiZacSbPg=
|
||||
github.com/libp2p/go-cidranger v1.1.0 h1:ewPN8EZ0dd1LSnrtuwd4709PXVcITVeuwbag38yPW7c=
|
||||
github.com/libp2p/go-cidranger v1.1.0/go.mod h1:KWZTfSr+r9qEo9OkI9/SIEeAtw+NNoU0dXIXt15Okic=
|
||||
github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM=
|
||||
github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro=
|
||||
github.com/libp2p/go-libp2p v0.32.0 h1:86I4B7nBUPIyTgw3+5Ibq6K7DdKRCuZw8URCfPc1hQM=
|
||||
github.com/libp2p/go-libp2p v0.32.0/go.mod h1:hXXC3kXPlBZ1eu8Q2hptGrMB4mZ3048JUoS4EKaHW5c=
|
||||
github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s=
|
||||
github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w=
|
||||
github.com/libp2p/go-libp2p-pubsub v0.10.0 h1:wS0S5FlISavMaAbxyQn3dxMOe2eegMfswM471RuHJwA=
|
||||
github.com/libp2p/go-libp2p-pubsub v0.10.0/go.mod h1:1OxbaT/pFRO5h+Dpze8hdHQ63R0ke55XTs6b6NwLLkw=
|
||||
github.com/libp2p/go-libp2p-testing v0.12.0 h1:EPvBb4kKMWO29qP4mZGyhVzUyR25dvfUIK5WDu6iPUA=
|
||||
github.com/libp2p/go-libp2p-testing v0.12.0/go.mod h1:KcGDRXyN7sQCllucn1cOOS+Dmm7ujhfEyXQL5lvkcPg=
|
||||
github.com/libp2p/go-msgio v0.3.0 h1:mf3Z8B1xcFN314sWX+2vOTShIE0Mmn2TXn3YCUQGNj0=
|
||||
github.com/libp2p/go-msgio v0.3.0/go.mod h1:nyRM819GmVaF9LX3l03RMh10QdOroF++NBbxAb0mmDM=
|
||||
github.com/libp2p/go-nat v0.2.0 h1:Tyz+bUFAYqGyJ/ppPPymMGbIgNRH+WqC5QrT5fKrrGk=
|
||||
github.com/libp2p/go-nat v0.2.0/go.mod h1:3MJr+GRpRkyT65EpVPBstXLvOlAPzUVlG6Pwg9ohLJk=
|
||||
github.com/libp2p/go-netroute v0.2.1 h1:V8kVrpD8GK0Riv15/7VN6RbUQ3URNZVosw7H2v9tksU=
|
||||
github.com/libp2p/go-netroute v0.2.1/go.mod h1:hraioZr0fhBjG0ZRXJJ6Zj2IVEVNx6tDTFQfSmcq7mQ=
|
||||
github.com/libp2p/go-reuseport v0.4.0 h1:nR5KU7hD0WxXCJbmw7r2rhRYruNRl2koHw8fQscQm2s=
|
||||
github.com/libp2p/go-reuseport v0.4.0/go.mod h1:ZtI03j/wO5hZVDFo2jKywN6bYKWLOy8Se6DrI2E1cLU=
|
||||
github.com/libp2p/go-yamux/v4 v4.0.1 h1:FfDR4S1wj6Bw2Pqbc8Uz7pCxeRBPbwsBbEdfwiCypkQ=
|
||||
github.com/libp2p/go-yamux/v4 v4.0.1/go.mod h1:NWjl8ZTLOGlozrXSOZ/HlfG++39iKNnM5wwmtQP1YB4=
|
||||
github.com/libp2p/zeroconf/v2 v2.2.0 h1:Cup06Jv6u81HLhIj1KasuNM/RHHrJ8T7wOTS4+Tv53Q=
|
||||
github.com/libp2p/zeroconf/v2 v2.2.0/go.mod h1:fuJqLnUwZTshS3U/bMRJ3+ow/v9oid1n0DmyYyNO1Xs=
|
||||
github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI=
|
||||
github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd h1:br0buuQ854V8u83wA0rVZ8ttrq5CpaPZdvrK0LP2lOk=
|
||||
github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd/go.mod h1:QuCEs1Nt24+FYQEqAAncTDPJIuGs+LxK1MCiFL25pMU=
|
||||
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
|
||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
|
||||
github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4=
|
||||
github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI=
|
||||
github.com/miekg/dns v1.1.43/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4=
|
||||
github.com/miekg/dns v1.1.56 h1:5imZaSeoRNvpM9SzWNhEcP9QliKiz20/dA2QabIGVnE=
|
||||
github.com/miekg/dns v1.1.56/go.mod h1:cRm6Oo2C8TY9ZS/TqsSrseAcncm74lfK5G+ikN2SWWY=
|
||||
github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c h1:bzE/A84HN25pxAuk9Eej1Kz9OUelF97nAc82bDquQI8=
|
||||
github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c/go.mod h1:0SQS9kMwD2VsyFEB++InYyBJroV/FRmBgcydeSUcJms=
|
||||
github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b h1:z78hV3sbSMAUoyUMM0I83AUIT6Hu17AWfgjzIbtrYFc=
|
||||
github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b/go.mod h1:lxPUiZwKoFL8DUUmalo2yJJUCxbPKtm8OKfqr2/FTNU=
|
||||
github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc h1:PTfri+PuQmWDqERdnNMiD9ZejrlswWrCpBEZgWOiTrc=
|
||||
github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc/go.mod h1:cGKTAVKx4SxOuR/czcZ/E2RSJ3sfHs8FpHhQ5CWMf9s=
|
||||
github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ=
|
||||
github.com/minio/sha256-simd v0.1.1-0.20190913151208-6de447530771/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM=
|
||||
github.com/minio/sha256-simd v1.0.1 h1:6kaan5IFmwTNynnKKpDHe6FWHohJOHhCPchzK49dzMM=
|
||||
github.com/minio/sha256-simd v1.0.1/go.mod h1:Pz6AKMiUdngCLpeTL/RJY1M9rUuPMYujV5xJjtbRSN8=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||
github.com/mr-tron/base58 v1.1.2/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc=
|
||||
github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o=
|
||||
github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc=
|
||||
github.com/multiformats/go-base32 v0.1.0 h1:pVx9xoSPqEIQG8o+UbAe7DNi51oej1NtK+aGkbLYxPE=
|
||||
github.com/multiformats/go-base32 v0.1.0/go.mod h1:Kj3tFY6zNr+ABYMqeUNeGvkIC/UYgtWibDcT0rExnbI=
|
||||
github.com/multiformats/go-base36 v0.2.0 h1:lFsAbNOGeKtuKozrtBsAkSVhv1p9D0/qedU9rQyccr0=
|
||||
github.com/multiformats/go-base36 v0.2.0/go.mod h1:qvnKE++v+2MWCfePClUEjE78Z7P2a1UV0xHgWc0hkp4=
|
||||
github.com/multiformats/go-multiaddr v0.1.1/go.mod h1:aMKBKNEYmzmDmxfX88/vz+J5IU55txyt0p4aiWVohjo=
|
||||
github.com/multiformats/go-multiaddr v0.2.0/go.mod h1:0nO36NvPpyV4QzvTLi/lafl2y95ncPj0vFwVF6k6wJ4=
|
||||
github.com/multiformats/go-multiaddr v0.12.0 h1:1QlibTFkoXJuDjjYsMHhE73TnzJQl8FSWatk/0gxGzE=
|
||||
github.com/multiformats/go-multiaddr v0.12.0/go.mod h1:WmZXgObOQOYp9r3cslLlppkrz1FYSHmE834dfz/lWu8=
|
||||
github.com/multiformats/go-multiaddr-dns v0.3.1 h1:QgQgR+LQVt3NPTjbrLLpsaT2ufAA2y0Mkk+QRVJbW3A=
|
||||
github.com/multiformats/go-multiaddr-dns v0.3.1/go.mod h1:G/245BRQ6FJGmryJCrOuTdB37AMA5AMOVuO6NY3JwTk=
|
||||
github.com/multiformats/go-multiaddr-fmt v0.1.0 h1:WLEFClPycPkp4fnIzoFoV9FVd49/eQsuaL3/CWe167E=
|
||||
github.com/multiformats/go-multiaddr-fmt v0.1.0/go.mod h1:hGtDIW4PU4BqJ50gW2quDuPVjyWNZxToGUh/HwTZYJo=
|
||||
github.com/multiformats/go-multibase v0.2.0 h1:isdYCVLvksgWlMW9OZRYJEa9pZETFivncJHmHnnd87g=
|
||||
github.com/multiformats/go-multibase v0.2.0/go.mod h1:bFBZX4lKCA/2lyOFSAoKH5SS6oPyjtnzK/XTFDPkNuk=
|
||||
github.com/multiformats/go-multicodec v0.9.0 h1:pb/dlPnzee/Sxv/j4PmkDRxCOi3hXTz3IbPKOXWJkmg=
|
||||
github.com/multiformats/go-multicodec v0.9.0/go.mod h1:L3QTQvMIaVBkXOXXtVmYE+LI16i14xuaojr/H7Ai54k=
|
||||
github.com/multiformats/go-multihash v0.0.8/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpKa63epEDmG8nTduyAew=
|
||||
github.com/multiformats/go-multihash v0.2.3 h1:7Lyc8XfX/IY2jWb/gI7JP+o7JEq9hOa7BFvVU9RSh+U=
|
||||
github.com/multiformats/go-multihash v0.2.3/go.mod h1:dXgKXCXjBzdscBLk9JkjINiEsCKRVch90MdaGiKsvSM=
|
||||
github.com/multiformats/go-multistream v0.5.0 h1:5htLSLl7lvJk3xx3qT/8Zm9J4K8vEOf/QGkvOGQAyiE=
|
||||
github.com/multiformats/go-multistream v0.5.0/go.mod h1:n6tMZiwiP2wUsR8DgfDWw1dydlEqV3l6N3/GBsX6ILA=
|
||||
github.com/multiformats/go-varint v0.0.1/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE=
|
||||
github.com/multiformats/go-varint v0.0.7 h1:sWSGR+f/eu5ABZA2ZpYKBILXTTs9JWpdEM/nEGOHFS8=
|
||||
github.com/multiformats/go-varint v0.0.7/go.mod h1:r8PUYw/fD/SjBCiKOoDlGF6QawOELpZAu9eioSos/OU=
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo=
|
||||
github.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM=
|
||||
github.com/onsi/ginkgo/v2 v2.13.0 h1:0jY9lJquiL8fcf3M4LAXN5aMlS/b2BV86HFFPCPMgE4=
|
||||
github.com/onsi/ginkgo/v2 v2.13.0/go.mod h1:TE309ZR8s5FsKKpuB1YAQYBzCaAfUgatB/xlT/ETL/o=
|
||||
github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI=
|
||||
github.com/onsi/gomega v1.27.10/go.mod h1:RsS8tutOdbdgzbPtzzATp12yT7kM5I5aElG3evPbQ0M=
|
||||
github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
|
||||
github.com/opencontainers/runtime-spec v1.1.0 h1:HHUyrt9mwHUjtasSbXSMvs4cyFxh+Bll4AjJ9odEGpg=
|
||||
github.com/opencontainers/runtime-spec v1.1.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
|
||||
github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8=
|
||||
github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 h1:onHthvaw9LFnH4t2DcNVpwGmV9E1BkGknEliJkfwQj0=
|
||||
github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58/go.mod h1:DXv8WO4yhMYhSNPKjeNKa5WY9YCIEBRbNzFFPJbWO6Y=
|
||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
|
||||
github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
|
||||
github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0=
|
||||
github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY=
|
||||
github.com/prometheus/client_golang v1.14.0 h1:nJdhIvne2eSX/XRAFV9PcvFFRbrjbcTUj0VP62TMhnw=
|
||||
github.com/prometheus/client_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y=
|
||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/client_model v0.4.0 h1:5lQXD3cAg1OXBf4Wq03gTrXHeaV0TQvGfUooCfx1yqY=
|
||||
github.com/prometheus/client_model v0.4.0/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJEYF2imWWhWtMkYU=
|
||||
github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
|
||||
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||
github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
|
||||
github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc=
|
||||
github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls=
|
||||
github.com/prometheus/common v0.37.0 h1:ccBbHCgIiT9uSoFY0vX8H3zsNR5eLt17/RQLUvn8pXE=
|
||||
github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA=
|
||||
github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||
github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
|
||||
github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
|
||||
github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
|
||||
github.com/prometheus/procfs v0.8.0 h1:ODq8ZFEaYeCaZOJlZZdJA2AbQR98dSHSM1KW/You5mo=
|
||||
github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4=
|
||||
github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo=
|
||||
github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A=
|
||||
github.com/quic-go/qtls-go1-20 v0.3.4 h1:MfFAPULvst4yoMgY9QmtpYmfij/em7O8UUi+bNVm7Cg=
|
||||
github.com/quic-go/qtls-go1-20 v0.3.4/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k=
|
||||
github.com/quic-go/quic-go v0.39.3 h1:o3YB6t2SR+HU/pgwF29kJ6g4jJIJEwEZ8CKia1h1TKg=
|
||||
github.com/quic-go/quic-go v0.39.3/go.mod h1:T09QsDQWjLiQ74ZmacDfqZmhY/NLnw5BC40MANNNZ1Q=
|
||||
github.com/quic-go/webtransport-go v0.6.0 h1:CvNsKqc4W2HljHJnoT+rMmbRJybShZ0YPFDD3NxaZLY=
|
||||
github.com/quic-go/webtransport-go v0.6.0/go.mod h1:9KjU4AEBqEQidGHNDkZrb8CAa1abRaosM2yGOyiikEc=
|
||||
github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk=
|
||||
github.com/raulk/go-watchdog v1.3.0/go.mod h1:fIvOnLbF0b0ZwkB9YU4mOW9Did//4vPZtDqv66NfsMU=
|
||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
|
||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
|
||||
github.com/shurcooL/component v0.0.0-20170202220835-f88ec8f54cc4/go.mod h1:XhFIlyj5a1fBNx5aJTbKoIq0mNaPvOagO+HjB3EtxrY=
|
||||
github.com/shurcooL/events v0.0.0-20181021180414-410e4ca65f48/go.mod h1:5u70Mqkb5O5cxEA8nxTsgrgLehJeAw6Oc4Ab1c/P1HM=
|
||||
github.com/shurcooL/github_flavored_markdown v0.0.0-20181002035957-2122de532470/go.mod h1:2dOwnU2uBioM+SGy2aZoq1f/Sd1l9OkAeAUvjSyvgU0=
|
||||
github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk=
|
||||
github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ=
|
||||
github.com/shurcooL/gofontwoff v0.0.0-20180329035133-29b52fc0a18d/go.mod h1:05UtEgK5zq39gLST6uB0cf3NEHjETfB4Fgr3Gx5R9Vw=
|
||||
github.com/shurcooL/gopherjslib v0.0.0-20160914041154-feb6d3990c2c/go.mod h1:8d3azKNyqcHP1GaQE/c6dDgjkgSx2BZ4IoEi4F1reUI=
|
||||
github.com/shurcooL/highlight_diff v0.0.0-20170515013008-09bb4053de1b/go.mod h1:ZpfEhSmds4ytuByIcDnOLkTHGUI6KNqRNPDLHDk+mUU=
|
||||
github.com/shurcooL/highlight_go v0.0.0-20181028180052-98c3abbbae20/go.mod h1:UDKB5a1T23gOMUJrI+uSuH0VRDStOiUVSjBTRDVBVag=
|
||||
github.com/shurcooL/home v0.0.0-20181020052607-80b7ffcb30f9/go.mod h1:+rgNQw2P9ARFAs37qieuu7ohDNQ3gds9msbT2yn85sg=
|
||||
github.com/shurcooL/htmlg v0.0.0-20170918183704-d01228ac9e50/go.mod h1:zPn1wHpTIePGnXSHpsVPWEktKXHr6+SS6x/IKRb7cpw=
|
||||
github.com/shurcooL/httperror v0.0.0-20170206035902-86b7830d14cc/go.mod h1:aYMfkZ6DWSJPJ6c4Wwz3QtW22G7mf/PEgaB9k/ik5+Y=
|
||||
github.com/shurcooL/httpfs v0.0.0-20171119174359-809beceb2371/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg=
|
||||
github.com/shurcooL/httpgzip v0.0.0-20180522190206-b1c53ac65af9/go.mod h1:919LwcH0M7/W4fcZ0/jy0qGght1GIhqyS/EgWGH2j5Q=
|
||||
github.com/shurcooL/issues v0.0.0-20181008053335-6292fdc1e191/go.mod h1:e2qWDig5bLteJ4fwvDAc2NHzqFEthkqn7aOZAOpj+PQ=
|
||||
github.com/shurcooL/issuesapp v0.0.0-20180602232740-048589ce2241/go.mod h1:NPpHK2TI7iSaM0buivtFUc9offApnI0Alt/K8hcHy0I=
|
||||
github.com/shurcooL/notifications v0.0.0-20181007000457-627ab5aea122/go.mod h1:b5uSkrEVM1jQUspwbixRBhaIjIzL2xazXp6kntxYle0=
|
||||
github.com/shurcooL/octicon v0.0.0-20181028054416-fa4f57f9efb2/go.mod h1:eWdoE5JD4R5UVWDucdOPg1g2fqQRq78IQa9zlOV1vpQ=
|
||||
github.com/shurcooL/reactions v0.0.0-20181006231557-f2e0b4ca5b82/go.mod h1:TCR1lToEk4d2s07G3XGfz2QrgHXg4RJBvjrOozvoWfk=
|
||||
github.com/shurcooL/sanitized_anchor_name v0.0.0-20170918181015-86672fcb3f95/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||
github.com/shurcooL/users v0.0.0-20180125191416-49c67e49c537/go.mod h1:QJTqeLYEDaXHZDBsXlPCDqdhQuJkuw4NOtaxYe3xii4=
|
||||
github.com/shurcooL/webdavfs v0.0.0-20170829043945-18c3829fa133/go.mod h1:hKmq5kWdCj2z2KEozexVbfEZIWiTjhE0+UjmZgPqehw=
|
||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
|
||||
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||
github.com/sourcegraph/annotate v0.0.0-20160123013949-f4cad6c6324d/go.mod h1:UdhH50NIW0fCiwBSr0co2m7BnFLdv4fQTgdqdJTHFeE=
|
||||
github.com/sourcegraph/syntaxhighlight v0.0.0-20170531221838-bd320f5d308e/go.mod h1:HuIsMU8RRBOtsCgI77wP899iHVBQpCmg4ErYMZB+2IA=
|
||||
github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI=
|
||||
github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA=
|
||||
github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
||||
github.com/viant/assertly v0.4.8/go.mod h1:aGifi++jvCrUaklKEKT0BU95igDNaqkvz+49uaYMPRU=
|
||||
github.com/viant/toolbox v0.24.0/go.mod h1:OxMCG57V0PXuIP2HNQrtJf2CjqdmbrOx5EkMILuUhzM=
|
||||
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
go.opencensus.io v0.18.0/go.mod h1:vKdFvxhtzZ9onBp9VKHK8z/sRpBMnKAsufL7wlDrCOA=
|
||||
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
||||
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
|
||||
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
||||
go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE=
|
||||
go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
|
||||
go.uber.org/dig v1.17.1 h1:Tga8Lz8PcYNsWsyHMZ1Vm0OQOUaJNDyvPImgbAu9YSc=
|
||||
go.uber.org/dig v1.17.1/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE=
|
||||
go.uber.org/fx v1.20.1 h1:zVwVQGS8zYvhh9Xxcu4w1M6ESyeMzebzj2NbSayZ4Mk=
|
||||
go.uber.org/fx v1.20.1/go.mod h1:iSYNbHf2y55acNCwCXKx7LbWb5WG1Bnue5RDXz1OREg=
|
||||
go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
|
||||
go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk=
|
||||
go.uber.org/goleak v1.2.0/go.mod h1:XJYK+MuIchqpmGmUSAzotztawfKvYLUIgg7guXrwVUo=
|
||||
go.uber.org/mock v0.3.0 h1:3mUxI1No2/60yUYax92Pt8eNOEecx2D3lcXZh2NEZJo=
|
||||
go.uber.org/mock v0.3.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc=
|
||||
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
|
||||
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
|
||||
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
|
||||
go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI=
|
||||
go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo=
|
||||
go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so=
|
||||
go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE=
|
||||
golang.org/x/build v0.0.0-20190111050920-041ab4dc3f9d/go.mod h1:OWs+y06UdEOHN4y+MfF/py+xQ/tYqIWW03b70/CG9Rw=
|
||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200602180216-279210d13fed/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
||||
golang.org/x/crypto v0.16.0 h1:mMMrFzRSCF0GvB7Ne27XVtVAaXLrPmgPC7/v0tkwHaY=
|
||||
golang.org/x/crypto v0.16.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||
golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=
|
||||
golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=
|
||||
golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
||||
golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
||||
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
||||
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
|
||||
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
|
||||
golang.org/x/exp v0.0.0-20231006140011-7918f672742d h1:jtJma62tbqLibJ5sFQz8bKtEM8rJBtfilJ2qTU199MI=
|
||||
golang.org/x/exp v0.0.0-20231006140011-7918f672742d/go.mod h1:ldy0pHrwJyGW56pPQzzkH36rKxoZW1tw7ZJpeKx+hdo=
|
||||
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
||||
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
|
||||
golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
|
||||
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
|
||||
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
|
||||
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
|
||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.13.0 h1:I/DsJXRlw/8l/0c24sM9yb0T4z9liZTduXvdAWYiysY=
|
||||
golang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181029044818-c44066c5c816/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181106065722-10aee1819953/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190313220215-9f648a60d977/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||
golang.org/x/net v0.0.0-20210423184538-5f58ad60dda6/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
|
||||
golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
||||
golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
||||
golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c=
|
||||
golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
|
||||
golang.org/x/oauth2 v0.15.0 h1:s8pnnxNVzjWyrvYdFUQq5llS1PX2zhPXmccZv99h7uQ=
|
||||
golang.org/x/oauth2 v0.15.0/go.mod h1:q48ptWNTY5XWf+JNten23lcvHpLJ0ZSxF5ttTHKVCAM=
|
||||
golang.org/x/perf v0.0.0-20180704124530-6e6d33e29852/go.mod h1:JLpeXjPJfIyPr5TlbXLkXWLhP8nz10XfvxElABhCtcw=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.4.0 h1:zxkM55ReGkDlKSM+Fu41A+zmbZuaPVbGMzvvdUPznYQ=
|
||||
golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
|
||||
golang.org/x/sys v0.0.0-20180810173357-98c5dad5d1a0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181029174526-d69651ed3497/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190316082340-a2f829d7f35f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210426080607-c94f62235c83/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc=
|
||||
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
|
||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20181030000716-a0a13e073c7b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
|
||||
golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
|
||||
golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
|
||||
golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.14.0 h1:jvNa2pY0M4r62jkRQ6RwEZZyPcymeL9XZMLBbV7U2nc=
|
||||
golang.org/x/tools v0.14.0/go.mod h1:uYBEerGOWcJyEORxN+Ek8+TT266gXkNlHdJBwexUsBg=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
|
||||
google.golang.org/api v0.0.0-20181030000543-1d582fd0359e/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
|
||||
google.golang.org/api v0.1.0/go.mod h1:UGEZY7KEX120AnNLIHFMKIo4obdJhkp2tPbaPlQx13Y=
|
||||
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
|
||||
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
|
||||
google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
|
||||
google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
|
||||
google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
||||
google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
||||
google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
||||
google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
|
||||
google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
|
||||
google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=
|
||||
google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
|
||||
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
|
||||
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20181029155118-b69ba1387ce2/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20181202183823-bd91e49a0898/go.mod h1:7Ep/1NZk928CDR8SjdVbjWNpdIf6nzjE3BTgJDr2Atg=
|
||||
google.golang.org/genproto v0.0.0-20190306203927-b5d61aea6440/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||
google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
|
||||
google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA=
|
||||
google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U=
|
||||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
||||
google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=
|
||||
google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
|
||||
google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio=
|
||||
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
||||
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
||||
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
||||
google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=
|
||||
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
|
||||
google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
||||
google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
||||
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.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
|
||||
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
|
||||
google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
|
||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
grpc.go4.org v0.0.0-20170609214715-11d0a25b4919/go.mod h1:77eQGdRu53HpSqPFJFmuJdjuHRquDANNeA4x7B8WQ9o=
|
||||
honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
||||
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||
lukechampine.com/blake3 v1.2.1 h1:YuqqRuaqsGV71BV/nm9xlI0MKUv4QC54jQnBChWbGnI=
|
||||
lukechampine.com/blake3 v1.2.1/go.mod h1:0OFRp7fBtAylGVCO40o87sbupkyIGgbpv1+M1k1LM6k=
|
||||
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
|
||||
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
|
||||
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
|
||||
sourcegraph.com/sourcegraph/go-diff v0.5.0/go.mod h1:kuch7UrkMzY0X+p9CRK03kfuPQ2zzQcaEFbx8wA8rck=
|
||||
sourcegraph.com/sqs/pbtypes v0.0.0-20180604144634-d3ebe8f20ae4/go.mod h1:ketZ/q3QxT9HOBeFhu6RdvsftgpsbFHBF5Cas6cDKZ0=
|
||||
313
logging/hypercore.go
Normal file
313
logging/hypercore.go
Normal file
@@ -0,0 +1,313 @@
|
||||
package logging
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/libp2p/go-libp2p/core/peer"
|
||||
)
|
||||
|
||||
// HypercoreLog represents a simplified Hypercore-inspired distributed log
|
||||
type HypercoreLog struct {
|
||||
entries []LogEntry
|
||||
mutex sync.RWMutex
|
||||
peerID peer.ID
|
||||
|
||||
// Verification chain
|
||||
headHash string
|
||||
|
||||
// Replication
|
||||
replicators map[peer.ID]*Replicator
|
||||
}
|
||||
|
||||
// LogEntry represents a single entry in the distributed log
|
||||
type LogEntry struct {
|
||||
Index uint64 `json:"index"`
|
||||
Timestamp time.Time `json:"timestamp"`
|
||||
Author string `json:"author"` // Peer ID of the author
|
||||
Type LogType `json:"type"` // Type of log entry
|
||||
Data map[string]interface{} `json:"data"` // Log data
|
||||
Hash string `json:"hash"` // Hash of this entry
|
||||
PrevHash string `json:"prev_hash"` // Hash of previous entry
|
||||
Signature string `json:"signature"` // Digital signature (simplified)
|
||||
}
|
||||
|
||||
// LogType represents different types of log entries
|
||||
type LogType string
|
||||
|
||||
const (
|
||||
// Bzzz coordination logs
|
||||
TaskAnnounced LogType = "task_announced"
|
||||
TaskClaimed LogType = "task_claimed"
|
||||
TaskProgress LogType = "task_progress"
|
||||
TaskCompleted LogType = "task_completed"
|
||||
TaskFailed LogType = "task_failed"
|
||||
|
||||
// Antennae meta-discussion logs
|
||||
PlanProposed LogType = "plan_proposed"
|
||||
ObjectionRaised LogType = "objection_raised"
|
||||
Collaboration LogType = "collaboration"
|
||||
ConsensusReached LogType = "consensus_reached"
|
||||
Escalation LogType = "escalation"
|
||||
|
||||
// System logs
|
||||
PeerJoined LogType = "peer_joined"
|
||||
PeerLeft LogType = "peer_left"
|
||||
CapabilityBcast LogType = "capability_broadcast"
|
||||
NetworkEvent LogType = "network_event"
|
||||
)
|
||||
|
||||
// Replicator handles log replication with other peers
|
||||
type Replicator struct {
|
||||
peerID peer.ID
|
||||
lastSyncIndex uint64
|
||||
connected bool
|
||||
}
|
||||
|
||||
// NewHypercoreLog creates a new distributed log for a peer
|
||||
func NewHypercoreLog(peerID peer.ID) *HypercoreLog {
|
||||
return &HypercoreLog{
|
||||
entries: make([]LogEntry, 0),
|
||||
peerID: peerID,
|
||||
headHash: "",
|
||||
replicators: make(map[peer.ID]*Replicator),
|
||||
}
|
||||
}
|
||||
|
||||
// Append adds a new entry to the log
|
||||
func (h *HypercoreLog) Append(logType LogType, data map[string]interface{}) (*LogEntry, error) {
|
||||
h.mutex.Lock()
|
||||
defer h.mutex.Unlock()
|
||||
|
||||
index := uint64(len(h.entries))
|
||||
|
||||
entry := LogEntry{
|
||||
Index: index,
|
||||
Timestamp: time.Now(),
|
||||
Author: h.peerID.String(),
|
||||
Type: logType,
|
||||
Data: data,
|
||||
PrevHash: h.headHash,
|
||||
}
|
||||
|
||||
// Calculate hash
|
||||
entryHash, err := h.calculateEntryHash(entry)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to calculate entry hash: %w", err)
|
||||
}
|
||||
entry.Hash = entryHash
|
||||
|
||||
// Add simple signature (in production, use proper cryptographic signatures)
|
||||
entry.Signature = h.createSignature(entry)
|
||||
|
||||
// Append to log
|
||||
h.entries = append(h.entries, entry)
|
||||
h.headHash = entryHash
|
||||
|
||||
fmt.Printf("📝 Log entry appended: %s [%d] by %s\n",
|
||||
logType, index, h.peerID.ShortString())
|
||||
|
||||
// Trigger replication to connected peers
|
||||
go h.replicateEntry(entry)
|
||||
|
||||
return &entry, nil
|
||||
}
|
||||
|
||||
// Get retrieves a log entry by index
|
||||
func (h *HypercoreLog) Get(index uint64) (*LogEntry, error) {
|
||||
h.mutex.RLock()
|
||||
defer h.mutex.RUnlock()
|
||||
|
||||
if index >= uint64(len(h.entries)) {
|
||||
return nil, fmt.Errorf("entry %d not found", index)
|
||||
}
|
||||
|
||||
return &h.entries[index], nil
|
||||
}
|
||||
|
||||
// Length returns the number of entries in the log
|
||||
func (h *HypercoreLog) Length() uint64 {
|
||||
h.mutex.RLock()
|
||||
defer h.mutex.RUnlock()
|
||||
|
||||
return uint64(len(h.entries))
|
||||
}
|
||||
|
||||
// GetRange retrieves a range of log entries
|
||||
func (h *HypercoreLog) GetRange(start, end uint64) ([]LogEntry, error) {
|
||||
h.mutex.RLock()
|
||||
defer h.mutex.RUnlock()
|
||||
|
||||
if start >= uint64(len(h.entries)) {
|
||||
return nil, fmt.Errorf("start index %d out of range", start)
|
||||
}
|
||||
|
||||
if end > uint64(len(h.entries)) {
|
||||
end = uint64(len(h.entries))
|
||||
}
|
||||
|
||||
if start > end {
|
||||
return nil, fmt.Errorf("invalid range: start %d > end %d", start, end)
|
||||
}
|
||||
|
||||
result := make([]LogEntry, end-start)
|
||||
copy(result, h.entries[start:end])
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// GetEntriesByType retrieves all entries of a specific type
|
||||
func (h *HypercoreLog) GetEntriesByType(logType LogType) ([]LogEntry, error) {
|
||||
h.mutex.RLock()
|
||||
defer h.mutex.RUnlock()
|
||||
|
||||
var result []LogEntry
|
||||
for _, entry := range h.entries {
|
||||
if entry.Type == logType {
|
||||
result = append(result, entry)
|
||||
}
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// GetEntriesByAuthor retrieves all entries by a specific author
|
||||
func (h *HypercoreLog) GetEntriesByAuthor(author string) ([]LogEntry, error) {
|
||||
h.mutex.RLock()
|
||||
defer h.mutex.RUnlock()
|
||||
|
||||
var result []LogEntry
|
||||
for _, entry := range h.entries {
|
||||
if entry.Author == author {
|
||||
result = append(result, entry)
|
||||
}
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// VerifyIntegrity verifies the integrity of the log chain
|
||||
func (h *HypercoreLog) VerifyIntegrity() error {
|
||||
h.mutex.RLock()
|
||||
defer h.mutex.RUnlock()
|
||||
|
||||
var prevHash string
|
||||
for i, entry := range h.entries {
|
||||
// Verify previous hash link
|
||||
if entry.PrevHash != prevHash {
|
||||
return fmt.Errorf("integrity error at entry %d: prev_hash mismatch", i)
|
||||
}
|
||||
|
||||
// Verify entry hash
|
||||
calculatedHash, err := h.calculateEntryHash(entry)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to calculate hash for entry %d: %w", i, err)
|
||||
}
|
||||
|
||||
if entry.Hash != calculatedHash {
|
||||
return fmt.Errorf("integrity error at entry %d: hash mismatch", i)
|
||||
}
|
||||
|
||||
prevHash = entry.Hash
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// AddReplicator adds a peer for log replication
|
||||
func (h *HypercoreLog) AddReplicator(peerID peer.ID) {
|
||||
h.mutex.Lock()
|
||||
defer h.mutex.Unlock()
|
||||
|
||||
h.replicators[peerID] = &Replicator{
|
||||
peerID: peerID,
|
||||
lastSyncIndex: 0,
|
||||
connected: true,
|
||||
}
|
||||
|
||||
fmt.Printf("🔄 Added replicator: %s\n", peerID.ShortString())
|
||||
}
|
||||
|
||||
// RemoveReplicator removes a peer from replication
|
||||
func (h *HypercoreLog) RemoveReplicator(peerID peer.ID) {
|
||||
h.mutex.Lock()
|
||||
defer h.mutex.Unlock()
|
||||
|
||||
delete(h.replicators, peerID)
|
||||
fmt.Printf("🔄 Removed replicator: %s\n", peerID.ShortString())
|
||||
}
|
||||
|
||||
// replicateEntry sends a new entry to all connected replicators
|
||||
func (h *HypercoreLog) replicateEntry(entry LogEntry) {
|
||||
h.mutex.RLock()
|
||||
replicators := make([]*Replicator, 0, len(h.replicators))
|
||||
for _, replicator := range h.replicators {
|
||||
if replicator.connected {
|
||||
replicators = append(replicators, replicator)
|
||||
}
|
||||
}
|
||||
h.mutex.RUnlock()
|
||||
|
||||
for _, replicator := range replicators {
|
||||
// In a real implementation, this would send the entry over the network
|
||||
fmt.Printf("🔄 Replicating entry %d to %s\n",
|
||||
entry.Index, replicator.peerID.ShortString())
|
||||
}
|
||||
}
|
||||
|
||||
// calculateEntryHash calculates the hash of a log entry
|
||||
func (h *HypercoreLog) calculateEntryHash(entry LogEntry) (string, error) {
|
||||
// Create a copy without the hash and signature for calculation
|
||||
entryForHash := LogEntry{
|
||||
Index: entry.Index,
|
||||
Timestamp: entry.Timestamp,
|
||||
Author: entry.Author,
|
||||
Type: entry.Type,
|
||||
Data: entry.Data,
|
||||
PrevHash: entry.PrevHash,
|
||||
}
|
||||
|
||||
entryBytes, err := json.Marshal(entryForHash)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
hash := sha256.Sum256(entryBytes)
|
||||
return hex.EncodeToString(hash[:]), nil
|
||||
}
|
||||
|
||||
// createSignature creates a simplified signature for the entry
|
||||
func (h *HypercoreLog) createSignature(entry LogEntry) string {
|
||||
// In production, this would use proper cryptographic signatures
|
||||
// For now, we use a simple hash-based signature
|
||||
signatureData := fmt.Sprintf("%s:%s:%d", h.peerID.String(), entry.Hash, entry.Index)
|
||||
hash := sha256.Sum256([]byte(signatureData))
|
||||
return hex.EncodeToString(hash[:])[:16] // Shortened for display
|
||||
}
|
||||
|
||||
// GetStats returns statistics about the log
|
||||
func (h *HypercoreLog) GetStats() map[string]interface{} {
|
||||
h.mutex.RLock()
|
||||
defer h.mutex.RUnlock()
|
||||
|
||||
typeCount := make(map[LogType]int)
|
||||
authorCount := make(map[string]int)
|
||||
|
||||
for _, entry := range h.entries {
|
||||
typeCount[entry.Type]++
|
||||
authorCount[entry.Author]++
|
||||
}
|
||||
|
||||
return map[string]interface{}{
|
||||
"total_entries": len(h.entries),
|
||||
"head_hash": h.headHash,
|
||||
"replicators": len(h.replicators),
|
||||
"entries_by_type": typeCount,
|
||||
"entries_by_author": authorCount,
|
||||
"peer_id": h.peerID.String(),
|
||||
}
|
||||
}
|
||||
114
main.go
Normal file
114
main.go
Normal file
@@ -0,0 +1,114 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/deepblackcloud/bzzz/p2p"
|
||||
"github.com/deepblackcloud/bzzz/discovery"
|
||||
"github.com/deepblackcloud/bzzz/pubsub"
|
||||
)
|
||||
|
||||
func main() {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
fmt.Println("🚀 Starting Bzzz + Antennae P2P Task Coordination System...")
|
||||
|
||||
// Initialize P2P node with configuration
|
||||
node, err := p2p.NewNode(ctx)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to create P2P node: %v", err)
|
||||
}
|
||||
defer node.Close()
|
||||
|
||||
fmt.Printf("🐝 Bzzz node started successfully\n")
|
||||
fmt.Printf("📍 Node ID: %s\n", node.ID().ShortString())
|
||||
fmt.Printf("🔗 Listening addresses:\n")
|
||||
for _, addr := range node.Addresses() {
|
||||
fmt.Printf(" %s/p2p/%s\n", addr, node.ID())
|
||||
}
|
||||
|
||||
// Initialize mDNS discovery for local network (192.168.1.0/24)
|
||||
mdnsDiscovery, err := discovery.NewMDNSDiscovery(ctx, node.Host(), "bzzz-peer-discovery")
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to create mDNS discovery: %v", err)
|
||||
}
|
||||
defer mdnsDiscovery.Close()
|
||||
|
||||
// Initialize PubSub for Bzzz task coordination and Antennae meta-discussion
|
||||
ps, err := pubsub.NewPubSub(ctx, node.Host(), "bzzz/coordination/v1", "antennae/meta-discussion/v1")
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to create PubSub: %v", err)
|
||||
}
|
||||
defer ps.Close()
|
||||
|
||||
// Announce capabilities
|
||||
go announceCapabilities(ps)
|
||||
|
||||
// Start status reporting
|
||||
go statusReporter(node, ps)
|
||||
|
||||
fmt.Printf("🔍 Listening for peers on local network (192.168.1.0/24)...\n")
|
||||
fmt.Printf("📡 Ready for task coordination and meta-discussion\n")
|
||||
fmt.Printf("🎯 Antennae collaborative reasoning enabled\n")
|
||||
|
||||
// Handle graceful shutdown
|
||||
c := make(chan os.Signal, 1)
|
||||
signal.Notify(c, os.Interrupt, syscall.SIGTERM)
|
||||
<-c
|
||||
|
||||
fmt.Println("\n🛑 Shutting down Bzzz node...")
|
||||
}
|
||||
|
||||
// announceCapabilities periodically announces this node's capabilities
|
||||
func announceCapabilities(ps *pubsub.PubSub) {
|
||||
ticker := time.NewTicker(60 * time.Second)
|
||||
defer ticker.Stop()
|
||||
|
||||
// Announce immediately
|
||||
capabilities := map[string]interface{}{
|
||||
"node_type": "bzzz-coordinator",
|
||||
"capabilities": []string{"task-coordination", "meta-discussion", "p2p-networking"},
|
||||
"version": "0.1.0",
|
||||
"timestamp": time.Now().Unix(),
|
||||
}
|
||||
|
||||
if err := ps.PublishBzzzMessage(pubsub.CapabilityBcast, capabilities); err != nil {
|
||||
fmt.Printf("❌ Failed to announce capabilities: %v\n", err)
|
||||
}
|
||||
|
||||
// Then announce periodically
|
||||
for {
|
||||
select {
|
||||
case <-ticker.C:
|
||||
capabilities["timestamp"] = time.Now().Unix()
|
||||
if err := ps.PublishBzzzMessage(pubsub.CapabilityBcast, capabilities); err != nil {
|
||||
fmt.Printf("❌ Failed to announce capabilities: %v\n", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// statusReporter provides periodic status updates
|
||||
func statusReporter(node *p2p.Node, ps *pubsub.PubSub) {
|
||||
ticker := time.NewTicker(30 * time.Second)
|
||||
defer ticker.Stop()
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-ticker.C:
|
||||
peers := node.ConnectedPeers()
|
||||
fmt.Printf("📊 Status: %d connected peers, ready for coordination\n", peers)
|
||||
|
||||
if peers > 0 {
|
||||
fmt.Printf(" 🤝 Network formed - ready for distributed task coordination\n")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
127
p2p/config.go
Normal file
127
p2p/config.go
Normal file
@@ -0,0 +1,127 @@
|
||||
package p2p
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// Config holds configuration for a Bzzz P2P node
|
||||
type Config struct {
|
||||
// Network configuration
|
||||
ListenAddresses []string
|
||||
NetworkID string
|
||||
|
||||
// Discovery configuration
|
||||
EnableMDNS bool
|
||||
MDNSServiceTag string
|
||||
|
||||
// Connection limits
|
||||
MaxConnections int
|
||||
MaxPeersPerIP int
|
||||
ConnectionTimeout time.Duration
|
||||
|
||||
// Security configuration
|
||||
EnableSecurity bool
|
||||
|
||||
// Pubsub configuration
|
||||
EnablePubsub bool
|
||||
BzzzTopic string // Task coordination topic
|
||||
AntennaeTopic string // Meta-discussion topic
|
||||
MessageValidationTime time.Duration
|
||||
}
|
||||
|
||||
// Option is a function that modifies the node configuration
|
||||
type Option func(*Config)
|
||||
|
||||
// DefaultConfig returns a default configuration for Bzzz nodes
|
||||
func DefaultConfig() *Config {
|
||||
return &Config{
|
||||
// Listen on all interfaces with random ports for TCP
|
||||
ListenAddresses: []string{
|
||||
"/ip4/0.0.0.0/tcp/0",
|
||||
"/ip6/::/tcp/0",
|
||||
},
|
||||
NetworkID: "bzzz-network",
|
||||
|
||||
// Discovery settings
|
||||
EnableMDNS: true,
|
||||
MDNSServiceTag: "bzzz-peer-discovery",
|
||||
|
||||
// Connection limits for local network
|
||||
MaxConnections: 50,
|
||||
MaxPeersPerIP: 3,
|
||||
ConnectionTimeout: 30 * time.Second,
|
||||
|
||||
// Security enabled by default
|
||||
EnableSecurity: true,
|
||||
|
||||
// Pubsub for coordination and meta-discussion
|
||||
EnablePubsub: true,
|
||||
BzzzTopic: "bzzz/coordination/v1",
|
||||
AntennaeTopic: "antennae/meta-discussion/v1",
|
||||
MessageValidationTime: 10 * time.Second,
|
||||
}
|
||||
}
|
||||
|
||||
// WithListenAddresses sets the addresses to listen on
|
||||
func WithListenAddresses(addrs ...string) Option {
|
||||
return func(c *Config) {
|
||||
c.ListenAddresses = addrs
|
||||
}
|
||||
}
|
||||
|
||||
// WithNetworkID sets the network ID
|
||||
func WithNetworkID(networkID string) Option {
|
||||
return func(c *Config) {
|
||||
c.NetworkID = networkID
|
||||
}
|
||||
}
|
||||
|
||||
// WithMDNS enables or disables mDNS discovery
|
||||
func WithMDNS(enabled bool) Option {
|
||||
return func(c *Config) {
|
||||
c.EnableMDNS = enabled
|
||||
}
|
||||
}
|
||||
|
||||
// WithMDNSServiceTag sets the mDNS service tag
|
||||
func WithMDNSServiceTag(tag string) Option {
|
||||
return func(c *Config) {
|
||||
c.MDNSServiceTag = tag
|
||||
}
|
||||
}
|
||||
|
||||
// WithMaxConnections sets the maximum number of connections
|
||||
func WithMaxConnections(max int) Option {
|
||||
return func(c *Config) {
|
||||
c.MaxConnections = max
|
||||
}
|
||||
}
|
||||
|
||||
// WithConnectionTimeout sets the connection timeout
|
||||
func WithConnectionTimeout(timeout time.Duration) Option {
|
||||
return func(c *Config) {
|
||||
c.ConnectionTimeout = timeout
|
||||
}
|
||||
}
|
||||
|
||||
// WithSecurity enables or disables security
|
||||
func WithSecurity(enabled bool) Option {
|
||||
return func(c *Config) {
|
||||
c.EnableSecurity = enabled
|
||||
}
|
||||
}
|
||||
|
||||
// WithPubsub enables or disables pubsub
|
||||
func WithPubsub(enabled bool) Option {
|
||||
return func(c *Config) {
|
||||
c.EnablePubsub = enabled
|
||||
}
|
||||
}
|
||||
|
||||
// WithTopics sets the Bzzz and Antennae topic names
|
||||
func WithTopics(bzzzTopic, antennaeTopic string) Option {
|
||||
return func(c *Config) {
|
||||
c.BzzzTopic = bzzzTopic
|
||||
c.AntennaeTopic = antennaeTopic
|
||||
}
|
||||
}
|
||||
148
p2p/node.go
Normal file
148
p2p/node.go
Normal file
@@ -0,0 +1,148 @@
|
||||
package p2p
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/libp2p/go-libp2p"
|
||||
"github.com/libp2p/go-libp2p/core/host"
|
||||
"github.com/libp2p/go-libp2p/core/peer"
|
||||
"github.com/libp2p/go-libp2p/p2p/security/noise"
|
||||
"github.com/libp2p/go-libp2p/p2p/transport/tcp"
|
||||
"github.com/multiformats/go-multiaddr"
|
||||
)
|
||||
|
||||
// Node represents a Bzzz P2P node
|
||||
type Node struct {
|
||||
host host.Host
|
||||
ctx context.Context
|
||||
cancel context.CancelFunc
|
||||
config *Config
|
||||
}
|
||||
|
||||
// NewNode creates a new P2P node with the given configuration
|
||||
func NewNode(ctx context.Context, opts ...Option) (*Node, error) {
|
||||
config := DefaultConfig()
|
||||
for _, opt := range opts {
|
||||
opt(config)
|
||||
}
|
||||
|
||||
nodeCtx, cancel := context.WithCancel(ctx)
|
||||
|
||||
// Build multiaddresses for listening
|
||||
var listenAddrs []multiaddr.Multiaddr
|
||||
for _, addr := range config.ListenAddresses {
|
||||
ma, err := multiaddr.NewMultiaddr(addr)
|
||||
if err != nil {
|
||||
cancel()
|
||||
return nil, fmt.Errorf("invalid listen address %s: %w", addr, err)
|
||||
}
|
||||
listenAddrs = append(listenAddrs, ma)
|
||||
}
|
||||
|
||||
// Create libp2p host with security and transport options
|
||||
h, err := libp2p.New(
|
||||
libp2p.ListenAddrs(listenAddrs...),
|
||||
libp2p.Security(noise.ID, noise.New),
|
||||
libp2p.Transport(tcp.NewTCPTransport),
|
||||
libp2p.DefaultMuxers,
|
||||
libp2p.EnableRelay(),
|
||||
)
|
||||
if err != nil {
|
||||
cancel()
|
||||
return nil, fmt.Errorf("failed to create libp2p host: %w", err)
|
||||
}
|
||||
|
||||
node := &Node{
|
||||
host: h,
|
||||
ctx: nodeCtx,
|
||||
cancel: cancel,
|
||||
config: config,
|
||||
}
|
||||
|
||||
// Start background processes
|
||||
go node.startBackgroundTasks()
|
||||
|
||||
return node, nil
|
||||
}
|
||||
|
||||
// Host returns the underlying libp2p host
|
||||
func (n *Node) Host() host.Host {
|
||||
return n.host
|
||||
}
|
||||
|
||||
// ID returns the peer ID of this node
|
||||
func (n *Node) ID() peer.ID {
|
||||
return n.host.ID()
|
||||
}
|
||||
|
||||
// Addresses returns the multiaddresses this node is listening on
|
||||
func (n *Node) Addresses() []multiaddr.Multiaddr {
|
||||
return n.host.Addrs()
|
||||
}
|
||||
|
||||
// Connect connects to a peer at the given multiaddress
|
||||
func (n *Node) Connect(ctx context.Context, addr string) error {
|
||||
ma, err := multiaddr.NewMultiaddr(addr)
|
||||
if err != nil {
|
||||
return fmt.Errorf("invalid multiaddress %s: %w", addr, err)
|
||||
}
|
||||
|
||||
addrInfo, err := peer.AddrInfoFromP2pAddr(ma)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to parse addr info: %w", err)
|
||||
}
|
||||
|
||||
return n.host.Connect(ctx, *addrInfo)
|
||||
}
|
||||
|
||||
// Peers returns the list of connected peers
|
||||
func (n *Node) Peers() []peer.ID {
|
||||
return n.host.Network().Peers()
|
||||
}
|
||||
|
||||
// ConnectedPeers returns the number of connected peers
|
||||
func (n *Node) ConnectedPeers() int {
|
||||
return len(n.Peers())
|
||||
}
|
||||
|
||||
// startBackgroundTasks starts background maintenance tasks
|
||||
func (n *Node) startBackgroundTasks() {
|
||||
ticker := time.NewTicker(30 * time.Second)
|
||||
defer ticker.Stop()
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-n.ctx.Done():
|
||||
return
|
||||
case <-ticker.C:
|
||||
// Periodic maintenance tasks
|
||||
n.logConnectionStatus()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// logConnectionStatus logs the current connection status
|
||||
func (n *Node) logConnectionStatus() {
|
||||
peers := n.Peers()
|
||||
fmt.Printf("🐝 Bzzz Node Status - ID: %s, Connected Peers: %d\n",
|
||||
n.ID().ShortString(), len(peers))
|
||||
|
||||
if len(peers) > 0 {
|
||||
fmt.Printf(" Connected to: ")
|
||||
for i, p := range peers {
|
||||
if i > 0 {
|
||||
fmt.Printf(", ")
|
||||
}
|
||||
fmt.Printf("%s", p.ShortString())
|
||||
}
|
||||
fmt.Println()
|
||||
}
|
||||
}
|
||||
|
||||
// Close shuts down the node
|
||||
func (n *Node) Close() error {
|
||||
n.cancel()
|
||||
return n.host.Close()
|
||||
}
|
||||
350
pubsub/pubsub.go
Normal file
350
pubsub/pubsub.go
Normal file
@@ -0,0 +1,350 @@
|
||||
package pubsub
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/libp2p/go-libp2p/core/host"
|
||||
"github.com/libp2p/go-libp2p/core/peer"
|
||||
pubsub "github.com/libp2p/go-libp2p-pubsub"
|
||||
)
|
||||
|
||||
// PubSub handles publish/subscribe messaging for Bzzz coordination and Antennae meta-discussion
|
||||
type PubSub struct {
|
||||
ps *pubsub.PubSub
|
||||
host host.Host
|
||||
ctx context.Context
|
||||
cancel context.CancelFunc
|
||||
|
||||
// Topic subscriptions
|
||||
bzzzTopic *pubsub.Topic
|
||||
antennaeTopic *pubsub.Topic
|
||||
|
||||
// Message handlers
|
||||
bzzzSub *pubsub.Subscription
|
||||
antennaeSub *pubsub.Subscription
|
||||
|
||||
// Configuration
|
||||
bzzzTopicName string
|
||||
antennaeTopicName string
|
||||
}
|
||||
|
||||
// MessageType represents different types of messages
|
||||
type MessageType string
|
||||
|
||||
const (
|
||||
// Bzzz coordination messages
|
||||
TaskAnnouncement MessageType = "task_announcement"
|
||||
TaskClaim MessageType = "task_claim"
|
||||
TaskProgress MessageType = "task_progress"
|
||||
TaskComplete MessageType = "task_complete"
|
||||
CapabilityBcast MessageType = "capability_broadcast"
|
||||
|
||||
// Antennae meta-discussion messages
|
||||
PlanProposal MessageType = "plan_proposal"
|
||||
Objection MessageType = "objection"
|
||||
Collaboration MessageType = "collaboration"
|
||||
Escalation MessageType = "escalation"
|
||||
)
|
||||
|
||||
// Message represents a Bzzz/Antennae message
|
||||
type Message struct {
|
||||
Type MessageType `json:"type"`
|
||||
From string `json:"from"`
|
||||
Timestamp time.Time `json:"timestamp"`
|
||||
Data map[string]interface{} `json:"data"`
|
||||
HopCount int `json:"hop_count,omitempty"` // For Antennae hop limiting
|
||||
}
|
||||
|
||||
// NewPubSub creates a new PubSub instance for Bzzz coordination and Antennae meta-discussion
|
||||
func NewPubSub(ctx context.Context, h host.Host, bzzzTopic, antennaeTopic string) (*PubSub, error) {
|
||||
if bzzzTopic == "" {
|
||||
bzzzTopic = "bzzz/coordination/v1"
|
||||
}
|
||||
if antennaeTopic == "" {
|
||||
antennaeTopic = "antennae/meta-discussion/v1"
|
||||
}
|
||||
|
||||
pubsubCtx, cancel := context.WithCancel(ctx)
|
||||
|
||||
// Create gossipsub instance with message validation
|
||||
ps, err := pubsub.NewGossipSub(pubsubCtx, h,
|
||||
pubsub.WithMessageSigning(true),
|
||||
pubsub.WithStrictSignatureVerification(true),
|
||||
pubsub.WithValidateQueueSize(256),
|
||||
pubsub.WithValidateThrottle(1024),
|
||||
)
|
||||
if err != nil {
|
||||
cancel()
|
||||
return nil, fmt.Errorf("failed to create gossipsub: %w", err)
|
||||
}
|
||||
|
||||
p := &PubSub{
|
||||
ps: ps,
|
||||
host: h,
|
||||
ctx: pubsubCtx,
|
||||
cancel: cancel,
|
||||
bzzzTopicName: bzzzTopic,
|
||||
antennaeTopicName: antennaeTopic,
|
||||
}
|
||||
|
||||
// Join topics
|
||||
if err := p.joinTopics(); err != nil {
|
||||
cancel()
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Start message handlers
|
||||
go p.handleBzzzMessages()
|
||||
go p.handleAntennaeMessages()
|
||||
|
||||
fmt.Printf("📡 PubSub initialized - Bzzz: %s, Antennae: %s\n", bzzzTopic, antennaeTopic)
|
||||
return p, nil
|
||||
}
|
||||
|
||||
// joinTopics joins the Bzzz coordination and Antennae meta-discussion topics
|
||||
func (p *PubSub) joinTopics() error {
|
||||
// Join Bzzz coordination topic
|
||||
bzzzTopic, err := p.ps.Join(p.bzzzTopicName)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to join Bzzz topic: %w", err)
|
||||
}
|
||||
p.bzzzTopic = bzzzTopic
|
||||
|
||||
// Subscribe to Bzzz messages
|
||||
bzzzSub, err := bzzzTopic.Subscribe()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to subscribe to Bzzz topic: %w", err)
|
||||
}
|
||||
p.bzzzSub = bzzzSub
|
||||
|
||||
// Join Antennae meta-discussion topic
|
||||
antennaeTopic, err := p.ps.Join(p.antennaeTopicName)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to join Antennae topic: %w", err)
|
||||
}
|
||||
p.antennaeTopic = antennaeTopic
|
||||
|
||||
// Subscribe to Antennae messages
|
||||
antennaeSub, err := antennaeTopic.Subscribe()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to subscribe to Antennae topic: %w", err)
|
||||
}
|
||||
p.antennaeSub = antennaeSub
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// PublishBzzzMessage publishes a message to the Bzzz coordination topic
|
||||
func (p *PubSub) PublishBzzzMessage(msgType MessageType, data map[string]interface{}) error {
|
||||
msg := Message{
|
||||
Type: msgType,
|
||||
From: p.host.ID().String(),
|
||||
Timestamp: time.Now(),
|
||||
Data: data,
|
||||
}
|
||||
|
||||
msgBytes, err := json.Marshal(msg)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to marshal message: %w", err)
|
||||
}
|
||||
|
||||
return p.bzzzTopic.Publish(p.ctx, msgBytes)
|
||||
}
|
||||
|
||||
// PublishAntennaeMessage publishes a message to the Antennae meta-discussion topic
|
||||
func (p *PubSub) PublishAntennaeMessage(msgType MessageType, data map[string]interface{}, hopCount int) error {
|
||||
// Antennae messages have hop limiting for safety
|
||||
if hopCount > 3 {
|
||||
return fmt.Errorf("hop count exceeded maximum of 3")
|
||||
}
|
||||
|
||||
msg := Message{
|
||||
Type: msgType,
|
||||
From: p.host.ID().String(),
|
||||
Timestamp: time.Now(),
|
||||
Data: data,
|
||||
HopCount: hopCount,
|
||||
}
|
||||
|
||||
msgBytes, err := json.Marshal(msg)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to marshal message: %w", err)
|
||||
}
|
||||
|
||||
return p.antennaeTopic.Publish(p.ctx, msgBytes)
|
||||
}
|
||||
|
||||
// handleBzzzMessages processes incoming Bzzz coordination messages
|
||||
func (p *PubSub) handleBzzzMessages() {
|
||||
for {
|
||||
msg, err := p.bzzzSub.Next(p.ctx)
|
||||
if err != nil {
|
||||
if p.ctx.Err() != nil {
|
||||
return // Context cancelled
|
||||
}
|
||||
fmt.Printf("❌ Error receiving Bzzz message: %v\n", err)
|
||||
continue
|
||||
}
|
||||
|
||||
// Skip our own messages
|
||||
if msg.ReceivedFrom == p.host.ID() {
|
||||
continue
|
||||
}
|
||||
|
||||
var bzzzMsg Message
|
||||
if err := json.Unmarshal(msg.Data, &bzzzMsg); err != nil {
|
||||
fmt.Printf("❌ Failed to unmarshal Bzzz message: %v\n", err)
|
||||
continue
|
||||
}
|
||||
|
||||
p.processBzzzMessage(bzzzMsg, msg.ReceivedFrom)
|
||||
}
|
||||
}
|
||||
|
||||
// handleAntennaeMessages processes incoming Antennae meta-discussion messages
|
||||
func (p *PubSub) handleAntennaeMessages() {
|
||||
for {
|
||||
msg, err := p.antennaeSub.Next(p.ctx)
|
||||
if err != nil {
|
||||
if p.ctx.Err() != nil {
|
||||
return // Context cancelled
|
||||
}
|
||||
fmt.Printf("❌ Error receiving Antennae message: %v\n", err)
|
||||
continue
|
||||
}
|
||||
|
||||
// Skip our own messages
|
||||
if msg.ReceivedFrom == p.host.ID() {
|
||||
continue
|
||||
}
|
||||
|
||||
var antennaeMsg Message
|
||||
if err := json.Unmarshal(msg.Data, &antennaeMsg); err != nil {
|
||||
fmt.Printf("❌ Failed to unmarshal Antennae message: %v\n", err)
|
||||
continue
|
||||
}
|
||||
|
||||
p.processAntennaeMessage(antennaeMsg, msg.ReceivedFrom)
|
||||
}
|
||||
}
|
||||
|
||||
// processBzzzMessage handles different types of Bzzz coordination messages
|
||||
func (p *PubSub) processBzzzMessage(msg Message, from peer.ID) {
|
||||
fmt.Printf("🐝 Bzzz [%s] from %s: %s\n", msg.Type, from.ShortString(), msg.Data)
|
||||
|
||||
switch msg.Type {
|
||||
case TaskAnnouncement:
|
||||
p.handleTaskAnnouncement(msg, from)
|
||||
case TaskClaim:
|
||||
p.handleTaskClaim(msg, from)
|
||||
case TaskProgress:
|
||||
p.handleTaskProgress(msg, from)
|
||||
case TaskComplete:
|
||||
p.handleTaskComplete(msg, from)
|
||||
case CapabilityBcast:
|
||||
p.handleCapabilityBroadcast(msg, from)
|
||||
default:
|
||||
fmt.Printf("⚠️ Unknown Bzzz message type: %s\n", msg.Type)
|
||||
}
|
||||
}
|
||||
|
||||
// processAntennaeMessage handles different types of Antennae meta-discussion messages
|
||||
func (p *PubSub) processAntennaeMessage(msg Message, from peer.ID) {
|
||||
fmt.Printf("🎯 Antennae [%s] from %s (hop %d): %s\n",
|
||||
msg.Type, from.ShortString(), msg.HopCount, msg.Data)
|
||||
|
||||
// Check hop count for safety
|
||||
if msg.HopCount > 3 {
|
||||
fmt.Printf("⚠️ Dropping Antennae message with excessive hop count: %d\n", msg.HopCount)
|
||||
return
|
||||
}
|
||||
|
||||
switch msg.Type {
|
||||
case PlanProposal:
|
||||
p.handlePlanProposal(msg, from)
|
||||
case Objection:
|
||||
p.handleObjection(msg, from)
|
||||
case Collaboration:
|
||||
p.handleCollaboration(msg, from)
|
||||
case Escalation:
|
||||
p.handleEscalation(msg, from)
|
||||
default:
|
||||
fmt.Printf("⚠️ Unknown Antennae message type: %s\n", msg.Type)
|
||||
}
|
||||
}
|
||||
|
||||
// Bzzz message handlers
|
||||
func (p *PubSub) handleTaskAnnouncement(msg Message, from peer.ID) {
|
||||
// Handle task announcement logic
|
||||
fmt.Printf("📋 New task announced: %v\n", msg.Data)
|
||||
}
|
||||
|
||||
func (p *PubSub) handleTaskClaim(msg Message, from peer.ID) {
|
||||
// Handle task claim logic
|
||||
fmt.Printf("✋ Task claimed by %s: %v\n", from.ShortString(), msg.Data)
|
||||
}
|
||||
|
||||
func (p *PubSub) handleTaskProgress(msg Message, from peer.ID) {
|
||||
// Handle task progress updates
|
||||
fmt.Printf("⏳ Task progress from %s: %v\n", from.ShortString(), msg.Data)
|
||||
}
|
||||
|
||||
func (p *PubSub) handleTaskComplete(msg Message, from peer.ID) {
|
||||
// Handle task completion
|
||||
fmt.Printf("✅ Task completed by %s: %v\n", from.ShortString(), msg.Data)
|
||||
}
|
||||
|
||||
func (p *PubSub) handleCapabilityBroadcast(msg Message, from peer.ID) {
|
||||
// Handle capability announcements
|
||||
fmt.Printf("🔧 Capabilities from %s: %v\n", from.ShortString(), msg.Data)
|
||||
}
|
||||
|
||||
// Antennae message handlers
|
||||
func (p *PubSub) handlePlanProposal(msg Message, from peer.ID) {
|
||||
// Handle plan proposals for collaborative reasoning
|
||||
fmt.Printf("💡 Plan proposal from %s: %v\n", from.ShortString(), msg.Data)
|
||||
}
|
||||
|
||||
func (p *PubSub) handleObjection(msg Message, from peer.ID) {
|
||||
// Handle objections during collaborative discussions
|
||||
fmt.Printf("⚠️ Objection from %s: %v\n", from.ShortString(), msg.Data)
|
||||
}
|
||||
|
||||
func (p *PubSub) handleCollaboration(msg Message, from peer.ID) {
|
||||
// Handle collaborative reasoning messages
|
||||
fmt.Printf("🤝 Collaboration from %s: %v\n", from.ShortString(), msg.Data)
|
||||
}
|
||||
|
||||
func (p *PubSub) handleEscalation(msg Message, from peer.ID) {
|
||||
// Handle escalations to human intervention
|
||||
fmt.Printf("🚨 Escalation from %s: %v\n", from.ShortString(), msg.Data)
|
||||
}
|
||||
|
||||
// GetConnectedPeers returns the number of connected peers
|
||||
func (p *PubSub) GetConnectedPeers() int {
|
||||
return len(p.host.Network().Peers())
|
||||
}
|
||||
|
||||
// Close shuts down the PubSub instance
|
||||
func (p *PubSub) Close() error {
|
||||
p.cancel()
|
||||
|
||||
if p.bzzzSub != nil {
|
||||
p.bzzzSub.Cancel()
|
||||
}
|
||||
if p.antennaeSub != nil {
|
||||
p.antennaeSub.Cancel()
|
||||
}
|
||||
|
||||
if p.bzzzTopic != nil {
|
||||
p.bzzzTopic.Close()
|
||||
}
|
||||
if p.antennaeTopic != nil {
|
||||
p.antennaeTopic.Close()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user